diff --git a/gradle/include/android/grandroid_ext.h b/gradle/include/android/grandroid_ext.h index a23f1180..74d5adfe 100644 --- a/gradle/include/android/grandroid_ext.h +++ b/gradle/include/android/grandroid_ext.h @@ -27,16 +27,28 @@ */ #include +#include +#include +#include +#include + +#define ENABLE_DEBUG_LOG 1 +#define LOG_TAG "GraalGluon" + +#if ENABLE_DEBUG_LOG == 1 +#define LOGD(ignore, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#define LOGE(ignore, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#else +#define LOGD(ignore, ...) +#define LOGE(ignore, ...) +#endif + extern jclass activityClass; extern jobject activity; -extern JavaVM *androidVM; -extern JNIEnv *androidEnv; - -// expose AndroidVM, Env, MainActivity and its class +// expose AndroidVM, MainActivity and its class JavaVM* substrateGetAndroidVM(); -JNIEnv* substrateGetAndroidEnv(); jclass substrateGetActivityClass(); jclass substrateGetPermissionActivityClass(); jobject substrateGetActivity(); @@ -51,3 +63,30 @@ void __attribute__((weak)) attach_setLifecycleEvent(const char *event) {} void attach_setActivityResult(jint requestCode, jint resultCode, jobject intent); void attach_setLifecycleEvent(const char *event); #endif + +#define ATTACH_GRAAL() \ + JNIEnv *graalEnv; \ + JavaVM* graalVM = getGraalVM(); \ + int tid = gettid(); \ + int attach_graal_det = ((*graalVM)->GetEnv(graalVM, (void **)&graalEnv, JNI_VERSION_1_6) == JNI_OK); \ + (*graalVM)->AttachCurrentThreadAsDaemon(graalVM, (void **) &graalEnv, NULL); \ + LOGD(stderr, "ATTACH_GRAAL, tid = %d, existed? %d, graalEnv at %p\n", tid, attach_graal_det, graalEnv); + +#define DETACH_GRAAL() \ + int tid_detach = gettid(); \ + LOGD(stderr, "DETACH_GRAAL, tid = %d, graalVM = %p, existed = %d, env at %p\n", tid_detach, graalVM, attach_graal_det, graalEnv); \ + if (attach_graal_det == 0) (*graalVM)->DetachCurrentThread(graalVM); + +#define ATTACH_DALVIK() \ + JNIEnv *dalvikEnv; \ + JavaVM* dalvikVM = substrateGetAndroidVM(); \ + int dalviktid = gettid(); \ + int attach_dalvik_det = ((*dalvikVM)->GetEnv(dalvikVM, (void **)&dalvikEnv, JNI_VERSION_1_6) == JNI_OK); \ + (*dalvikVM)->AttachCurrentThreadAsDaemon(dalvikVM, (void **) &dalvikEnv, NULL); \ + LOGD(stderr, "ATTACH_DALVIK, tid = %d, existed? %d, dalvikEnv at %p\n", dalviktid, attach_dalvik_det, dalvikEnv); + +#define DETACH_DALVIK() \ + int dalviktid_detach = gettid(); \ + LOGD(stderr, "DETACH_DALVIK, tid = %d, existed = %d, env at %p\n", dalviktid_detach, attach_dalvik_det, dalvikEnv); \ + if (attach_dalvik_det == 0) (*dalvikVM)->DetachCurrentThread(dalvikVM); + diff --git a/gradle/native-build.gradle b/gradle/native-build.gradle index dd37a288..c0978998 100644 --- a/gradle/native-build.gradle +++ b/gradle/native-build.gradle @@ -160,7 +160,7 @@ ext.nativeBuild = { buildDir, projectDir, name, os -> File nativeSourcesDir = file("$projectDir/src/main/native/$os/c/") osSources = [nativeSourcesDir.listFiles().findAll {it.name.endsWith(".c")}].flatten() - def compilerArgs = ["-target", platform, "-c", includeFlags, osIncludeFlags, osSources].flatten() + def compilerArgs = ["-target", platform, "-Werror", "-c", includeFlags, osIncludeFlags, osSources].flatten() exec { executable compiler @@ -205,4 +205,4 @@ ext.nativeBuild = { buildDir, projectDir, name, os -> .first() } } -} \ No newline at end of file +} diff --git a/modules/ble/src/main/native/android/c/Ble.c b/modules/ble/src/main/native/android/c/Ble.c index d47331d8..466f9c18 100644 --- a/modules/ble/src/main/native/android/c/Ble.c +++ b/modules/ble/src/main/native/android/c/Ble.c @@ -27,9 +27,6 @@ */ #include "Ble.h" -static JNIEnv *graalEnv; -JNIEnv* javaEnvBle = NULL; -JavaVM *jVMBle = NULL; static jclass jGraalBleClass; static jmethodID jGraalSetDetectionMethod; static jmethodID jGraalSetDeviceDetectionMethod; @@ -39,7 +36,6 @@ static jmethodID jGraalSetDeviceCharMethod; static jmethodID jGraalSetDeviceDescMethod; static jmethodID jGraalSetDeviceValueMethod; -static JavaVM *myAndroidVM = NULL; static jobject jDalvikBleService; static jmethodID jBleServiceStartScanningMethod; static jmethodID jBleServiceStopScanningMethod; @@ -68,30 +64,28 @@ void initializeGraalHandles(JNIEnv *graalEnv) { jGraalSetDeviceValueMethod = (*graalEnv)->GetStaticMethodID(graalEnv, jGraalBleClass, "gotValue", "(Ljava/lang/String;Ljava/lang/String;[B)V"); } -void initializeDalvikHandles() { - myAndroidVM = substrateGetAndroidVM(); +void initializeBleDalvikHandles() { jclass jBleServiceClass = substrateGetBleServiceClass(); - JNIEnv* androidEnv; - (*myAndroidVM)->AttachCurrentThread(myAndroidVM, (void **)&androidEnv, NULL); - jmethodID jBleServiceInitMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "", "(Landroid/app/Activity;)V"); - jBleServiceStartScanningMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "startScanning", "()V"); - jBleServiceStopScanningMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "stopScanning", "()V"); - jBleServiceStartBroadcastMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "startBroadcast", "(Ljava/lang/String;IILjava/lang/String;)V"); - jBleServiceStopBroadcastMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "stopBroadcast", "()V"); - jBleServiceEnableDebug = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "enableDebug", "()V"); - - jBleServiceStartScanningPeripheralsMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "startScanningPeripherals", "()V"); - jBleServiceStopScanningPeripheralsMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "stopScanningPeripherals", "()V"); - jBleServiceConnectMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "connect", "(Ljava/lang/String;Ljava/lang/String;)V"); - jBleServiceDisconnectMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "disconnect", "(Ljava/lang/String;Ljava/lang/String;)V"); - jBleServiceReadMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "read", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - jBleServiceWriteMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "write", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)V"); - jBleServiceSubscribeMethod = (*androidEnv)->GetMethodID(androidEnv, jBleServiceClass, "subscribe", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V"); + ATTACH_DALVIK(); + jmethodID jBleServiceInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "", "(Landroid/app/Activity;)V"); + jBleServiceStartScanningMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "startScanning", "()V"); + jBleServiceStopScanningMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "stopScanning", "()V"); + jBleServiceStartBroadcastMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "startBroadcast", "(Ljava/lang/String;IILjava/lang/String;)V"); + jBleServiceStopBroadcastMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "stopBroadcast", "()V"); + jBleServiceEnableDebug = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "enableDebug", "()V"); + + jBleServiceStartScanningPeripheralsMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "startScanningPeripherals", "()V"); + jBleServiceStopScanningPeripheralsMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "stopScanningPeripherals", "()V"); + jBleServiceConnectMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "connect", "(Ljava/lang/String;Ljava/lang/String;)V"); + jBleServiceDisconnectMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "disconnect", "(Ljava/lang/String;Ljava/lang/String;)V"); + jBleServiceReadMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "read", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + jBleServiceWriteMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "write", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)V"); + jBleServiceSubscribeMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBleServiceClass, "subscribe", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V"); jobject jActivity = substrateGetActivity(); - jobject jtmpobj = (*androidEnv)->NewObject(androidEnv, jBleServiceClass, jBleServiceInitMethod, jActivity); - jDalvikBleService = (*androidEnv)->NewGlobalRef(androidEnv, jtmpobj); - (*myAndroidVM)->DetachCurrentThread(myAndroidVM); + jobject jtmpobj = (*dalvikEnv)->NewObject(dalvikEnv, jBleServiceClass, jBleServiceInitMethod, jActivity); + jDalvikBleService = (*dalvikEnv)->NewGlobalRef(dalvikEnv, jtmpobj); + DETACH_DALVIK(); } ////////////////////////// @@ -104,14 +98,14 @@ JNI_OnLoad_Ble(JavaVM *vm, void *reserved) { fprintf(stderr, "JNI_OnLoad_BLE called\n"); #ifdef JNI_VERSION_1_8 - jVMBle = vm; + JNIEnv* graalEnv; if ((*vm)->GetEnv(vm, (void **)&graalEnv, JNI_VERSION_1_8) != JNI_OK) { ATTACH_LOG_WARNING("Error initializing native Ble from OnLoad"); return JNI_FALSE; } ATTACH_LOG_FINE("[BLESERVICE] Initializing native BLE from OnLoad"); initializeGraalHandles(graalEnv); - initializeDalvikHandles(); + initializeBleDalvikHandles(); ATTACH_LOG_FINE("Initializing native Ble done"); return JNI_VERSION_1_8; #else @@ -121,20 +115,12 @@ fprintf(stderr, "JNI_OnLoad_BLE called\n"); // from Java to Android -JNIEnv* getSafeAndroidEnv() { - JNIEnv* androidEnv; - if ((*myAndroidVM)->GetEnv(myAndroidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("enableDalvikDebug called from not-attached thread\n"); - (*myAndroidVM)->AttachCurrentThread(myAndroidVM, (void **)&androidEnv, NULL); - } - return androidEnv; -} - JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_enableDebug (JNIEnv *env, jclass jClass) { - JNIEnv* androidEnv = getSafeAndroidEnv(); debugBLE = JNI_TRUE; - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceEnableDebug); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceEnableDebug); + DETACH_DALVIK(); } // BLE BEACONS @@ -144,37 +130,38 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_startO { int uuidCount = (*env)->GetArrayLength(env, jUuidsArray); fprintf(stderr, "ble.c startObserver\n"); - JNIEnv* androidEnv = getSafeAndroidEnv(); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceStartScanningMethod); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceStartScanningMethod); + DETACH_DALVIK(); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_stopObserver (JNIEnv *env, jclass jClass) { - fprintf(stderr, "ble.c stopObserver\n"); - JNIEnv* androidEnv = getSafeAndroidEnv(); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceStopScanningMethod); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceStopScanningMethod); + DETACH_DALVIK(); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_startBroadcast (JNIEnv *env, jclass jClass, jstring jUuid, jint major, jint minor, jstring jId) { const char *uuidChars = (*env)->GetStringUTFChars(env, jUuid, NULL); const char *idChars = (*env)->GetStringUTFChars(env, jId, NULL); - JNIEnv* androidEnv = getSafeAndroidEnv(); - jstring duuid = (*androidEnv)->NewStringUTF(androidEnv, uuidChars); - jstring did = (*androidEnv)->NewStringUTF(androidEnv, idChars); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceStartBroadcastMethod, + ATTACH_DALVIK(); + jstring duuid = (*dalvikEnv)->NewStringUTF(dalvikEnv, uuidChars); + jstring did = (*dalvikEnv)->NewStringUTF(dalvikEnv, idChars); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceStartBroadcastMethod, duuid, major, minor, did); - (*androidEnv)->DeleteLocalRef(androidEnv, duuid); - (*androidEnv)->DeleteLocalRef(androidEnv, did); - (*env)->ReleaseStringUTFChars(env, jUuid, uuidChars); - (*env)->ReleaseStringUTFChars(env, jId, idChars); + DETACH_DALVIK(); + // (*env)->ReleaseStringUTFChars(env, jUuid, uuidChars); + // (*env)->ReleaseStringUTFChars(env, jId, idChars); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_stopBroadcast (JNIEnv *env, jclass jClass) { - JNIEnv* androidEnv = getSafeAndroidEnv(); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceStopBroadcastMethod); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceStopBroadcastMethod); + DETACH_DALVIK(); } // BLE DEVICES @@ -182,15 +169,17 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_stopBr JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_startScanningPeripherals (JNIEnv *env, jclass jClass) { - JNIEnv* androidEnv = getSafeAndroidEnv(); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceStartScanningPeripheralsMethod); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceStartScanningPeripheralsMethod); + DETACH_DALVIK(); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_stopScanningPeripherals (JNIEnv *env, jclass jClass) { - JNIEnv* androidEnv = getSafeAndroidEnv(); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceStopScanningPeripheralsMethod); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceStopScanningPeripheralsMethod); + DETACH_DALVIK(); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doConnect @@ -198,15 +187,14 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doConn { const char *nameChars = (*env)->GetStringUTFChars(env, jName, NULL); const char *addressChars = (*env)->GetStringUTFChars(env, jAddress, NULL); - JNIEnv* androidEnv = getSafeAndroidEnv(); - jstring dname = (*androidEnv)->NewStringUTF(androidEnv, nameChars); - jstring daddress = (*androidEnv)->NewStringUTF(androidEnv, addressChars); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceConnectMethod, + ATTACH_DALVIK(); + jstring dname = (*dalvikEnv)->NewStringUTF(dalvikEnv, nameChars); + jstring daddress = (*dalvikEnv)->NewStringUTF(dalvikEnv, addressChars); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceConnectMethod, dname, daddress); - (*androidEnv)->DeleteLocalRef(androidEnv, dname); - (*androidEnv)->DeleteLocalRef(androidEnv, daddress); - (*env)->ReleaseStringUTFChars(env, jName, nameChars); - (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); + DETACH_DALVIK(); + // (*env)->ReleaseStringUTFChars(env, jName, nameChars); + // (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doDisconnect @@ -214,15 +202,14 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doDisc { const char *nameChars = (*env)->GetStringUTFChars(env, jName, NULL); const char *addressChars = (*env)->GetStringUTFChars(env, jAddress, NULL); - JNIEnv* androidEnv = getSafeAndroidEnv(); - jstring dname = (*androidEnv)->NewStringUTF(androidEnv, nameChars); - jstring daddress = (*androidEnv)->NewStringUTF(androidEnv, addressChars); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceDisconnectMethod, + ATTACH_DALVIK(); + jstring dname = (*dalvikEnv)->NewStringUTF(dalvikEnv, nameChars); + jstring daddress = (*dalvikEnv)->NewStringUTF(dalvikEnv, addressChars); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceDisconnectMethod, dname, daddress); - (*androidEnv)->DeleteLocalRef(androidEnv, dname); - (*androidEnv)->DeleteLocalRef(androidEnv, daddress); - (*env)->ReleaseStringUTFChars(env, jName, nameChars); - (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); + DETACH_DALVIK(); + // (*env)->ReleaseStringUTFChars(env, jName, nameChars); + // (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doRead @@ -231,18 +218,16 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doRead const char *addressChars = (*env)->GetStringUTFChars(env, jAddress, NULL); const char *profileChars = (*env)->GetStringUTFChars(env, jProfile, NULL); const char *characteristicChars = (*env)->GetStringUTFChars(env, jCharacteristic, NULL); - JNIEnv* androidEnv = getSafeAndroidEnv(); - jstring daddress = (*androidEnv)->NewStringUTF(androidEnv, addressChars); - jstring dprofile = (*androidEnv)->NewStringUTF(androidEnv, profileChars); - jstring dcharacteristic = (*androidEnv)->NewStringUTF(androidEnv, characteristicChars); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceReadMethod, + ATTACH_DALVIK(); + jstring daddress = (*dalvikEnv)->NewStringUTF(dalvikEnv, addressChars); + jstring dprofile = (*dalvikEnv)->NewStringUTF(dalvikEnv, profileChars); + jstring dcharacteristic = (*dalvikEnv)->NewStringUTF(dalvikEnv, characteristicChars); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceReadMethod, daddress, dprofile, dcharacteristic); - (*androidEnv)->DeleteLocalRef(androidEnv, daddress); - (*androidEnv)->DeleteLocalRef(androidEnv, dprofile); - (*androidEnv)->DeleteLocalRef(androidEnv, dcharacteristic); - (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); - (*env)->ReleaseStringUTFChars(env, jProfile, profileChars); - (*env)->ReleaseStringUTFChars(env, jCharacteristic, characteristicChars); + DETACH_DALVIK(); + // (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); + // (*env)->ReleaseStringUTFChars(env, jProfile, profileChars); + // (*env)->ReleaseStringUTFChars(env, jCharacteristic, characteristicChars); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doWrite @@ -254,23 +239,20 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doWrit jbyte *valueBytes = (*env)->GetByteArrayElements(env, value, NULL); int size = (*env)->GetArrayLength(env, value); - JNIEnv* androidEnv = getSafeAndroidEnv(); - jstring daddress = (*androidEnv)->NewStringUTF(androidEnv, addressChars); - jstring dprofile = (*androidEnv)->NewStringUTF(androidEnv, profileChars); - jstring dcharacteristic = (*androidEnv)->NewStringUTF(androidEnv, characteristicChars); - jbyteArray jvalue = (*androidEnv)->NewByteArray(androidEnv, size); - (*androidEnv)->SetByteArrayRegion(androidEnv, jvalue, 0, size, valueBytes); + ATTACH_DALVIK(); + jstring daddress = (*dalvikEnv)->NewStringUTF(dalvikEnv, addressChars); + jstring dprofile = (*dalvikEnv)->NewStringUTF(dalvikEnv, profileChars); + jstring dcharacteristic = (*dalvikEnv)->NewStringUTF(dalvikEnv, characteristicChars); + jbyteArray jvalue = (*dalvikEnv)->NewByteArray(dalvikEnv, size); + (*dalvikEnv)->SetByteArrayRegion(dalvikEnv, jvalue, 0, size, valueBytes); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceWriteMethod, + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceWriteMethod, daddress, dprofile, dcharacteristic, jvalue); - (*androidEnv)->DeleteLocalRef(androidEnv, daddress); - (*androidEnv)->DeleteLocalRef(androidEnv, dprofile); - (*androidEnv)->DeleteLocalRef(androidEnv, dcharacteristic); - (*androidEnv)->DeleteLocalRef(androidEnv, jvalue); - (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); - (*env)->ReleaseStringUTFChars(env, jProfile, profileChars); - (*env)->ReleaseStringUTFChars(env, jCharacteristic, characteristicChars); - (*env)->ReleaseByteArrayElements(env, value, valueBytes, JNI_ABORT); + DETACH_DALVIK(); + // (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); + // (*env)->ReleaseStringUTFChars(env, jProfile, profileChars); + // (*env)->ReleaseStringUTFChars(env, jCharacteristic, characteristicChars); + // (*env)->ReleaseByteArrayElements(env, value, valueBytes, JNI_ABORT); } JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doSubscribe @@ -280,19 +262,17 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_ble_impl_AndroidBleService_doSubs const char *profileChars = (*env)->GetStringUTFChars(env, jProfile, NULL); const char *characteristicChars = (*env)->GetStringUTFChars(env, jCharacteristic, NULL); - JNIEnv* androidEnv = getSafeAndroidEnv(); - jstring daddress = (*androidEnv)->NewStringUTF(androidEnv, addressChars); - jstring dprofile = (*androidEnv)->NewStringUTF(androidEnv, profileChars); - jstring dcharacteristic = (*androidEnv)->NewStringUTF(androidEnv, characteristicChars); + ATTACH_DALVIK(); + jstring daddress = (*dalvikEnv)->NewStringUTF(dalvikEnv, addressChars); + jstring dprofile = (*dalvikEnv)->NewStringUTF(dalvikEnv, profileChars); + jstring dcharacteristic = (*dalvikEnv)->NewStringUTF(dalvikEnv, characteristicChars); - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikBleService, jBleServiceSubscribeMethod, + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikBleService, jBleServiceSubscribeMethod, daddress, dprofile, dcharacteristic, value); - (*androidEnv)->DeleteLocalRef(androidEnv, daddress); - (*androidEnv)->DeleteLocalRef(androidEnv, dprofile); - (*androidEnv)->DeleteLocalRef(androidEnv, dcharacteristic); - (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); - (*env)->ReleaseStringUTFChars(env, jProfile, profileChars); - (*env)->ReleaseStringUTFChars(env, jCharacteristic, characteristicChars); + DETACH_DALVIK(); + // (*env)->ReleaseStringUTFChars(env, jAddress, addressChars); + // (*env)->ReleaseStringUTFChars(env, jProfile, profileChars); + // (*env)->ReleaseStringUTFChars(env, jCharacteristic, characteristicChars); } /////////////////////////// @@ -306,12 +286,12 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_DalvikBleService_scanDetect ATTACH_LOG_FINE("Scan Detection is now in native layer, major = %d\n", major); } const char *uuidChars = (*env)->GetStringUTFChars(env, uuid, NULL); - (*jVMBle)->AttachCurrentThread(jVMBle, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring juuid = (*graalEnv)->NewStringUTF(graalEnv, uuidChars); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalBleClass, jGraalSetDetectionMethod, juuid, major, minor, ris, proxy); - (*graalEnv)->DeleteLocalRef(graalEnv, juuid); - (*env)->ReleaseStringUTFChars(env, uuid, uuidChars); + DETACH_GRAAL(); + // (*env)->ReleaseStringUTFChars(env, uuid, uuidChars); } // BLE DEVICES @@ -324,15 +304,14 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_DalvikBleService_scanDevice ATTACH_LOG_FINE("Scan Device Detection, name = %s, address = %s\n", nameChars, addressChars); } - (*jVMBle)->AttachCurrentThread(jVMBle, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring jname = (*graalEnv)->NewStringUTF(graalEnv, nameChars); jstring jaddress = (*graalEnv)->NewStringUTF(graalEnv, addressChars); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalBleClass, jGraalSetDeviceDetectionMethod, jname, jaddress); - (*graalEnv)->DeleteLocalRef(graalEnv, jname); - (*graalEnv)->DeleteLocalRef(graalEnv, jaddress); - (*env)->ReleaseStringUTFChars(env, name, nameChars); - (*env)->ReleaseStringUTFChars(env, address, addressChars); + DETACH_GRAAL(); + // (*env)->ReleaseStringUTFChars(env, name, nameChars); + // (*env)->ReleaseStringUTFChars(env, address, addressChars); } JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_setState(JNIEnv *env, jobject service, @@ -342,15 +321,13 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_setState(JN if (debugBLE) { ATTACH_LOG_FINE("Device state, name = %s, state = %s\n", nameChars, stateChars); } - - (*jVMBle)->AttachCurrentThread(jVMBle, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring jname = (*graalEnv)->NewStringUTF(graalEnv, nameChars); jstring jstate = (*graalEnv)->NewStringUTF(graalEnv, stateChars); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalBleClass, jGraalSetDeviceStateMethod, jname, jstate); - (*graalEnv)->DeleteLocalRef(graalEnv, jname); - (*graalEnv)->DeleteLocalRef(graalEnv, jstate); - (*env)->ReleaseStringUTFChars(env, name, nameChars); - (*env)->ReleaseStringUTFChars(env, state, stateChars); + DETACH_GRAAL(); + // (*env)->ReleaseStringUTFChars(env, name, nameChars); + // (*env)->ReleaseStringUTFChars(env, state, stateChars); } JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_addProfile(JNIEnv *env, jobject service, @@ -361,18 +338,15 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_addProfile( if (debugBLE) { ATTACH_LOG_FINE("Device type, name = %s, service: uuid = %s, type = %s\n", nameChars, uuidChars, typeChars); } - - (*jVMBle)->AttachCurrentThread(jVMBle, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring jname = (*graalEnv)->NewStringUTF(graalEnv, nameChars); jstring juuid = (*graalEnv)->NewStringUTF(graalEnv, uuidChars); jstring jtype = (*graalEnv)->NewStringUTF(graalEnv, typeChars); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalBleClass, jGraalSetDeviceProfileMethod, jname, juuid, jtype); - (*graalEnv)->DeleteLocalRef(graalEnv, jname); - (*graalEnv)->DeleteLocalRef(graalEnv, juuid); - (*graalEnv)->DeleteLocalRef(graalEnv, jtype); - (*env)->ReleaseStringUTFChars(env, name, nameChars); - (*env)->ReleaseStringUTFChars(env, uuid, uuidChars); - (*env)->ReleaseStringUTFChars(env, type, typeChars); + DETACH_GRAAL(); + // (*env)->ReleaseStringUTFChars(env, name, nameChars); + // (*env)->ReleaseStringUTFChars(env, uuid, uuidChars); + // (*env)->ReleaseStringUTFChars(env, type, typeChars); } JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_addCharacteristic(JNIEnv *env, jobject service, @@ -386,20 +360,17 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_addCharacte nameChars, profileUuidChars, charUuidChars, propertiesChars); } - (*jVMBle)->AttachCurrentThread(jVMBle, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring jname = (*graalEnv)->NewStringUTF(graalEnv, nameChars); jstring jprofileUuid = (*graalEnv)->NewStringUTF(graalEnv, profileUuidChars); jstring jcharUuid = (*graalEnv)->NewStringUTF(graalEnv, charUuidChars); jstring jproperties = (*graalEnv)->NewStringUTF(graalEnv, propertiesChars); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalBleClass, jGraalSetDeviceCharMethod, jname, jprofileUuid, jcharUuid, jproperties); - (*graalEnv)->DeleteLocalRef(graalEnv, jname); - (*graalEnv)->DeleteLocalRef(graalEnv, jprofileUuid); - (*graalEnv)->DeleteLocalRef(graalEnv, jcharUuid); - (*graalEnv)->DeleteLocalRef(graalEnv, jproperties); - (*env)->ReleaseStringUTFChars(env, name, nameChars); - (*env)->ReleaseStringUTFChars(env, profileUuid, profileUuidChars); - (*env)->ReleaseStringUTFChars(env, charUuid, charUuidChars); - (*env)->ReleaseStringUTFChars(env, properties, profileUuidChars); + DETACH_GRAAL(); + // (*env)->ReleaseStringUTFChars(env, name, nameChars); + // (*env)->ReleaseStringUTFChars(env, profileUuid, profileUuidChars); + // (*env)->ReleaseStringUTFChars(env, charUuid, charUuidChars); + // (*env)->ReleaseStringUTFChars(env, properties, profileUuidChars); } JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_addDescriptor(JNIEnv *env, jobject service, @@ -415,7 +386,7 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_addDescript nameChars, profileUuidChars, charUuidChars, descUuidChars); } - (*jVMBle)->AttachCurrentThread(jVMBle, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring jname = (*graalEnv)->NewStringUTF(graalEnv, nameChars); jstring jprofileUuid = (*graalEnv)->NewStringUTF(graalEnv, profileUuidChars); jstring jcharUuid = (*graalEnv)->NewStringUTF(graalEnv, charUuidChars); @@ -424,15 +395,12 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_addDescript (*graalEnv)->SetByteArrayRegion(graalEnv, jvalue, 0, size, valueBytes); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalBleClass, jGraalSetDeviceDescMethod, jname, jprofileUuid, jcharUuid, jdescUuid, jvalue); - (*graalEnv)->DeleteLocalRef(graalEnv, jname); - (*graalEnv)->DeleteLocalRef(graalEnv, jprofileUuid); - (*graalEnv)->DeleteLocalRef(graalEnv, jcharUuid); - (*graalEnv)->DeleteLocalRef(graalEnv, jdescUuid); - (*graalEnv)->ReleaseByteArrayElements(graalEnv, value, valueBytes, JNI_ABORT); - (*env)->ReleaseStringUTFChars(env, name, nameChars); - (*env)->ReleaseStringUTFChars(env, profileUuid, profileUuidChars); - (*env)->ReleaseStringUTFChars(env, charUuid, charUuidChars); - (*env)->ReleaseStringUTFChars(env, descUuid, descUuidChars); + // (*graalEnv)->ReleaseByteArrayElements(graalEnv, value, valueBytes, JNI_ABORT); + DETACH_GRAAL(); + // (*env)->ReleaseStringUTFChars(env, name, nameChars); + // (*env)->ReleaseStringUTFChars(env, profileUuid, profileUuidChars); + // (*env)->ReleaseStringUTFChars(env, charUuid, charUuidChars); + // (*env)->ReleaseStringUTFChars(env, descUuid, descUuidChars); } JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_setValue(JNIEnv *env, jobject service, @@ -443,16 +411,15 @@ JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_BleGattCallback_setValue(JN jbyte *valueBytes = (*env)->GetByteArrayElements(env, value, NULL); int size = (*env)->GetArrayLength(env, value); - (*jVMBle)->AttachCurrentThread(jVMBle, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring jname = (*graalEnv)->NewStringUTF(graalEnv, nameChars); jstring jcharUuid = (*graalEnv)->NewStringUTF(graalEnv, charUuidChars); jbyteArray jvalue = (*graalEnv)->NewByteArray(graalEnv, size); (*graalEnv)->SetByteArrayRegion(graalEnv, jvalue, 0, size, valueBytes); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalBleClass, jGraalSetDeviceValueMethod, jname, jcharUuid, jvalue); - (*graalEnv)->DeleteLocalRef(graalEnv, jname); - (*graalEnv)->DeleteLocalRef(graalEnv, jcharUuid); - (*graalEnv)->ReleaseByteArrayElements(graalEnv, value, valueBytes, JNI_ABORT); - (*env)->ReleaseStringUTFChars(env, name, nameChars); - (*env)->ReleaseStringUTFChars(env, charUuid, charUuidChars); + // (*graalEnv)->ReleaseByteArrayElements(graalEnv, value, valueBytes, JNI_ABORT); + DETACH_GRAAL(); + // (*env)->ReleaseStringUTFChars(env, name, nameChars); + // (*env)->ReleaseStringUTFChars(env, charUuid, charUuidChars); } diff --git a/modules/browser/src/main/native/android/c/Browser.c b/modules/browser/src/main/native/android/c/Browser.c index 2a519ee6..b0456196 100644 --- a/modules/browser/src/main/native/android/c/Browser.c +++ b/modules/browser/src/main/native/android/c/Browser.c @@ -27,25 +27,20 @@ */ #include "Browser.h" -static JNIEnv *graalEnv; -JavaVM *jVMBrowser = NULL; -static JavaVM *myAndroidVM = NULL; static jobject jDalvikBrowserService; static jmethodID jBrowserServiceLaunchMethod; static void initializeDalvikHandles() { - myAndroidVM = substrateGetAndroidVM(); jclass jBrowserServiceClass = substrateGetBrowserServiceClass(); - JNIEnv* androidEnv; - (*myAndroidVM)->AttachCurrentThread(myAndroidVM, (void **)&androidEnv, NULL); - jmethodID jBrowserServiceInitMethod = (*androidEnv)->GetMethodID(androidEnv, jBrowserServiceClass, "", "(Landroid/app/Activity;)V"); - jBrowserServiceLaunchMethod = (*androidEnv)->GetMethodID(androidEnv, jBrowserServiceClass, "launchURL", "(Ljava/lang/String;)Z"); + ATTACH_DALVIK(); + jmethodID jBrowserServiceInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBrowserServiceClass, "", "(Landroid/app/Activity;)V"); + jBrowserServiceLaunchMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jBrowserServiceClass, "launchURL", "(Ljava/lang/String;)Z"); jobject jActivity = substrateGetActivity(); - jobject jtmpobj = (*androidEnv)->NewObject(androidEnv, jBrowserServiceClass, jBrowserServiceInitMethod, jActivity); - jDalvikBrowserService = (*androidEnv)->NewGlobalRef(androidEnv, jtmpobj); - (*myAndroidVM)->DetachCurrentThread(myAndroidVM); + jobject jtmpobj = (*dalvikEnv)->NewObject(dalvikEnv, jBrowserServiceClass, jBrowserServiceInitMethod, jActivity); + jDalvikBrowserService = (*dalvikEnv)->NewGlobalRef(dalvikEnv, jtmpobj); + DETACH_DALVIK(); } ////////////////////////// @@ -56,9 +51,9 @@ static void initializeDalvikHandles() { JNIEXPORT jint JNICALL JNI_OnLoad_Browser(JavaVM *vm, void *reserved) { -fprintf(stderr, "JNI_OnLoad_Browser called\n"); + ATTACH_LOG_INFO("JNI_OnLoad_Browser called\n"); #ifdef JNI_VERSION_1_8 - jVMBrowser = vm; + JNIEnv* graalEnv; if ((*vm)->GetEnv(vm, (void **)&graalEnv, JNI_VERSION_1_8) != JNI_OK) { ATTACH_LOG_WARNING("Error initializing native Browser from OnLoad"); return JNI_FALSE; @@ -73,22 +68,14 @@ fprintf(stderr, "JNI_OnLoad_Browser called\n"); // from Java to Android -static JNIEnv* getSafeAndroidEnv() { - JNIEnv* androidEnv; - if ((*myAndroidVM)->GetEnv(myAndroidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("AndroidEnv called from not-attached thread\n"); - (*myAndroidVM)->AttachCurrentThread(myAndroidVM, (void **)&androidEnv, NULL); - } - return androidEnv; -} - JNIEXPORT jboolean JNICALL Java_com_gluonhq_attach_browser_impl_AndroidBrowserService_launchURL (JNIEnv *env, jclass jClass, jstring jurl) { const char *urlChars = (*env)->GetStringUTFChars(env, jurl, NULL); - JNIEnv* androidEnv = getSafeAndroidEnv(); - jstring durl = (*androidEnv)->NewStringUTF(androidEnv, urlChars); - jboolean result = (*androidEnv)->CallBooleanMethod(androidEnv, jDalvikBrowserService, jBrowserServiceLaunchMethod, durl); - (*env)->ReleaseStringUTFChars(env, jurl, urlChars); + ATTACH_DALVIK(); + jstring durl = (*dalvikEnv)->NewStringUTF(dalvikEnv, urlChars); + jboolean result = (*dalvikEnv)->CallBooleanMethod(dalvikEnv, jDalvikBrowserService, jBrowserServiceLaunchMethod, durl); + DETACH_DALVIK(); + // (*env)->ReleaseStringUTFChars(env, jurl, urlChars); return result; } diff --git a/modules/display/src/main/native/android/c/Display.c b/modules/display/src/main/native/android/c/Display.c index 2be4fb8f..af27e276 100644 --- a/modules/display/src/main/native/android/c/Display.c +++ b/modules/display/src/main/native/android/c/Display.c @@ -27,31 +27,25 @@ */ #include "Display.h" -static JNIEnv *graalEnv; -JavaVM *jVMDisplay = NULL; - -static JavaVM *myAndroidVM = NULL; static jobject jDalvikDisplayService; static jmethodID jDisplayServiceWidthMethod; static jmethodID jDisplayServiceHeightMethod; static jmethodID jDisplayServiceFactorMethod; static jmethodID jDisplayServiceRoundMethod; -static void initializeDalvikHandles() { - myAndroidVM = substrateGetAndroidVM(); +static void initializeDisplayDalvikHandles() { + ATTACH_DALVIK(); jclass jDisplayServiceClass = substrateGetDisplayServiceClass(); - JNIEnv* androidEnv; - (*myAndroidVM)->AttachCurrentThread(myAndroidVM, (void **)&androidEnv, NULL); - jmethodID jDisplayServiceInitMethod = (*androidEnv)->GetMethodID(androidEnv, jDisplayServiceClass, "", "(Landroid/app/Activity;)V"); - jDisplayServiceWidthMethod = (*androidEnv)->GetMethodID(androidEnv, jDisplayServiceClass, "screenWidth", "()D"); - jDisplayServiceHeightMethod = (*androidEnv)->GetMethodID(androidEnv, jDisplayServiceClass, "screenHeight", "()D"); - jDisplayServiceFactorMethod = (*androidEnv)->GetMethodID(androidEnv, jDisplayServiceClass, "isPhoneFactor", "()Z"); - jDisplayServiceRoundMethod = (*androidEnv)->GetMethodID(androidEnv, jDisplayServiceClass, "isScreenRound", "()Z"); + jmethodID jDisplayServiceInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jDisplayServiceClass, "", "(Landroid/app/Activity;)V"); + jDisplayServiceWidthMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jDisplayServiceClass, "screenWidth", "()D"); + jDisplayServiceHeightMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jDisplayServiceClass, "screenHeight", "()D"); + jDisplayServiceFactorMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jDisplayServiceClass, "isPhoneFactor", "()Z"); + jDisplayServiceRoundMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jDisplayServiceClass, "isScreenRound", "()Z"); jobject jActivity = substrateGetActivity(); - jobject jtmpobj = (*androidEnv)->NewObject(androidEnv, jDisplayServiceClass, jDisplayServiceInitMethod, jActivity); - jDalvikDisplayService = (*androidEnv)->NewGlobalRef(androidEnv, jtmpobj); - (*myAndroidVM)->DetachCurrentThread(myAndroidVM); + jobject jtmpobj = (*dalvikEnv)->NewObject(dalvikEnv, jDisplayServiceClass, jDisplayServiceInitMethod, jActivity); + jDalvikDisplayService = (*dalvikEnv)->NewGlobalRef(dalvikEnv, jtmpobj); + DETACH_DALVIK(); } ////////////////////////// @@ -62,15 +56,15 @@ static void initializeDalvikHandles() { JNIEXPORT jint JNICALL JNI_OnLoad_Display(JavaVM *vm, void *reserved) { -fprintf(stderr, "JNI_OnLoad_Display called\n"); + JNIEnv* graalEnv; + ATTACH_LOG_INFO("JNI_OnLoad_Display called\n"); #ifdef JNI_VERSION_1_8 - jVMDisplay = vm; if ((*vm)->GetEnv(vm, (void **)&graalEnv, JNI_VERSION_1_8) != JNI_OK) { ATTACH_LOG_WARNING("Error initializing native Display from OnLoad"); return JNI_FALSE; } ATTACH_LOG_FINE("[Display Service] Initializing native Display from OnLoad"); - initializeDalvikHandles(); + initializeDisplayDalvikHandles(); return JNI_VERSION_1_8; #else #error Error: Java 8+ SDK is required to compile Attach @@ -79,21 +73,12 @@ fprintf(stderr, "JNI_OnLoad_Display called\n"); // from Java to Android -static JNIEnv* getSafeAndroidEnv() { - JNIEnv* androidEnv; - if ((*myAndroidVM)->GetEnv(myAndroidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("AndroidEnv called from not-attached thread\n"); - (*myAndroidVM)->AttachCurrentThread(myAndroidVM, (void **)&androidEnv, NULL); - } - return androidEnv; -} - JNIEXPORT jdoubleArray JNICALL Java_com_gluonhq_attach_display_impl_AndroidDisplayService_screenSize (JNIEnv *env, jclass jClass) { - JNIEnv* androidEnv = getSafeAndroidEnv(); - jdouble w = (*androidEnv)->CallDoubleMethod(androidEnv, jDalvikDisplayService, jDisplayServiceWidthMethod); - jdouble h = (*androidEnv)->CallDoubleMethod(androidEnv, jDalvikDisplayService, jDisplayServiceHeightMethod); + ATTACH_DALVIK(); + jdouble w = (*dalvikEnv)->CallDoubleMethod(dalvikEnv, jDalvikDisplayService, jDisplayServiceWidthMethod); + jdouble h = (*dalvikEnv)->CallDoubleMethod(dalvikEnv, jDalvikDisplayService, jDisplayServiceHeightMethod); jdoubleArray output = (*env)->NewDoubleArray(env, 2); if (output == NULL) @@ -102,19 +87,24 @@ JNIEXPORT jdoubleArray JNICALL Java_com_gluonhq_attach_display_impl_AndroidDispl } jdouble res[] = {w, h}; (*env)->SetDoubleArrayRegion(env, output, 0, 2, res); + DETACH_DALVIK(); return output; } JNIEXPORT jboolean JNICALL Java_com_gluonhq_attach_display_impl_AndroidDisplayService_isPhoneFactor (JNIEnv *env, jclass jClass) { - JNIEnv* androidEnv = getSafeAndroidEnv(); - return (*androidEnv)->CallBooleanMethod(androidEnv, jDalvikDisplayService, jDisplayServiceFactorMethod); + ATTACH_DALVIK(); + jboolean answer = (*dalvikEnv)->CallBooleanMethod(dalvikEnv, jDalvikDisplayService, jDisplayServiceFactorMethod); + DETACH_DALVIK(); + return answer; } JNIEXPORT jboolean JNICALL Java_com_gluonhq_attach_display_impl_AndroidDisplayService_screenRound (JNIEnv *env, jclass jClass) { - JNIEnv* androidEnv = getSafeAndroidEnv(); - return (*androidEnv)->CallBooleanMethod(androidEnv, jDalvikDisplayService, jDisplayServiceRoundMethod); + ATTACH_DALVIK(); + jboolean answer = (*dalvikEnv)->CallBooleanMethod(dalvikEnv, jDalvikDisplayService, jDisplayServiceRoundMethod); + DETACH_DALVIK(); + return answer; } diff --git a/modules/keyboard/src/main/native/android/c/Keyboard.c b/modules/keyboard/src/main/native/android/c/Keyboard.c index 8f1053b7..00a7ad03 100644 --- a/modules/keyboard/src/main/native/android/c/Keyboard.c +++ b/modules/keyboard/src/main/native/android/c/Keyboard.c @@ -27,9 +27,6 @@ */ #include "Keyboard.h" -static JNIEnv *env; -JNIEnv* javaEnvKeyboard = NULL; -static JavaVM *graalVM = NULL; static jclass jAttachKeyboardClass; static jmethodID jAttach_notifyHeightMethod; int debugKeyboard = 0; @@ -40,11 +37,11 @@ JNI_OnLoad_Keyboard(JavaVM *vm, void *reserved) { #ifdef JNI_VERSION_1_8 //min. returned JNI_VERSION required by JDK8 for builtin libraries + JNIEnv* env; if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) { ATTACH_LOG_WARNING("Error initializing native Keyboard from OnLoad"); return JNI_FALSE; } - graalVM = getGraalVM(); ATTACH_LOG_FINE("Initializing native Keyboard from OnLoad"); jAttachKeyboardClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "com/gluonhq/attach/keyboard/impl/AndroidKeyboardService")); jAttach_notifyHeightMethod = (*env)->GetStaticMethodID(env, jAttachKeyboardClass, "notifyVisibleHeight", "(F)V"); @@ -67,18 +64,16 @@ void initKeyboard() KeyboardInited = 1; ATTACH_LOG_FINE("Init AndroidKeyboardService"); - JavaVM* androidVM = substrateGetAndroidVM(); jclass activityClass = substrateGetActivityClass(); jobject jActivity = substrateGetActivity(); jclass jKeyboardServiceClass = substrateGetKeyboardServiceClass(); - JNIEnv* androidEnv; - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - jmethodID jKeyboardServiceInitMethod = (*androidEnv)->GetMethodID(androidEnv, jKeyboardServiceClass, "", "(Landroid/app/Activity;)V"); - jobject keyboardservice = (*androidEnv)->NewObject(androidEnv, jKeyboardServiceClass, jKeyboardServiceInitMethod, jActivity); - (*androidVM)->DetachCurrentThread(androidVM); + ATTACH_DALVIK(); + jmethodID jKeyboardServiceInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jKeyboardServiceClass, "", "(Landroid/app/Activity;)V"); + jobject keyboardservice = (*dalvikEnv)->NewObject(dalvikEnv, jKeyboardServiceClass, jKeyboardServiceInitMethod, jActivity); + density = android_getDensity(dalvikEnv); + DETACH_DALVIK(); - density = android_getDensity(env); if (density == 0.0f) { density = 1.0f; } @@ -91,35 +86,11 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_keyboard_impl_AndroidKeyboardServ debugKeyboard = 1; } -void initializeKeyboardFromNative() { - if (javaEnvKeyboard != NULL) { - return; // already have a JNIEnv - } - if (graalVM == NULL) { - ATTACH_LOG_FINE("initialize Keyboard from native can't be done without JVM"); - return; // can't initialize from native before we have a graalVM - } - if (debugKeyboard == 1) { - ATTACH_LOG_FINE("Initializing native Keyboard from Android/native code"); - } - jint error = (*graalVM)->AttachCurrentThread(graalVM, (void **)&javaEnvKeyboard, NULL); - if (error != 0) { - ATTACH_LOG_FINE("initializeKeyboardFromNative failed with error %d", error); - } -} - JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_KeyboardService_nativeDispatchKeyboardHeight(JNIEnv *env, jobject activity, jfloat jheight) { - if (debugKeyboard == 1) { - ATTACH_LOG_FINE("Dispatching keyboard height from native Dalvik layer: %.3f", jheight / density); - } - initializeKeyboardFromNative(); - if (javaEnvKeyboard == NULL) { - ATTACH_LOG_FINE("javaEnvKeyboard still null, not ready to process keyboard events"); - return; - } - (*javaEnvKeyboard)->CallStaticVoidMethod(javaEnvKeyboard, jAttachKeyboardClass, jAttach_notifyHeightMethod, jheight / density); - if (debugKeyboard == 1) { - ATTACH_LOG_FINE("called Attach method from native Keyboard done"); - } + ATTACH_LOG_FINE("Dispatching keyboard height from native Dalvik layer: %.3f", jheight / density); + ATTACH_GRAAL(); + (*graalEnv)->CallStaticVoidMethod(graalEnv, jAttachKeyboardClass, jAttach_notifyHeightMethod, jheight / density); + DETACH_GRAAL(); + ATTACH_LOG_FINE("called Attach method from native Keyboard done"); } diff --git a/modules/lifecycle/src/main/native/android/c/Lifecycle.c b/modules/lifecycle/src/main/native/android/c/Lifecycle.c index 13587e38..702cfda5 100644 --- a/modules/lifecycle/src/main/native/android/c/Lifecycle.c +++ b/modules/lifecycle/src/main/native/android/c/Lifecycle.c @@ -27,9 +27,6 @@ */ #include "Lifecycle.h" -static JavaVM* graalVM; -static JNIEnv *graalEnv; - // Graal handles static jclass jGraalLifecycleClass; static jmethodID jGraalSetLifecycleEventMethod; @@ -39,25 +36,22 @@ static void initializeGraalHandles(JNIEnv* env) { jGraalSetLifecycleEventMethod = (*env)->GetStaticMethodID(env, jGraalLifecycleClass, "setEvent", "(Ljava/lang/String;)V"); } -static void initializeDalvikHandles() { - androidVM = substrateGetAndroidVM(); +static void initializeUtilDalvikHandles() { jclass activityClass = substrateGetActivityClass(); jobject jActivity = substrateGetActivity(); jclass jLifecycleServiceClass = substrateGetLifecycleServiceClass(); - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_FINE("initializeDalvikHandles, thread is not linked to JNIEnv, doing that now.\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } - jmethodID jLifecycleServiceInitMethod = (*androidEnv)->GetMethodID(androidEnv, jLifecycleServiceClass, "", "()V"); - jthrowable t = (*androidEnv)->ExceptionOccurred(androidEnv); + ATTACH_DALVIK(); + jmethodID jLifecycleServiceInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jLifecycleServiceClass, "", "()V"); + jthrowable t = (*dalvikEnv)->ExceptionOccurred(dalvikEnv); if (t) { ATTACH_LOG_INFO("EXCEPTION occurred when dealing with dalvik handles\n"); - (*androidEnv)->ExceptionClear(androidEnv); + (*dalvikEnv)->ExceptionClear(dalvikEnv); } - jobject jObj = (*androidEnv)->NewObject(androidEnv, jLifecycleServiceClass, jLifecycleServiceInitMethod); - jobject jDalvikLifecycleService = (jobject)(*androidEnv)->NewGlobalRef(androidEnv, jObj); + jobject jObj = (*dalvikEnv)->NewObject(dalvikEnv, jLifecycleServiceClass, jLifecycleServiceInitMethod); + jobject jDalvikLifecycleService = (jobject)(*dalvikEnv)->NewGlobalRef(dalvikEnv, jObj); + DETACH_DALVIK(); } ////////////////////////// @@ -68,14 +62,14 @@ JNIEXPORT jint JNICALL JNI_OnLoad_Lifecycle(JavaVM *vm, void *reserved) { #ifdef JNI_VERSION_1_8 - graalVM = vm; + JNIEnv* graalEnv; if ((*vm)->GetEnv(vm, (void **)&graalEnv, JNI_VERSION_1_8) != JNI_OK) { ATTACH_LOG_WARNING("Error initializing native Lifecycle from OnLoad"); return JNI_FALSE; } ATTACH_LOG_FINE("Initializing native Lifecycle from OnLoad"); initializeGraalHandles(graalEnv); - initializeDalvikHandles(); + initializeUtilDalvikHandles(); ATTACH_LOG_FINE("Initializing native Lifecycle from OnLoad Done"); return JNI_VERSION_1_8; #else @@ -91,9 +85,10 @@ JNI_OnLoad_Lifecycle(JavaVM *vm, void *reserved) JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_DalvikLifecycleService_setLifecycleEventNative(JNIEnv *env, jobject service, jstring jevent) { const char *chars = (*env)->GetStringUTFChars(env, jevent, NULL); ATTACH_LOG_FINE("Native layer got new event: %s\n", chars); - (*graalVM)->AttachCurrentThread(graalVM, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); jstring jchars = (*graalEnv)->NewStringUTF(graalEnv, chars); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalLifecycleClass, jGraalSetLifecycleEventMethod, jchars); - (*env)->ReleaseStringUTFChars(env, jevent, chars); (*graalEnv)->DeleteLocalRef(graalEnv, jchars); -} \ No newline at end of file + DETACH_GRAAL(); + (*env)->ReleaseStringUTFChars(env, jevent, chars); +} diff --git a/modules/position/src/main/native/android/c/Position.c b/modules/position/src/main/native/android/c/Position.c index 4a934410..b1e6ece2 100644 --- a/modules/position/src/main/native/android/c/Position.c +++ b/modules/position/src/main/native/android/c/Position.c @@ -27,9 +27,6 @@ */ #include "position.h" -static JavaVM* graalVM; -static JNIEnv *graalEnv; - // Graal handles static jclass jGraalPositionClass; jmethodID jGraalSetLocationMethod; @@ -46,27 +43,23 @@ static void initializeGraalHandles(JNIEnv* env) { } static void initializeDalvikHandles() { - androidVM = substrateGetAndroidVM(); jclass activityClass = substrateGetActivityClass(); jobject jActivity = substrateGetActivity(); jclass jPositionServiceClass = substrateGetPositionServiceClass(); - - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_FINE("initializeDalvikHandles, thread is not linked to JNIEnv, doing that now.\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } - jmethodID jPositionServiceInitMethod = (*androidEnv)->GetMethodID(androidEnv, jPositionServiceClass, "", "(Landroid/app/Activity;)V"); - jDalvikPositionServiceEnableDebug = (*androidEnv)->GetMethodID(androidEnv, jPositionServiceClass, "enableDebug", "()V"); - jDalvikPositionServiceStartMethod = (*androidEnv)->GetMethodID(androidEnv, jPositionServiceClass, "start", "(JFZ)V"); - jDalvikPositionServiceStopMethod = (*androidEnv)->GetMethodID(androidEnv, jPositionServiceClass, "stop", "()V"); - jthrowable t = (*androidEnv)->ExceptionOccurred(androidEnv); + ATTACH_DALVIK(); + jmethodID jPositionServiceInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jPositionServiceClass, "", "(Landroid/app/Activity;)V"); + jDalvikPositionServiceEnableDebug = (*dalvikEnv)->GetMethodID(dalvikEnv, jPositionServiceClass, "enableDebug", "()V"); + jDalvikPositionServiceStartMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jPositionServiceClass, "start", "(JFZ)V"); + jDalvikPositionServiceStopMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jPositionServiceClass, "stop", "()V"); + jthrowable t = (*dalvikEnv)->ExceptionOccurred(dalvikEnv); if (t) { ATTACH_LOG_INFO("EXCEPTION occured when dealing with dalvik handles\n"); - (*androidEnv)->ExceptionClear(androidEnv); + (*dalvikEnv)->ExceptionClear(dalvikEnv); } - jobject jObj = (*androidEnv)->NewObject(androidEnv, jPositionServiceClass, jPositionServiceInitMethod, jActivity); - jDalvikPositionService = (jobject)(*androidEnv)->NewGlobalRef(androidEnv, jObj); + jobject jObj = (*dalvikEnv)->NewObject(dalvikEnv, jPositionServiceClass, jPositionServiceInitMethod, jActivity); + jDalvikPositionService = (jobject)(*dalvikEnv)->NewGlobalRef(dalvikEnv, jObj); + DETACH_DALVIK(); } /////////////////////////// @@ -74,33 +67,21 @@ static void initializeDalvikHandles() { /////////////////////////// void enableDalvikDebug() { - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("enableDalvikDebug called from not-attached thread\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } else { - ATTACH_LOG_FINE("enableDalvikDebug called from attached thread %p\n", androidEnv); - } - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikPositionService, jDalvikPositionServiceEnableDebug); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikPositionService, jDalvikPositionServiceEnableDebug); + DETACH_DALVIK(); } void startDalvikObserving(jlong jInterval, jfloat jDistance, jboolean jBackground) { - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("startDalvikObserving called from not-attached thread\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } else { - ATTACH_LOG_FINE("startDalvikObserving called from attached thread %p\n", androidEnv); - } - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikPositionService, jDalvikPositionServiceStartMethod, jInterval, jDistance, jBackground); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikPositionService, jDalvikPositionServiceStartMethod, jInterval, jDistance, jBackground); + DETACH_DALVIK(); } void stopDalvikObserving() { - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("stopDalvikObserving called from not-attached thread\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } else { - ATTACH_LOG_WARNING("stopDalvikObserving called from attached thread %p\n", androidEnv); - } - (*androidEnv)->CallVoidMethod(androidEnv, jDalvikPositionService, jDalvikPositionServiceStopMethod); + ATTACH_DALVIK(); + (*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikPositionService, jDalvikPositionServiceStopMethod); + DETACH_DALVIK(); } ////////////////////////// @@ -111,7 +92,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad_Position(JavaVM *vm, void *reserved) { #ifdef JNI_VERSION_1_8 - graalVM = vm; + JNIEnv* graalEnv; if ((*vm)->GetEnv(vm, (void **)&graalEnv, JNI_VERSION_1_8) != JNI_OK) { ATTACH_LOG_WARNING("Error initializing native position from OnLoad"); return JNI_FALSE; @@ -151,7 +132,8 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_position_impl_AndroidPositionServ // the JNIEnv passed here is the Dalvik JNIEnv, do not use it to call into GraalVM! JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_DalvikPositionService_updatePositionNative(JNIEnv *env, jobject service, jdouble jlat, jdouble jlon, jdouble jalt) { ATTACH_LOG_FINE("Native layer got new position: %lf, %lf, %lf\n", jlat, jlon, jalt); - (*graalVM)->AttachCurrentThread(graalVM, (void **)&graalEnv, NULL); + ATTACH_GRAAL(); (*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalPositionClass, jGraalSetLocationMethod, jlat, jlon, jalt); + DETACH_GRAAL(); } diff --git a/modules/util/src/main/native/android/c/Util.c b/modules/util/src/main/native/android/c/Util.c index d13cf158..94c125a7 100644 --- a/modules/util/src/main/native/android/c/Util.c +++ b/modules/util/src/main/native/android/c/Util.c @@ -27,8 +27,7 @@ */ #include "Util.h" -static JavaVM* graalVM; -static JNIEnv *graalEnv; +JavaVM* graalVM; // Dalvik handles static jclass jUtilClass; @@ -37,27 +36,28 @@ static jmethodID jUtilOnActivityResultMethod; static jmethodID jUtilOnLifecycleEventMethod; static jmethodID jUtilRequestPermissionsMethod; -static void initializeDalvikHandles() { +static void initializeUtilDalvikHandles() { ATTACH_LOG_FINE("Init Util"); - androidVM = substrateGetAndroidVM(); jUtilClass = substrateGetUtilClass(); + ATTACH_LOG_FINE("Init Util, class at %p\n",jUtilClass); jPermissionActivityClass = substrateGetPermissionActivityClass(); - - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_FINE("initializeDalvikHandles, thread is not linked to JNIEnv, doing that now.\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } - jmethodID jUtilInitMethod = (*androidEnv)->GetMethodID(androidEnv, jUtilClass, "", "()V"); - jUtilOnActivityResultMethod = (*androidEnv)->GetStaticMethodID(androidEnv, jUtilClass, "onActivityResult", "(IILandroid/content/Intent;)V"); - jUtilOnLifecycleEventMethod = (*androidEnv)->GetStaticMethodID(androidEnv, jUtilClass, "lifecycleEvent", "(Ljava/lang/String;)V"); - jUtilRequestPermissionsMethod = (*androidEnv)->GetStaticMethodID(androidEnv, jPermissionActivityClass, "verifyPermissions", "(Landroid/app/Activity;[Ljava/lang/String;)Z"); - jthrowable t = (*androidEnv)->ExceptionOccurred(androidEnv); + ATTACH_DALVIK(); + jmethodID jUtilInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jUtilClass, "", "()V"); + ATTACH_LOG_FINE("Init Util, juim = %p\n", jUtilInitMethod); + jUtilOnActivityResultMethod = (*dalvikEnv)->GetStaticMethodID(dalvikEnv, jUtilClass, "onActivityResult", "(IILandroid/content/Intent;)V"); + ATTACH_LOG_FINE("Init Util, juim = %p\n", jUtilOnActivityResultMethod); + jUtilOnLifecycleEventMethod = (*dalvikEnv)->GetStaticMethodID(dalvikEnv, jUtilClass, "lifecycleEvent", "(Ljava/lang/String;)V"); + ATTACH_LOG_FINE("Init Util, juim = %p\n", jUtilOnLifecycleEventMethod); + jUtilRequestPermissionsMethod = (*dalvikEnv)->GetStaticMethodID(dalvikEnv, jPermissionActivityClass, "verifyPermissions", "(Landroid/app/Activity;[Ljava/lang/String;)Z"); + ATTACH_LOG_FINE("Init Util, juim = %p\n", jUtilRequestPermissionsMethod); + jthrowable t = (*dalvikEnv)->ExceptionOccurred(dalvikEnv); if (t) { ATTACH_LOG_INFO("EXCEPTION occurred when dealing with dalvik handles\n"); - (*androidEnv)->ExceptionClear(androidEnv); + (*dalvikEnv)->ExceptionClear(dalvikEnv); } - jobject util = (*androidEnv)->NewObject(androidEnv, jUtilClass, jUtilInitMethod); + jobject util = (*dalvikEnv)->NewObject(dalvikEnv, jUtilClass, jUtilInitMethod); + DETACH_DALVIK(); ATTACH_LOG_FINE("Dalvik Util init was called"); } @@ -66,13 +66,14 @@ JNI_OnLoad_Util(JavaVM *vm, void *reserved) { #ifdef JNI_VERSION_1_8 graalVM = vm; + JNIEnv* graalEnv; //min. returned JNI_VERSION required by JDK8 for builtin libraries if ((*vm)->GetEnv(vm, (void **)&graalEnv, JNI_VERSION_1_8) != JNI_OK) { ATTACH_LOG_WARNING("Error initializing native Util from OnLoad"); return JNI_FALSE; } ATTACH_LOG_FINE("Initializing native Util from OnLoad"); - initializeDalvikHandles(); + initializeUtilDalvikHandles(); return JNI_VERSION_1_8; #else #error Error: Java 8+ SDK is required to compile Attach @@ -83,40 +84,35 @@ JavaVM* getGraalVM() { return graalVM; } -/////////////////////////////////////////// -// native (Substrate) to native (Attach) // -/////////////////////////////////////////// +////////////////////////////////// +// native (Substrate) to Dalvik // +////////////////////////////////// void attach_setActivityResult(jint requestCode, jint resultCode, jobject intent) { - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("attach_setActivityResult called from not-attached thread\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } else { - ATTACH_LOG_WARNING("attach_setActivityResult called from attached thread %p\n", androidEnv); - } ATTACH_LOG_FINE("call Attach::nativeDispatchActivityResult method from native: %d %d", requestCode, resultCode); - (*androidEnv)->CallStaticVoidMethod(androidEnv, jUtilClass, jUtilOnActivityResultMethod, requestCode, resultCode, intent); + ATTACH_DALVIK(); + (*dalvikEnv)->CallStaticVoidMethod(dalvikEnv, jUtilClass, jUtilOnActivityResultMethod, requestCode, resultCode, intent); + DETACH_DALVIK(); ATTACH_LOG_FINE("call Attach::nativeDispatchActivityResult method from native done"); } void attach_setLifecycleEvent(const char* event) { - if ((*androidVM)->GetEnv(androidVM, (void **)&androidEnv, JNI_VERSION_1_6) != JNI_OK) { - ATTACH_LOG_WARNING("attach_setLifecycleEvent called from not-attached thread\n"); - (*androidVM)->AttachCurrentThread(androidVM, (void **)&androidEnv, NULL); - } else { - ATTACH_LOG_WARNING("attach_setLifecycleEvent called from attached thread %p\n", androidEnv); - } - ATTACH_LOG_FINE("call Attach method from native Lifecycle: %s", event); - jstring jchars = (*androidEnv)->NewStringUTF(androidEnv, event); - (*androidEnv)->CallStaticVoidMethod(androidEnv, jUtilClass, jUtilOnLifecycleEventMethod, jchars); - (*androidEnv)->DeleteLocalRef(androidEnv, jchars); + ATTACH_LOG_FINE("Call Attach method from native Lifecycle: %s", event); + ATTACH_DALVIK(); + jstring jchars = (*dalvikEnv)->NewStringUTF(dalvikEnv, event); + ATTACH_LOG_FINE("Call2 Attach method from native Lifecycle: %s, class at %p and method at %p and jc at %p\n", event, jUtilClass, jUtilOnLifecycleEventMethod, jchars); + (*dalvikEnv)->CallStaticVoidMethod(dalvikEnv, jUtilClass, jUtilOnLifecycleEventMethod, jchars); + ATTACH_LOG_FINE("Call3 Attach method from native Lifecycle: %s", event); + (*dalvikEnv)->DeleteLocalRef(dalvikEnv, jchars); + ATTACH_LOG_FINE("Call4 Attach method from native Lifecycle: %s", event); + DETACH_DALVIK(); ATTACH_LOG_FINE("called Attach method from native Lifecycle done"); } -/////////////////////////////////////// -// From native to Dalvik (Substrate) // -/////////////////////////////////////// +//////////////////////////// +// From Dalvik to Dalvik // +//////////////////////////// JNIEXPORT jboolean JNICALL Java_com_gluonhq_helloandroid_Util_nativeVerifyPermissions(JNIEnv *env, jobject activity, jobjectArray jpermissionsArray) { @@ -124,4 +120,4 @@ JNIEXPORT jboolean JNICALL Java_com_gluonhq_helloandroid_Util_nativeVerifyPermis jboolean jresult = (*env)->CallStaticBooleanMethod(env, jPermissionActivityClass, jUtilRequestPermissionsMethod, substrateGetActivity(), jpermissionsArray); ATTACH_LOG_FINE("Verify Permissions from native Attach::Util done"); return jresult; -} \ No newline at end of file +}