1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 The code included in this file is provided under the terms of the ISC license 11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission 12 To use, copy, modify, and/or distribute this software for any purpose with or 13 without fee is hereby granted provided that the above copyright notice and 14 this permission notice appear in all copies. 15 16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 18 DISCLAIMED. 19 20 ============================================================================== 21 */ 22 23 namespace juce 24 { 25 26 //============================================================================== 27 extern JNIEnv* getEnv() noexcept; 28 29 //============================================================================== 30 template <typename JavaType> 31 class LocalRef 32 { 33 public: LocalRef()34 explicit inline LocalRef() noexcept : obj (nullptr) {} LocalRef(JavaType o)35 explicit inline LocalRef (JavaType o) noexcept : obj (o) {} LocalRef(const LocalRef & other)36 inline LocalRef (const LocalRef& other) noexcept : obj (retain (other.obj)) {} LocalRef(LocalRef && other)37 inline LocalRef (LocalRef&& other) noexcept : obj (nullptr) { std::swap (obj, other.obj); } ~LocalRef()38 ~LocalRef() { clear(); } 39 clear()40 void clear() 41 { 42 if (obj != nullptr) 43 { 44 getEnv()->DeleteLocalRef (obj); 45 obj = nullptr; 46 } 47 } 48 49 LocalRef& operator= (const LocalRef& other) 50 { 51 JavaType newObj = retain (other.obj); 52 clear(); 53 obj = newObj; 54 return *this; 55 } 56 57 LocalRef& operator= (LocalRef&& other) 58 { 59 clear(); 60 std::swap (other.obj, obj); 61 return *this; 62 } 63 JavaType()64 inline operator JavaType() const noexcept { return obj; } get()65 inline JavaType get() const noexcept { return obj; } 66 67 private: 68 JavaType obj; 69 retain(JavaType obj)70 static JavaType retain (JavaType obj) 71 { 72 return obj == nullptr ? nullptr : (JavaType) getEnv()->NewLocalRef (obj); 73 } 74 }; 75 76 //============================================================================== 77 class GlobalRef 78 { 79 public: GlobalRef()80 inline GlobalRef() noexcept : obj (nullptr) {} GlobalRef(const LocalRef<jobject> & o)81 inline explicit GlobalRef (const LocalRef<jobject>& o) : obj (retain (o.get(), getEnv())) {} GlobalRef(const LocalRef<jobject> & o,JNIEnv * env)82 inline explicit GlobalRef (const LocalRef<jobject>& o, JNIEnv* env) : obj (retain (o.get(), env)) {} GlobalRef(const GlobalRef & other)83 inline GlobalRef (const GlobalRef& other) : obj (retain (other.obj, getEnv())) {} GlobalRef(GlobalRef && other)84 inline GlobalRef (GlobalRef && other) noexcept : obj (nullptr) { std::swap (other.obj, obj); } ~GlobalRef()85 ~GlobalRef() { clear(); } 86 87 clear()88 inline void clear() { if (obj != nullptr) clear (getEnv()); } clear(JNIEnv * env)89 inline void clear (JNIEnv* env) 90 { 91 if (obj != nullptr) 92 { 93 env->DeleteGlobalRef (obj); 94 obj = nullptr; 95 } 96 } 97 98 inline GlobalRef& operator= (const GlobalRef& other) 99 { 100 jobject newObj = retain (other.obj, getEnv()); 101 clear(); 102 obj = newObj; 103 return *this; 104 } 105 106 inline GlobalRef& operator= (GlobalRef&& other) 107 { 108 clear(); 109 std::swap (obj, other.obj); 110 111 return *this; 112 } 113 114 //============================================================================== jobject()115 inline operator jobject() const noexcept { return obj; } get()116 inline jobject get() const noexcept { return obj; } 117 118 //============================================================================== 119 #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ 120 returnType call##typeName##Method (jmethodID methodID, ... ) const \ 121 { \ 122 va_list args; \ 123 va_start (args, methodID); \ 124 returnType result = getEnv()->Call##typeName##MethodV (obj, methodID, args); \ 125 va_end (args); \ 126 return result; \ 127 } 128 DECLARE_CALL_TYPE_METHOD(jobject,Object)129 DECLARE_CALL_TYPE_METHOD (jobject, Object) 130 DECLARE_CALL_TYPE_METHOD (jboolean, Boolean) 131 DECLARE_CALL_TYPE_METHOD (jbyte, Byte) 132 DECLARE_CALL_TYPE_METHOD (jchar, Char) 133 DECLARE_CALL_TYPE_METHOD (jshort, Short) 134 DECLARE_CALL_TYPE_METHOD (jint, Int) 135 DECLARE_CALL_TYPE_METHOD (jlong, Long) 136 DECLARE_CALL_TYPE_METHOD (jfloat, Float) 137 DECLARE_CALL_TYPE_METHOD (jdouble, Double) 138 #undef DECLARE_CALL_TYPE_METHOD 139 140 void callVoidMethod (jmethodID methodID, ... ) const 141 { 142 va_list args; 143 va_start (args, methodID); 144 getEnv()->CallVoidMethodV (obj, methodID, args); 145 va_end (args); 146 } 147 148 private: 149 //============================================================================== 150 jobject obj = nullptr; 151 retain(jobject obj,JNIEnv * env)152 static jobject retain (jobject obj, JNIEnv* env) 153 { 154 return obj == nullptr ? nullptr : env->NewGlobalRef (obj); 155 } 156 }; 157 158 159 //============================================================================== 160 extern LocalRef<jobject> getAppContext() noexcept; 161 extern LocalRef<jobject> getCurrentActivity() noexcept; 162 extern LocalRef<jobject> getMainActivity() noexcept; 163 164 //============================================================================== 165 struct SystemJavaClassComparator; 166 class JNIClassBase 167 { 168 public: 169 explicit JNIClassBase (const char* classPath, int minSDK, const void* byteCode, size_t byteCodeSize); 170 virtual ~JNIClassBase(); 171 jclass()172 inline operator jclass() const noexcept { return classRef; } 173 174 static void initialiseAllClasses (JNIEnv*); 175 static void releaseAllClasses (JNIEnv*); 176 getClassPath()177 inline const char* getClassPath() const noexcept { return classPath; } 178 179 protected: 180 virtual void initialiseFields (JNIEnv*) = 0; 181 182 jmethodID resolveMethod (JNIEnv*, const char* methodName, const char* params); 183 jmethodID resolveStaticMethod (JNIEnv*, const char* methodName, const char* params); 184 jfieldID resolveField (JNIEnv*, const char* fieldName, const char* signature); 185 jfieldID resolveStaticField (JNIEnv*, const char* fieldName, const char* signature); 186 void resolveCallbacks (JNIEnv*, const Array<JNINativeMethod>&); 187 188 private: 189 friend struct SystemJavaClassComparator; 190 191 const char* const classPath; 192 const void* byteCode; 193 size_t byteCodeSize; 194 195 int minSDK; 196 jclass classRef = nullptr; 197 198 static Array<JNIClassBase*>& getClasses(); 199 void initialise (JNIEnv*); 200 void release (JNIEnv*); 201 void tryLoadingClassWithClassLoader (JNIEnv* env, jobject classLoader); 202 203 JUCE_DECLARE_NON_COPYABLE (JNIClassBase) 204 }; 205 206 //============================================================================== 207 #define CREATE_JNI_METHOD(methodID, stringName, params) methodID = resolveMethod (env, stringName, params); 208 #define CREATE_JNI_STATICMETHOD(methodID, stringName, params) methodID = resolveStaticMethod (env, stringName, params); 209 #define CREATE_JNI_FIELD(fieldID, stringName, signature) fieldID = resolveField (env, stringName, signature); 210 #define CREATE_JNI_STATICFIELD(fieldID, stringName, signature) fieldID = resolveStaticField (env, stringName, signature); 211 #define CREATE_JNI_CALLBACK(callbackName, stringName, signature) callbacks.add ({stringName, signature, (void*) callbackName}); 212 #define DECLARE_JNI_METHOD(methodID, stringName, params) jmethodID methodID; 213 #define DECLARE_JNI_FIELD(fieldID, stringName, signature) jfieldID fieldID; 214 #define DECLARE_JNI_CALLBACK(fieldID, stringName, signature) 215 216 #define DECLARE_JNI_CLASS_WITH_BYTECODE(CppClassName, javaPath, minSDK, byteCodeData, byteCodeSize) \ 217 class CppClassName ## _Class : public JNIClassBase \ 218 { \ 219 public: \ 220 CppClassName ## _Class() : JNIClassBase (javaPath, minSDK, byteCodeData, byteCodeSize) {} \ 221 \ 222 void initialiseFields (JNIEnv* env) \ 223 { \ 224 Array<JNINativeMethod> callbacks; \ 225 JNI_CLASS_MEMBERS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD, CREATE_JNI_FIELD, CREATE_JNI_STATICFIELD, CREATE_JNI_CALLBACK); \ 226 resolveCallbacks (env, callbacks); \ 227 } \ 228 \ 229 JNI_CLASS_MEMBERS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD, DECLARE_JNI_FIELD, DECLARE_JNI_FIELD, DECLARE_JNI_CALLBACK) \ 230 }; \ 231 static CppClassName ## _Class CppClassName; 232 233 //============================================================================== 234 #define DECLARE_JNI_CLASS_WITH_MIN_SDK(CppClassName, javaPath, minSDK) \ 235 DECLARE_JNI_CLASS_WITH_BYTECODE (CppClassName, javaPath, minSDK, nullptr, 0) 236 237 //============================================================================== 238 #define DECLARE_JNI_CLASS(CppClassName, javaPath) \ 239 DECLARE_JNI_CLASS_WITH_MIN_SDK (CppClassName, javaPath, 16) 240 241 //============================================================================== 242 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 243 METHOD (getAssets, "getAssets", "()Landroid/content/res/AssetManager;") \ 244 METHOD (getSystemService, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;") \ 245 METHOD (getPackageManager, "getPackageManager", "()Landroid/content/pm/PackageManager;") \ 246 METHOD (getPackageName, "getPackageName", "()Ljava/lang/String;") \ 247 METHOD (getResources, "getResources", "()Landroid/content/res/Resources;") \ 248 METHOD (bindService, "bindService", "(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z") \ 249 METHOD (unbindService, "unbindService", "(Landroid/content/ServiceConnection;)V") \ 250 METHOD (startActivity, "startActivity", "(Landroid/content/Intent;)V") \ 251 METHOD (getContentResolver, "getContentResolver", "()Landroid/content/ContentResolver;") \ 252 METHOD (getApplicationContext, "getApplicationContext", "()Landroid/content/Context;") \ 253 METHOD (getApplicationInfo, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;") \ 254 METHOD (checkCallingOrSelfPermission, "checkCallingOrSelfPermission", "(Ljava/lang/String;)I") \ 255 METHOD (getCacheDir, "getCacheDir", "()Ljava/io/File;") 256 257 DECLARE_JNI_CLASS (AndroidContext, "android/content/Context") 258 #undef JNI_CLASS_MEMBERS 259 260 //============================================================================== 261 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 262 METHOD (finish, "finish", "()V") \ 263 METHOD (getWindowManager, "getWindowManager", "()Landroid/view/WindowManager;") \ 264 METHOD (setRequestedOrientation, "setRequestedOrientation", "(I)V") \ 265 METHOD (startIntentSenderForResult, "startIntentSenderForResult", "(Landroid/content/IntentSender;ILandroid/content/Intent;III)V") \ 266 METHOD (moveTaskToBack, "moveTaskToBack", "(Z)Z") \ 267 METHOD (startActivityForResult, "startActivityForResult", "(Landroid/content/Intent;I)V") \ 268 METHOD (getFragmentManager, "getFragmentManager", "()Landroid/app/FragmentManager;") \ 269 METHOD (setContentView, "setContentView", "(Landroid/view/View;)V") \ 270 METHOD (getWindow, "getWindow", "()Landroid/view/Window;") 271 272 DECLARE_JNI_CLASS (AndroidActivity, "android/app/Activity") 273 #undef JNI_CLASS_MEMBERS 274 275 //============================================================================== 276 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 277 METHOD (startActivityForResult, "startActivityForResult", "(Landroid/content/Intent;I)V") \ 278 METHOD (setArguments, "setArguments", "(Landroid/os/Bundle;)V") 279 280 DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidFragment, "android/app/Fragment", 11) 281 #undef JNI_CLASS_MEMBERS 282 283 //============================================================================== 284 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 285 METHOD (build, "build", "()Landroid/media/AudioAttributes;") \ 286 METHOD (constructor, "<init>", "()V") \ 287 METHOD (setContentType, "setContentType", "(I)Landroid/media/AudioAttributes$Builder;") \ 288 METHOD (setUsage, "setUsage", "(I)Landroid/media/AudioAttributes$Builder;") 289 290 DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidAudioAttributesBuilder, "android/media/AudioAttributes$Builder", 21) 291 #undef JNI_CLASS_MEMBERS 292 293 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 294 METHOD (abandonAudioFocus, "abandonAudioFocus", "(Landroid/media/AudioManager$OnAudioFocusChangeListener;)I") \ 295 METHOD (requestAudioFocus, "requestAudioFocus", "(Landroid/media/AudioManager$OnAudioFocusChangeListener;II)I") 296 297 DECLARE_JNI_CLASS (AndroidAudioManager, "android/media/AudioManager") 298 #undef JNI_CLASS_MEMBERS 299 300 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 301 STATICMETHOD (createBitmap, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;") \ 302 STATICMETHOD (createBitmapFrom, "createBitmap", "(Landroid/graphics/Bitmap;IIIILandroid/graphics/Matrix;Z)Landroid/graphics/Bitmap;") \ 303 METHOD (compress, "compress", "(Landroid/graphics/Bitmap$CompressFormat;ILjava/io/OutputStream;)Z") \ 304 METHOD (getHeight, "getHeight", "()I") \ 305 METHOD (getWidth, "getWidth", "()I") \ 306 METHOD (recycle, "recycle", "()V") \ 307 METHOD (setPixel, "setPixel", "(III)V") \ 308 METHOD (getPixels, "getPixels", "([IIIIIII)V") 309 310 DECLARE_JNI_CLASS (AndroidBitmap, "android/graphics/Bitmap") 311 #undef JNI_CLASS_MEMBERS 312 313 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 314 STATICMETHOD (valueOf, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;") 315 316 DECLARE_JNI_CLASS (AndroidBitmapConfig, "android/graphics/Bitmap$Config") 317 #undef JNI_CLASS_MEMBERS 318 319 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 320 STATICMETHOD (decodeByteArray, "decodeByteArray", "([BII)Landroid/graphics/Bitmap;") 321 322 DECLARE_JNI_CLASS (AndroidBitmapFactory, "android/graphics/BitmapFactory") 323 #undef JNI_CLASS_MEMBERS 324 325 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 326 METHOD (constructor, "<init>", "()V") \ 327 METHOD (containsKey, "containsKey", "(Ljava/lang/String;)Z") \ 328 METHOD (get, "get", "(Ljava/lang/String;)Ljava/lang/Object;") \ 329 METHOD (getBoolean, "getBoolean", "(Ljava/lang/String;)Z") \ 330 METHOD (getBundle, "getBundle", "(Ljava/lang/String;)Landroid/os/Bundle;") \ 331 METHOD (getCharSequence, "getCharSequence", "(Ljava/lang/String;)Ljava/lang/CharSequence;") \ 332 METHOD (getInt, "getInt", "(Ljava/lang/String;)I") \ 333 METHOD (getLong, "getLong", "(Ljava/lang/String;)J") \ 334 METHOD (getLongArray, "getLongArray", "(Ljava/lang/String;)[J") \ 335 METHOD (getParcelable, "getParcelable", "(Ljava/lang/String;)Landroid/os/Parcelable;") \ 336 METHOD (getString, "getString", "(Ljava/lang/String;)Ljava/lang/String;") \ 337 METHOD (getStringArrayList, "getStringArrayList", "(Ljava/lang/String;)Ljava/util/ArrayList;") \ 338 METHOD (keySet, "keySet", "()Ljava/util/Set;") \ 339 METHOD (putBoolean, "putBoolean", "(Ljava/lang/String;Z)V") \ 340 METHOD (putBundle, "putBundle", "(Ljava/lang/String;Landroid/os/Bundle;)V") \ 341 METHOD (putFloat, "putFloat", "(Ljava/lang/String;F)V") \ 342 METHOD (putInt, "putInt", "(Ljava/lang/String;I)V") \ 343 METHOD (putLong, "putLong", "(Ljava/lang/String;J)V") \ 344 METHOD (putLongArray, "putLongArray", "(Ljava/lang/String;[J)V") \ 345 METHOD (putString, "putString", "(Ljava/lang/String;Ljava/lang/String;)V") \ 346 METHOD (putStringArrayList, "putStringArrayList", "(Ljava/lang/String;Ljava/util/ArrayList;)V") 347 348 DECLARE_JNI_CLASS (AndroidBundle, "android/os/Bundle") 349 #undef JNI_CLASS_MEMBERS 350 351 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 352 STATICMETHOD (dumpReferenceTables, "dumpReferenceTables", "()V") 353 354 DECLARE_JNI_CLASS (AndroidDebug, "android/os/Debug") 355 #undef JNI_CLASS_MEMBERS 356 357 #define JUCE_LOG_JNI_REFERENCES_TABLE getEnv()->CallStaticVoidMethod (AndroidDebug, AndroidDebug.dumpReferenceTables); 358 359 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 360 METHOD (getRotation, "getRotation", "()I") \ 361 METHOD (getMetrics, "getMetrics", "(Landroid/util/DisplayMetrics;)V" ) \ 362 METHOD (getSize, "getSize", "(Landroid/graphics/Point;)V" ) 363 364 DECLARE_JNI_CLASS (AndroidDisplay, "android/view/Display") 365 #undef JNI_CLASS_MEMBERS 366 367 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 368 METHOD (constructor, "<init>", "()V") \ 369 METHOD (constructorWithLooper, "<init>", "(Landroid/os/Looper;)V") \ 370 METHOD (post, "post", "(Ljava/lang/Runnable;)Z") \ 371 METHOD (postDelayed, "postDelayed", "(Ljava/lang/Runnable;J)Z") \ 372 373 DECLARE_JNI_CLASS (AndroidHandler, "android/os/Handler") 374 #undef JNI_CLASS_MEMBERS 375 376 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 377 METHOD (constructor, "<init>", "(Ljava/lang/String;)V") \ 378 METHOD (getLooper, "getLooper", "()Landroid/os/Looper;") \ 379 METHOD (join, "join", "()V") \ 380 METHOD (start, "start", "()V") 381 382 DECLARE_JNI_CLASS (AndroidHandlerThread, "android/os/HandlerThread") 383 #undef JNI_CLASS_MEMBERS 384 385 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 386 STATICMETHOD (createChooser, "createChooser", "(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;") \ 387 METHOD (addCategory, "addCategory", "(Ljava/lang/String;)Landroid/content/Intent;") \ 388 METHOD (constructor, "<init>", "()V") \ 389 METHOD (constructorWithContextAndClass, "<init>", "(Landroid/content/Context;Ljava/lang/Class;)V") \ 390 METHOD (constructWithString, "<init>", "(Ljava/lang/String;)V") \ 391 METHOD (constructWithUri, "<init>", "(Ljava/lang/String;Landroid/net/Uri;)V") \ 392 METHOD (getAction, "getAction", "()Ljava/lang/String;") \ 393 METHOD (getCategories, "getCategories", "()Ljava/util/Set;") \ 394 METHOD (getData, "getData", "()Landroid/net/Uri;") \ 395 METHOD (getExtras, "getExtras", "()Landroid/os/Bundle;") \ 396 METHOD (getIntExtra, "getIntExtra", "(Ljava/lang/String;I)I") \ 397 METHOD (getStringExtra, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;") \ 398 METHOD (putExtra, "putExtra", "(Ljava/lang/String;Ljava/lang/CharSequence;)Landroid/content/Intent;") \ 399 METHOD (putExtras, "putExtras", "(Landroid/os/Bundle;)Landroid/content/Intent;") \ 400 METHOD (putExtraString, "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;") \ 401 METHOD (putExtraStrings, "putExtra", "(Ljava/lang/String;[Ljava/lang/String;)Landroid/content/Intent;") \ 402 METHOD (putExtraParcelable, "putExtra", "(Ljava/lang/String;Landroid/os/Parcelable;)Landroid/content/Intent;") \ 403 METHOD (putParcelableArrayListExtra, "putParcelableArrayListExtra", "(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;") \ 404 METHOD (setAction, "setAction", "(Ljava/lang/String;)Landroid/content/Intent;") \ 405 METHOD (setFlags, "setFlags", "(I)Landroid/content/Intent;") \ 406 METHOD (setPackage, "setPackage", "(Ljava/lang/String;)Landroid/content/Intent;") \ 407 METHOD (setType, "setType", "(Ljava/lang/String;)Landroid/content/Intent;") \ 408 409 DECLARE_JNI_CLASS (AndroidIntent, "android/content/Intent") 410 #undef JNI_CLASS_MEMBERS 411 412 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 413 METHOD (constructor, "<init>", "()V") \ 414 METHOD (postRotate, "postRotate", "(FFF)Z") \ 415 METHOD (postScale, "postScale", "(FFFF)Z") \ 416 METHOD (postTranslate, "postTranslate", "(FF)Z") \ 417 METHOD (setValues, "setValues", "([F)V") \ 418 METHOD (mapRect, "mapRect", "(Landroid/graphics/RectF;)Z") 419 420 DECLARE_JNI_CLASS (AndroidMatrix, "android/graphics/Matrix") 421 #undef JNI_CLASS_MEMBERS 422 423 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 424 METHOD (getPackageInfo, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;") \ 425 METHOD (resolveActivity, "resolveActivity", "(Landroid/content/Intent;I)Landroid/content/pm/ResolveInfo;") \ 426 METHOD (hasSystemFeature, "hasSystemFeature", "(Ljava/lang/String;)Z") 427 428 DECLARE_JNI_CLASS (AndroidPackageManager, "android/content/pm/PackageManager") 429 #undef JNI_CLASS_MEMBERS 430 431 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 432 FIELD (requestedPermissions, "requestedPermissions", "[Ljava/lang/String;") \ 433 FIELD (activities, "activities", "[Landroid/content/pm/ActivityInfo;") \ 434 FIELD (providers, "providers", "[Landroid/content/pm/ProviderInfo;") 435 436 DECLARE_JNI_CLASS (AndroidPackageInfo, "android/content/pm/PackageInfo") 437 #undef JNI_CLASS_MEMBERS 438 439 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 440 FIELD (name, "name", "Ljava/lang/String;") \ 441 FIELD (packageName, "packageName", "Ljava/lang/String;") 442 443 DECLARE_JNI_CLASS (AndroidPackageItemInfo, "android/content/pm/PackageItemInfo") 444 #undef JNI_CLASS_MEMBERS 445 446 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 447 METHOD (constructor, "<init>", "(I)V") \ 448 METHOD (setColor, "setColor", "(I)V") \ 449 METHOD (setAlpha, "setAlpha", "(I)V") \ 450 METHOD (setTypeface, "setTypeface", "(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;") \ 451 METHOD (ascent, "ascent", "()F") \ 452 METHOD (descent, "descent", "()F") \ 453 METHOD (setTextSize, "setTextSize", "(F)V") \ 454 METHOD (getTextWidths, "getTextWidths", "(Ljava/lang/String;[F)I") \ 455 METHOD (setTextScaleX, "setTextScaleX", "(F)V") \ 456 METHOD (getTextPath, "getTextPath", "(Ljava/lang/String;IIFFLandroid/graphics/Path;)V") \ 457 METHOD (getCharsPath, "getTextPath", "([CIIFFLandroid/graphics/Path;)V") \ 458 METHOD (setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \ 459 460 DECLARE_JNI_CLASS (AndroidPaint, "android/graphics/Paint") 461 #undef JNI_CLASS_MEMBERS 462 463 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 464 METHOD (create, "<init>", "(Landroid/graphics/Bitmap;)V") \ 465 METHOD (setMatrix, "setMatrix", "(Landroid/graphics/Matrix;)V") \ 466 METHOD (drawPath, "drawPath", "(Landroid/graphics/Path;Landroid/graphics/Paint;)V") \ 467 METHOD (drawBitmap, "drawBitmap", "([IIIFFIIZLandroid/graphics/Paint;)V") \ 468 METHOD (getClipBounds, "getClipBounds", "()Landroid/graphics/Rect;") 469 470 DECLARE_JNI_CLASS (AndroidCanvas, "android/graphics/Canvas") 471 #undef JNI_CLASS_MEMBERS 472 473 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 474 STATICMETHOD (getActivity, "getActivity", "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;") \ 475 METHOD (getIntentSender, "getIntentSender", "()Landroid/content/IntentSender;") 476 477 DECLARE_JNI_CLASS (AndroidPendingIntent, "android/app/PendingIntent") 478 #undef JNI_CLASS_MEMBERS 479 480 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 481 METHOD (toString, "toString", "()Ljava/lang/String;") 482 483 DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidRange, "android/util/Range", 21) 484 #undef JNI_CLASS_MEMBERS 485 486 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 487 METHOD (create, "<init>", "(II)V") \ 488 FIELD (x, "x", "I") \ 489 FIELD (y, "y", "I") 490 491 DECLARE_JNI_CLASS (AndroidPoint, "android/graphics/Point") 492 #undef JNI_CLASS_MEMBERS 493 494 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 495 METHOD (constructor, "<init>", "(IIII)V") \ 496 FIELD (left, "left", "I") \ 497 FIELD (right, "right", "I") \ 498 FIELD (top, "top", "I") \ 499 FIELD (bottom, "bottom", "I") 500 501 DECLARE_JNI_CLASS (AndroidRect, "android/graphics/Rect") 502 #undef JNI_CLASS_MEMBERS 503 504 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 505 METHOD (getIdentifier, "getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I") \ 506 METHOD (openRawResourceFd, "openRawResourceFd", "(I)Landroid/content/res/AssetFileDescriptor;") 507 508 DECLARE_JNI_CLASS (AndroidResources, "android/content/res/Resources") 509 #undef JNI_CLASS_MEMBERS 510 511 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 512 METHOD (getHeight, "getHeight", "()I") \ 513 METHOD (getWidth, "getWidth", "()I") 514 515 DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidSize, "android/util/Size", 21) 516 #undef JNI_CLASS_MEMBERS 517 518 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 519 STATICMETHOD (parse, "parse", "(Ljava/lang/String;)Landroid/net/Uri;") \ 520 METHOD (toString, "toString", "()Ljava/lang/String;") 521 522 DECLARE_JNI_CLASS (AndroidUri, "android/net/Uri") 523 #undef JNI_CLASS_MEMBERS 524 525 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 526 METHOD (construct, "<init>", "(Landroid/content/Context;)V") \ 527 METHOD (layout, "layout", "(IIII)V") \ 528 METHOD (getLeft, "getLeft", "()I") \ 529 METHOD (getTop, "getTop", "()I") \ 530 METHOD (getWidth, "getWidth", "()I") \ 531 METHOD (getHeight, "getHeight", "()I") \ 532 METHOD (getLocationOnScreen, "getLocationOnScreen", "([I)V") \ 533 METHOD (getParent, "getParent", "()Landroid/view/ViewParent;") \ 534 METHOD (bringToFront, "bringToFront", "()V") \ 535 METHOD (requestFocus, "requestFocus", "()Z") \ 536 METHOD (hasFocus, "hasFocus", "()Z") \ 537 METHOD (invalidate, "invalidate", "(IIII)V") \ 538 METHOD (setVisibility, "setVisibility", "(I)V") \ 539 METHOD (setLayoutParams, "setLayoutParams", "(Landroid/view/ViewGroup$LayoutParams;)V") \ 540 METHOD (setSystemUiVisibility, "setSystemUiVisibility", "(I)V") \ 541 METHOD (findViewById, "findViewById", "(I)Landroid/view/View;") \ 542 METHOD (getRootView, "getRootView", "()Landroid/view/View;") \ 543 METHOD (addOnLayoutChangeListener, "addOnLayoutChangeListener", "(Landroid/view/View$OnLayoutChangeListener;)V") 544 545 DECLARE_JNI_CLASS (AndroidView, "android/view/View") 546 #undef JNI_CLASS_MEMBERS 547 548 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 549 METHOD (addView, "addView", "(Landroid/view/View;)V") \ 550 METHOD (removeView, "removeView", "(Landroid/view/View;)V") 551 552 DECLARE_JNI_CLASS (AndroidViewGroup, "android/view/ViewGroup") 553 #undef JNI_CLASS_MEMBERS 554 555 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 556 METHOD (getDefaultDisplay, "getDefaultDisplay", "()Landroid/view/Display;") 557 558 DECLARE_JNI_CLASS (AndroidWindowManager, "android/view/WindowManager") 559 #undef JNI_CLASS_MEMBERS 560 561 //============================================================================== 562 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 563 METHOD (constructor, "<init>", "(I)V") \ 564 METHOD (add, "add", "(Ljava/lang/Object;)Z") \ 565 METHOD (iterator, "iterator", "()Ljava/util/Iterator;") \ 566 METHOD (get, "get", "(I)Ljava/lang/Object;") \ 567 METHOD (size, "size", "()I") 568 569 DECLARE_JNI_CLASS (JavaArrayList, "java/util/ArrayList") 570 #undef JNI_CLASS_MEMBERS 571 572 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 573 STATICMETHOD (valueOf, "valueOf", "(Z)Ljava/lang/Boolean;") \ 574 METHOD (booleanValue, "booleanValue", "()Z") 575 576 DECLARE_JNI_CLASS (JavaBoolean, "java/lang/Boolean") 577 #undef JNI_CLASS_MEMBERS 578 579 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 580 METHOD (get, "get", "([B)Ljava/nio/ByteBuffer;") \ 581 METHOD (remaining, "remaining", "()I") \ 582 STATICMETHOD (wrap, "wrap", "([B)Ljava/nio/ByteBuffer;") 583 584 DECLARE_JNI_CLASS (JavaByteBuffer, "java/nio/ByteBuffer") 585 #undef JNI_CLASS_MEMBERS 586 587 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 588 METHOD (toString, "toString", "()Ljava/lang/String;") 589 590 DECLARE_JNI_CLASS (JavaCharSequence, "java/lang/CharSequence") 591 #undef JNI_CLASS_MEMBERS 592 593 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 594 STATICMETHOD (forName, "forName", "(Ljava/lang/String;)Ljava/lang/Class;") \ 595 METHOD (getName, "getName", "()Ljava/lang/String;") \ 596 METHOD (getModifiers, "getModifiers", "()I") \ 597 METHOD (isAnnotation, "isAnnotation", "()Z") \ 598 METHOD (isAnonymousClass, "isAnonymousClass", "()Z") \ 599 METHOD (isArray, "isArray", "()Z") \ 600 METHOD (isEnum, "isEnum", "()Z") \ 601 METHOD (isInterface, "isInterface", "()Z") \ 602 METHOD (isLocalClass, "isLocalClass", "()Z") \ 603 METHOD (isMemberClass, "isMemberClass", "()Z") \ 604 METHOD (isPrimitive, "isPrimitive", "()Z") \ 605 METHOD (isSynthetic, "isSynthetic", "()Z") \ 606 METHOD (getComponentType, "getComponentType", "()Ljava/lang/Class;") \ 607 METHOD (getSuperclass, "getSuperclass", "()Ljava/lang/Class;") \ 608 METHOD (getClassLoader, "getClassLoader", "()Ljava/lang/ClassLoader;") \ 609 610 DECLARE_JNI_CLASS (JavaClass, "java/lang/Class") 611 #undef JNI_CLASS_MEMBERS 612 613 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 614 METHOD (toString, "toString", "()Ljava/lang/String;") 615 616 DECLARE_JNI_CLASS (JavaEnum, "java/lang/Enum") 617 #undef JNI_CLASS_MEMBERS 618 619 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 620 METHOD (constructor, "<init>", "(Ljava/lang/String;)V") \ 621 METHOD (getAbsolutePath, "getAbsolutePath", "()Ljava/lang/String;") \ 622 METHOD (length, "length", "()J") 623 624 DECLARE_JNI_CLASS (JavaFile, "java/io/File") 625 #undef JNI_CLASS_MEMBERS 626 627 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 628 METHOD (constructor, "<init>", "(Ljava/lang/String;)V") \ 629 METHOD (close, "close", "()V") \ 630 METHOD (read, "read", "([B)I") 631 632 DECLARE_JNI_CLASS (JavaFileInputStream, "java/io/FileInputStream") 633 #undef JNI_CLASS_MEMBERS 634 635 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 636 METHOD (constructor, "<init>", "(Ljava/lang/String;)V") \ 637 METHOD (close, "close", "()V") \ 638 METHOD (write, "write", "([BII)V") 639 640 DECLARE_JNI_CLASS (JavaFileOutputStream, "java/io/FileOutputStream") 641 #undef JNI_CLASS_MEMBERS 642 643 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 644 METHOD (constructor, "<init>", "()V") \ 645 METHOD (constructorWithCapacity, "<init>", "(I)V") 646 647 DECLARE_JNI_CLASS (JavaHashMap, "java/util/HashMap") 648 #undef JNI_CLASS_MEMBERS 649 650 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 651 STATICMETHOD (parseInt, "parseInt", "(Ljava/lang/String;I)I") \ 652 STATICMETHOD (valueOf, "valueOf", "(I)Ljava/lang/Integer;") \ 653 METHOD (intValue, "intValue", "()I") 654 655 DECLARE_JNI_CLASS (JavaInteger, "java/lang/Integer") 656 #undef JNI_CLASS_MEMBERS 657 658 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 659 METHOD (hasNext, "hasNext", "()Z") \ 660 METHOD (next, "next", "()Ljava/lang/Object;") 661 662 DECLARE_JNI_CLASS (JavaIterator, "java/util/Iterator") 663 #undef JNI_CLASS_MEMBERS 664 665 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 666 METHOD (get, "get", "(I)Ljava/lang/Object;") \ 667 METHOD (size, "size", "()I") 668 669 DECLARE_JNI_CLASS (JavaList, "java/util/List") 670 #undef JNI_CLASS_MEMBERS 671 672 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 673 METHOD (constructor, "<init>", "(J)V") 674 675 DECLARE_JNI_CLASS (JavaLong, "java/lang/Long") 676 #undef JNI_CLASS_MEMBERS 677 678 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 679 METHOD (get, "get", "(Ljava/lang/Object;)Ljava/lang/Object;") \ 680 METHOD (keySet, "keySet", "()Ljava/util/Set;") \ 681 METHOD (put, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") 682 683 DECLARE_JNI_CLASS (JavaMap, "java/util/Map") 684 #undef JNI_CLASS_MEMBERS 685 686 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 687 METHOD (getName, "getName", "()Ljava/lang/String;") \ 688 METHOD (getModifiers, "getModifiers", "()I") \ 689 METHOD (getParameterTypes, "getParameterTypes", "()[Ljava/lang/Class;") \ 690 METHOD (getReturnType, "getReturnType", "()Ljava/lang/Class;") \ 691 METHOD (invoke, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;") \ 692 METHOD (hashCode, "hashCode", "()I") \ 693 METHOD (equals, "equals", "(Ljava/lang/Object;)Z") \ 694 695 DECLARE_JNI_CLASS (JavaMethod, "java/lang/reflect/Method") 696 #undef JNI_CLASS_MEMBERS 697 698 699 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 700 METHOD (constructor, "<init>", "()V") \ 701 METHOD (getClass, "getClass", "()Ljava/lang/Class;") \ 702 METHOD (toString, "toString", "()Ljava/lang/String;") 703 704 DECLARE_JNI_CLASS (JavaObject, "java/lang/Object") 705 #undef JNI_CLASS_MEMBERS 706 707 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 708 METHOD (contains, "contains", "(Ljava/lang/Object;)Z") \ 709 METHOD (iterator, "iterator", "()Ljava/util/Iterator;") \ 710 METHOD (size, "size", "()I") 711 712 DECLARE_JNI_CLASS (JavaSet, "java/util/Set") 713 #undef JNI_CLASS_MEMBERS 714 715 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 716 METHOD (concat, "concat", "(Ljava/lang/String;)Ljava/lang/String;") \ 717 METHOD (getBytes, "getBytes", "()[B") 718 719 DECLARE_JNI_CLASS (JavaString, "java/lang/String") 720 #undef JNI_CLASS_MEMBERS 721 722 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) 723 DECLARE_JNI_CLASS (AndroidBuild, "android/os/Build") 724 #undef JNI_CLASS_MEMBERS 725 726 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) 727 DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION") 728 #undef JNI_CLASS_MEMBERS 729 730 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 731 METHOD (registerActivityLifecycleCallbacks, "registerActivityLifecycleCallbacks", "(Landroid/app/Application$ActivityLifecycleCallbacks;)V") \ 732 METHOD (unregisterActivityLifecycleCallbacks, "unregisterActivityLifecycleCallbacks", "(Landroid/app/Application$ActivityLifecycleCallbacks;)V") 733 734 DECLARE_JNI_CLASS (AndroidApplication, "android/app/Application") 735 #undef JNI_CLASS_MEMBERS 736 737 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 738 METHOD (constructor, "<init>", "(Landroid/content/Context;)V") \ 739 METHOD (getHolder, "getHolder", "()Landroid/view/SurfaceHolder;") \ 740 METHOD (getParent, "getParent", "()Landroid/view/ViewParent;") 741 742 DECLARE_JNI_CLASS (AndroidSurfaceView, "android/view/SurfaceView") 743 #undef JNI_CLASS_MEMBERS 744 745 746 #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ 747 METHOD (getSurface, "getSurface", "()Landroid/view/Surface;") \ 748 METHOD (addCallback, "addCallback", "(Landroid/view/SurfaceHolder$Callback;)V") \ 749 METHOD (removeCallback, "removeCallback", "(Landroid/view/SurfaceHolder$Callback;)V") 750 751 DECLARE_JNI_CLASS (AndroidSurfaceHolder, "android/view/SurfaceHolder") 752 #undef JNI_CLASS_MEMBERS 753 754 //============================================================================== 755 namespace 756 { juceString(JNIEnv * env,jstring s)757 inline String juceString (JNIEnv* env, jstring s) 758 { 759 if (s == nullptr) 760 return {}; 761 762 const char* const utf8 = env->GetStringUTFChars (s, nullptr); 763 CharPointer_UTF8 utf8CP (utf8); 764 const String result (utf8CP); 765 env->ReleaseStringUTFChars (s, utf8); 766 return result; 767 } 768 juceString(jstring s)769 inline String juceString (jstring s) 770 { 771 return juceString (getEnv(), s); 772 } 773 javaString(const String & s)774 inline LocalRef<jstring> javaString (const String& s) 775 { 776 return LocalRef<jstring> (getEnv()->NewStringUTF (s.toUTF8())); 777 } 778 javaStringFromChar(const juce_wchar c)779 inline LocalRef<jstring> javaStringFromChar (const juce_wchar c) 780 { 781 char utf8[8] = { 0 }; 782 CharPointer_UTF8 (utf8).write (c); 783 return LocalRef<jstring> (getEnv()->NewStringUTF (utf8)); 784 } 785 juceStringArrayToJava(const StringArray & juceArray)786 inline LocalRef<jobjectArray> juceStringArrayToJava (const StringArray& juceArray) 787 { 788 auto* env = getEnv(); 789 790 LocalRef<jobjectArray> result (env->NewObjectArray ((jsize) juceArray.size(), 791 JavaString, 792 javaString ("").get())); 793 794 for (int i = 0; i < juceArray.size(); ++i) 795 env->SetObjectArrayElement (result, i, javaString (juceArray [i]).get()); 796 797 return result; 798 } 799 javaStringArrayToJuce(const LocalRef<jobjectArray> & javaArray)800 inline StringArray javaStringArrayToJuce (const LocalRef<jobjectArray>& javaArray) 801 { 802 if (javaArray.get() == nullptr) 803 return {}; 804 805 auto* env = getEnv(); 806 807 StringArray result; 808 809 for (int i = 0; i < env->GetArrayLength (javaArray.get()); ++i) 810 { 811 LocalRef<jstring> javaString ((jstring) env->GetObjectArrayElement (javaArray.get(), i)); 812 result.add (juceString (javaString.get())); 813 } 814 815 return result; 816 } 817 jniCheckHasExceptionOccurredAndClear()818 inline bool jniCheckHasExceptionOccurredAndClear() 819 { 820 auto* env = getEnv(); 821 822 LocalRef<jobject> exception (env->ExceptionOccurred()); 823 824 if (exception != nullptr) 825 { 826 env->ExceptionClear(); 827 return true; 828 } 829 830 return false; 831 } 832 } 833 834 //============================================================================== 835 int getAndroidSDKVersion(); 836 bool isPermissionDeclaredInManifest (const String& requestedPermission); 837 838 //============================================================================== 839 class AndroidInterfaceImplementer; 840 841 // This function takes ownership of the implementer. When the returned GlobalRef 842 // goes out of scope (and no other Java routine has a reference on the return-value) 843 // then the implementer will be deleted as well. 844 LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer, 845 const StringArray& interfaceNames, 846 LocalRef<jobject> subclass); 847 848 //============================================================================== 849 jobject juce_invokeImplementer (JNIEnv*, jobject, jlong, jobject, jobject, jobjectArray); 850 void juce_dispatchDelete (JNIEnv*, jobject, jlong); 851 852 //============================================================================== 853 class AndroidInterfaceImplementer 854 { 855 protected: 856 virtual ~AndroidInterfaceImplementer(); 857 virtual jobject invoke (jobject proxy, jobject method, jobjectArray args); 858 void clear(); 859 860 //============================================================================== 861 friend LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer*, const StringArray&, LocalRef<jobject>); 862 friend jobject juce_invokeImplementer (JNIEnv*, jobject, jlong, jobject, jobject, jobjectArray); 863 friend void juce_dispatchDelete (JNIEnv*, jobject, jlong); 864 private: 865 GlobalRef javaSubClass; 866 GlobalRef invocationHandler; 867 }; 868 869 LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer, 870 const StringArray& interfaceNames); 871 LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer, 872 const String& interfaceName); 873 874 //============================================================================== 875 class ActivityLifecycleCallbacks : public AndroidInterfaceImplementer 876 { 877 public: onActivityPreCreated(jobject,jobject)878 virtual void onActivityPreCreated (jobject /*activity*/, jobject /*bundle*/) {} onActivityPreDestroyed(jobject)879 virtual void onActivityPreDestroyed (jobject /*activity*/) {} onActivityPrePaused(jobject)880 virtual void onActivityPrePaused (jobject /*activity*/) {} onActivityPreResumed(jobject)881 virtual void onActivityPreResumed (jobject /*activity*/) {} onActivityPreSaveInstanceState(jobject,jobject)882 virtual void onActivityPreSaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {} onActivityPreStarted(jobject)883 virtual void onActivityPreStarted (jobject /*activity*/) {} onActivityPreStopped(jobject)884 virtual void onActivityPreStopped (jobject /*activity*/) {} 885 onActivityCreated(jobject,jobject)886 virtual void onActivityCreated (jobject /*activity*/, jobject /*bundle*/) {} onActivityDestroyed(jobject)887 virtual void onActivityDestroyed (jobject /*activity*/) {} onActivityPaused(jobject)888 virtual void onActivityPaused (jobject /*activity*/) {} onActivityResumed(jobject)889 virtual void onActivityResumed (jobject /*activity*/) {} onActivitySaveInstanceState(jobject,jobject)890 virtual void onActivitySaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {} onActivityStarted(jobject)891 virtual void onActivityStarted (jobject /*activity*/) {} onActivityStopped(jobject)892 virtual void onActivityStopped (jobject /*activity*/) {} 893 onActivityPostCreated(jobject,jobject)894 virtual void onActivityPostCreated (jobject /*activity*/, jobject /*bundle*/) {} onActivityPostDestroyed(jobject)895 virtual void onActivityPostDestroyed (jobject /*activity*/) {} onActivityPostPaused(jobject)896 virtual void onActivityPostPaused (jobject /*activity*/) {} onActivityPostResumed(jobject)897 virtual void onActivityPostResumed (jobject /*activity*/) {} onActivityPostSaveInstanceState(jobject,jobject)898 virtual void onActivityPostSaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {} onActivityPostStarted(jobject)899 virtual void onActivityPostStarted (jobject /*activity*/) {} onActivityPostStopped(jobject)900 virtual void onActivityPostStopped (jobject /*activity*/) {} 901 902 private: 903 jobject invoke (jobject, jobject, jobjectArray) override; 904 }; 905 906 //============================================================================== 907 struct SurfaceHolderCallback : AndroidInterfaceImplementer 908 { 909 virtual ~SurfaceHolderCallback() override = default; 910 911 virtual void surfaceChanged (LocalRef<jobject> holder, int format, int width, int height) = 0; 912 virtual void surfaceCreated (LocalRef<jobject> holder) = 0; 913 virtual void surfaceDestroyed (LocalRef<jobject> holder) = 0; 914 915 private: invokeSurfaceHolderCallback916 jobject invoke (jobject proxy, jobject method, jobjectArray args) override 917 { 918 auto* env = getEnv(); 919 auto methodName = juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName)); 920 LocalRef<jobject> holder (env->GetArrayLength (args) > 0 ? env->GetObjectArrayElement (args, 0) : (jobject) nullptr); 921 922 if (methodName == "surfaceChanged") 923 { 924 int intArgs[3]; 925 926 for (int i = 0; i < 3; ++i) 927 { 928 LocalRef<jobject> boxedType (env->GetObjectArrayElement (args, 1 + i)); 929 intArgs[i] = env->CallIntMethod (boxedType.get(), JavaInteger.intValue); 930 } 931 932 surfaceChanged (std::move (holder), intArgs[0], intArgs[1], intArgs[2]); 933 } 934 else if (methodName == "surfaceCreated") 935 { 936 surfaceCreated (std::move (holder)); 937 } 938 else if (methodName == "surfaceDestroyed") 939 { 940 surfaceDestroyed (std::move (holder)); 941 } 942 else 943 { 944 return AndroidInterfaceImplementer::invoke (proxy, method, args); 945 } 946 947 return nullptr; 948 } 949 }; 950 951 //============================================================================== 952 class FragmentOverlay 953 { 954 public: 955 FragmentOverlay(); 956 virtual ~FragmentOverlay(); 957 958 void open(); 959 onCreated(LocalRef<jobject>)960 virtual void onCreated (LocalRef<jobject> /*bundle*/) {} onStart()961 virtual void onStart() {} onRequestPermissionsResult(int,const StringArray &,const Array<int> &)962 virtual void onRequestPermissionsResult (int /*requestCode*/, 963 const StringArray& /*permissions*/, 964 const Array<int>& /*grantResults*/) {} onActivityResult(int,int,LocalRef<jobject>)965 virtual void onActivityResult (int /*requestCode*/, int /*resultCode*/, LocalRef<jobject> /*data*/) {} 966 967 protected: 968 jobject getNativeHandle(); 969 970 private: 971 972 GlobalRef native; 973 974 public: 975 /* internal: do not use */ 976 static void onActivityResultNative (JNIEnv*, jobject, jlong, jint, jint, jobject); 977 static void onCreateNative (JNIEnv*, jobject, jlong, jobject); 978 static void onStartNative (JNIEnv*, jobject, jlong); 979 static void onRequestPermissionsResultNative (JNIEnv*, jobject, jlong, jint, 980 jobjectArray, jintArray); 981 }; 982 983 //============================================================================== 984 // Allows you to start an activity without requiring to have an activity 985 void startAndroidActivityForResult (const LocalRef<jobject>& intent, int requestCode, 986 std::function<void (int, int, LocalRef<jobject>)> && callback); 987 988 //============================================================================== 989 bool androidHasSystemFeature (const String& property); 990 String audioManagerGetProperty (const String& property); 991 992 } // namespace juce 993