void JNIExecutor::frameworkMessage(ExecutorDriver* driver, const string& data) { jvm->AttachCurrentThread((void**) &env, NULL); jclass clazz = env->GetObjectClass(jdriver); jfieldID exec = env->GetFieldID(clazz, "exec", "Lorg/apache/mesos/Executor;"); jobject jexec = env->GetObjectField(jdriver, exec); clazz = env->GetObjectClass(jexec); // exec.frameworkMessage(driver, data); jmethodID frameworkMessage = env->GetMethodID(clazz, "frameworkMessage", "(Lorg/apache/mesos/ExecutorDriver;" "[B)V"); // byte[] data = ..; jbyteArray jdata = env->NewByteArray(data.size()); env->SetByteArrayRegion(jdata, 0, data.size(), (jbyte*) data.data()); env->ExceptionClear(); env->CallVoidMethod(jexec, frameworkMessage, jdriver, jdata); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); jvm->DetachCurrentThread(); driver->stop(); this->error(driver, -1, "Java exception caught"); return; } jvm->DetachCurrentThread(); }
void Thread::DetachFromJVM() { if (true == IsMainThread()) return; DAVA::CorePlatformAndroid *core = (DAVA::CorePlatformAndroid *)DAVA::Core::Instance(); DAVA::AndroidSystemDelegate* delegate = core->GetAndroidSystemDelegate(); JavaVM *vm = delegate->GetVM(); JNIEnv *env; if (JNI_OK == vm->GetEnv((void**)&env, JNI_VERSION_1_6)) { if (0 != vm->DetachCurrentThread()) Logger::Error("runtime_error(Could not detach current thread from JNI)"); } }
void callVoidJavaMethod(const char* javaMethodName, string param){ ANativeActivity* activity = NULL; JavaVM* jvm = NULL; JNIEnv* env = NULL; if(prepareForCallJavaMethod(&activity, &jvm, &env)){ jclass clazz = env->GetObjectClass(activity->clazz); jmethodID methodID = env->GetMethodID(clazz, javaMethodName, "(Ljava/lang/String;)V"); jstring jStringParam = env->NewStringUTF( param.c_str() ); if( !jStringParam ) { __android_log_print(ANDROID_LOG_ERROR, "MainNativeActivity#callJavaMethod", "Fallo al pasar string de ndk a java"); return; } env->CallVoidMethod(activity->clazz, methodID, jStringParam); env->DeleteLocalRef( jStringParam ); jvm->DetachCurrentThread(); } }
~msandroid_sound_write_data() { ms_bufferizer_flush(bufferizer); ms_bufferizer_destroy(bufferizer); ms_cond_destroy(&cond); if (audio_track_class!=0) { //JNIEnv *env = ms_get_jni_env(); JNIEnv *env = NULL; JavaVM *jvm = ms_get_jvm(); if (jvm->AttachCurrentThread(&env, NULL)!=0) { ms_fatal("AttachCurrentThread() failed !"); } env->DeleteGlobalRef(audio_track_class); jvm->DetachCurrentThread(); } }
void GoogleStoreFront::makePayment(const char * productID, int quantity, const char * usernameHash) { android_app* app = __state; JNIEnv* env = app->activity->env; JavaVM* vm = app->activity->vm; vm->AttachCurrentThread(&env, NULL); jstring paramString = env->NewStringUTF(productID); while (quantity-- > 0) env->CallVoidMethod(app->activity->clazz, __midPurchaseItem, paramString); vm->DetachCurrentThread(); getListener()->paymentTransactionInProcessEvent(productID, quantity); }
/** * Used for user supplied input/output functions. See initDxClass(); */ int dx_uio_read (int fd, char* ptr, unsigned cnt) { JavaVM *vm = jvr_getVM(); JNIEnv *e; int detach = 0; if (vm->GetEnv((void **)&e, JNI_VERSION_1_2) != JNI_OK) { vm->AttachCurrentThread((void**)&e,&attachArgs); detach = 1; } if (e->ExceptionOccurred()) { e->ExceptionDescribe(); e->ExceptionClear(); return -1; } jcharArray charArray = (jcharArray) e->CallStaticObjectMethod(dx_class, dx_uio_read_method, (jint) fd, (jint) cnt); if (e->ExceptionOccurred()) { e->ExceptionDescribe(); e->ExceptionClear(); if (detach) { vm->DetachCurrentThread(); } return -1; } if (charArray == NULL) { // EOF if (detach) { vm->DetachCurrentThread(); } return -1; } int buflen = e->GetArrayLength(charArray); if (e->ExceptionOccurred()) { e->ExceptionDescribe(); e->ExceptionClear(); if (detach) { vm->DetachCurrentThread(); } return -1; } if (buflen == 0) { // EOF aka no data if (detach) { vm->DetachCurrentThread(); } return -1; } jchar* bufp = (jchar*) e->GetCharArrayElements(charArray,0); if (e->ExceptionOccurred()) { e->ExceptionDescribe(); e->ExceptionClear(); if (detach) { vm->DetachCurrentThread(); } return -1; } memcpy(ptr,bufp,buflen); e->ReleaseCharArrayElements(charArray, bufp, JNI_ABORT); e->DeleteLocalRef(charArray); if (detach) { vm->DetachCurrentThread(); } return buflen; }
static void report_exception(JNIEnv* env, jthrowable excep, const char* msg) { env->ExceptionClear(); jstring tagstr = env->NewStringUTF(LOG_TAG); jstring msgstr = env->NewStringUTF(msg); if ((tagstr == NULL) || (msgstr == NULL)) { env->ExceptionClear(); /* assume exception (OOM?) was thrown */ ALOGE("Unable to call Log.e()\n"); ALOGE("%s", msg); goto bail; } env->CallStaticIntMethod( gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep); if (env->ExceptionCheck()) { /* attempting to log the failure has failed */ ALOGW("Failed trying to log exception, msg='%s'\n", msg); env->ExceptionClear(); } if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) { /* * It's an Error: Reraise the exception, detach this thread, and * wait for the fireworks. Die even more blatantly after a minute * if the gentler attempt doesn't do the trick. * * The GetJavaVM function isn't on the "approved" list of JNI calls * that can be made while an exception is pending, so we want to * get the VM ptr, throw the exception, and then detach the thread. */ JavaVM* vm = jnienv_to_javavm(env); env->Throw(excep); vm->DetachCurrentThread(); sleep(60); ALOGE("Forcefully exiting"); exit(1); *((int *) 1) = 1; } bail: /* discard local refs created for us by VM */ env->DeleteLocalRef(tagstr); env->DeleteLocalRef(msgstr); }
// Called by the HAL to notify us of fingerprint events static void hal_notify_callback(fingerprint_msg_t msg) { uint32_t arg1 = 0; uint32_t arg2 = 0; uint32_t arg3 = 0; // TODO switch (msg.type) { case FINGERPRINT_ERROR: arg1 = msg.data.error; break; case FINGERPRINT_ACQUIRED: arg1 = msg.data.acquired.acquired_info; break; case FINGERPRINT_PROCESSED: arg1 = msg.data.processed.id; break; case FINGERPRINT_TEMPLATE_ENROLLING: arg1 = msg.data.enroll.id; arg2 = msg.data.enroll.samples_remaining; arg3 = msg.data.enroll.data_collected_bmp; break; case FINGERPRINT_TEMPLATE_REMOVED: arg1 = msg.data.removed.id; break; default: ALOGE("fingerprint: invalid msg: %d", msg.type); return; } //ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2); // TODO: fix gross hack to attach JNI to calling thread JNIEnv* env = AndroidRuntime::getJNIEnv(); JavaVM* vm = NULL; if (env == NULL) { JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; vm = AndroidRuntime::getJavaVM(); int result = vm->AttachCurrentThread(&env, (void*) &args); if (result != JNI_OK) { ALOGE("Can't call JNI method: attach failed: %#x", result); return; } } env->CallVoidMethod(gFingerprintServiceClassInfo.callbackObject, gFingerprintServiceClassInfo.notify, msg.type, arg1, arg2); if (vm != NULL) { vm->DetachCurrentThread(); } }
int32_t SpiReadAutoReceiveBufferCallbackStore::performCallback( const char* name, uint32_t* buffer, int32_t numToRead) { JNIEnv* env; JavaVM* vm = sim::GetJVM(); bool didAttachThread = false; int tryGetEnv = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); if (tryGetEnv == JNI_EDETACHED) { // Thread not attached didAttachThread = true; if (vm->AttachCurrentThread(reinterpret_cast<void**>(&env), nullptr) != 0) { // Failed to attach, log and return wpi::outs() << "Failed to attach\n"; wpi::outs().flush(); return -1; } } else if (tryGetEnv == JNI_EVERSION) { wpi::outs() << "Invalid JVM Version requested\n"; wpi::outs().flush(); } auto toCallbackArr = MakeJIntArray( env, wpi::ArrayRef<uint32_t>{buffer, static_cast<size_t>(numToRead)}); jint ret = env->CallIntMethod(m_call, sim::GetBufferCallback(), MakeJString(env, name), toCallbackArr, (jint)numToRead); jint* fromCallbackArr = reinterpret_cast<jint*>( env->GetPrimitiveArrayCritical(toCallbackArr, nullptr)); for (int i = 0; i < ret; i++) { buffer[i] = fromCallbackArr[i]; } env->ReleasePrimitiveArrayCritical(toCallbackArr, fromCallbackArr, JNI_ABORT); if (env->ExceptionCheck()) { env->ExceptionDescribe(); } if (didAttachThread) { vm->DetachCurrentThread(); } return ret; }
static void callback_thread_event(bt_cb_thread_evt event) { JavaVM* vm = AndroidRuntime::getJavaVM(); if (event == ASSOCIATE_JVM) { JavaVMAttachArgs args; char name[] = "BT Service Callback Thread"; args.version = JNI_VERSION_1_6; args.name = name; args.group = NULL; vm->AttachCurrentThread(&callbackEnv, &args); ALOGV("Callback thread attached: %p", callbackEnv); } else if (event == DISASSOCIATE_JVM) { if (!checkCallbackThread()) { ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); return; } vm->DetachCurrentThread(); } }
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); extern "C" void SuspendSleep( int bStopSleep ) { static jobject WindowManager_LayoutParams_FLAG_KEEP_SCREEN_ON; // Attaches the current thread to the JVM. jint lResult; jint lFlags = 0; JavaVM* lJavaVM = engine.app->activity->vm; JNIEnv* lJNIEnv = engine.app->activity->env; JavaVMAttachArgs lJavaVMAttachArgs; lJavaVMAttachArgs.version = JNI_VERSION_1_6; lJavaVMAttachArgs.name = "NativeThread"; lJavaVMAttachArgs.group = NULL; lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); if (lResult == JNI_ERR) { return; } // Retrieves NativeActivity. jobject lNativeActivity = engine.app->activity->clazz; jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity); if( bStopSleep ) { jmethodID MethodSetFlags = lJNIEnv->GetMethodID( ClassNativeActivity, "setSuspendSleep", "()V"); LOGI( "suspend Sleep" ); if( MethodSetFlags ) lJNIEnv->CallVoidMethod( lNativeActivity, MethodSetFlags ); } else { jmethodID MethodSetFlags = lJNIEnv->GetMethodID( ClassNativeActivity, "setAllowSleep", "()V"); if( MethodSetFlags ) lJNIEnv->CallVoidMethod( lNativeActivity, MethodSetFlags ); } // Finished with the JVM. lJavaVM->DetachCurrentThread(); }
string callStringJavaMethod(const char* javaMethodName, string param){ ANativeActivity* activity = NULL; JavaVM* jvm = NULL; JNIEnv* env = NULL; string result; if(prepareForCallJavaMethod(&activity, &jvm, &env)){ jclass clazz = env->GetObjectClass(activity->clazz); jmethodID methodID = env->GetMethodID(clazz, javaMethodName, "(Ljava/lang/String;)Ljava/lang/String;"); jstring jStringParam = env->NewStringUTF( param.c_str() ); if( !jStringParam ) { __android_log_print(ANDROID_LOG_ERROR, "NativeActivityConnector#callStringJavaMethod", "Fallo al pasar string de ndk a java"); return result; } jstring jresult = (jstring) env->CallObjectMethod(activity->clazz, methodID, jStringParam); result = jstringToString(jresult, env); env->DeleteLocalRef( jStringParam ); jvm->DetachCurrentThread(); } return result; }
/** * Used for user supplied input/output functions. See initDxClass(); */ long dx_uio_seek (int fd, long offset, int whence) { JavaVM *vm = jvr_getVM(); JNIEnv *e; int detach = 0; if (vm->GetEnv((void **)&e, JNI_VERSION_1_2) != JNI_OK) { vm->AttachCurrentThread((void**)&e,&attachArgs); detach = 1; } if (e->ExceptionOccurred()) { e->ExceptionDescribe(); e->ExceptionClear(); return -1; } long ret = e->CallStaticLongMethod(dx_class,dx_uio_seek_method,(jint) fd,(jlong) offset,(jint) whence); if (detach) { vm->DetachCurrentThread(); } return ret; }
int GetUnicodeChar(struct android_app* app, int eventType, int keyCode, int metaState) { JavaVM* javaVM = app->activity->vm; JNIEnv* jniEnv = app->activity->env; JavaVMAttachArgs attachArgs; attachArgs.version = JNI_VERSION_1_6; attachArgs.name = "NativeThread"; attachArgs.group = NULL; jint result = javaVM->AttachCurrentThread(&jniEnv, &attachArgs); if(result == JNI_ERR) { return 0; } jclass class_key_event = jniEnv->FindClass("android/view/KeyEvent"); int unicodeKey; if(metaState == 0) { jmethodID method_get_unicode_char = jniEnv->GetMethodID(class_key_event, "getUnicodeChar", "()I"); jmethodID eventConstructor = jniEnv->GetMethodID(class_key_event, "<init>", "(II)V"); jobject eventObj = jniEnv->NewObject(class_key_event, eventConstructor, eventType, keyCode); unicodeKey = jniEnv->CallIntMethod(eventObj, method_get_unicode_char); } else { jmethodID method_get_unicode_char = jniEnv->GetMethodID(class_key_event, "getUnicodeChar", "(I)I"); jmethodID eventConstructor = jniEnv->GetMethodID(class_key_event, "<init>", "(II)V"); jobject eventObj = jniEnv->NewObject(class_key_event, eventConstructor, eventType, keyCode); unicodeKey = jniEnv->CallIntMethod(eventObj, method_get_unicode_char, metaState); } javaVM->DetachCurrentThread(); LOGI("Unicode key is: %d", unicodeKey); return unicodeKey; }
/**************************************************************************** Desc: ****************************************************************************/ RCODE JNIBackupStatus::backupStatus( FLMUINT64 ui64BytesToDo, FLMUINT64 ui64BytesDone) { RCODE rc = NE_XFLM_OK; JNIEnv * pEnv; jclass Cls; jmethodID MId; FLMBOOL bMustDetach = FALSE; if (m_pJvm->GetEnv( (void **)&pEnv, JNI_VERSION_1_2) != JNI_OK) { if (m_pJvm->AttachCurrentThread( (void **)&pEnv, NULL) != 0) { rc = RC_SET(NE_XFLM_FAILURE); goto Exit; } bMustDetach = TRUE; } Cls = pEnv->GetObjectClass( m_jStatus); MId = pEnv->GetMethodID( Cls, "backupStatus", "(JJ)I"); flmAssert( MId); rc = (RCODE)pEnv->CallIntMethod( m_jStatus, MId, (jlong)ui64BytesToDo, (jlong)ui64BytesDone); Exit: if (bMustDetach) { if (m_pJvm->DetachCurrentThread() != 0) { flmAssert( 0); rc = RC_SET( NE_XFLM_FAILURE); } } return( rc); }
JniCallbackHelper::~JniCallbackHelper() { if (mMethodId != 0) { if (mEnv->ExceptionCheck()) { JNI_HELPER_LOGE( "There was an exception thrown from the Java method!!"); mEnv->ExceptionClear(); } } for (std::vector<jobject>::iterator it = mNewJavaObjects.begin(); it != mNewJavaObjects.end(); ++it) { mEnv->DeleteLocalRef(*it); } mEnv->DeleteGlobalRef(mJObject); if (JNI_EDETACHED == mGetEnvResult) { JavaVM * vm; mEnv->GetJavaVM(&vm); vm->DetachCurrentThread(); } }
void OpenSLMediaPlayerHQVisualizerJNIBinder::onLeaveInternalPeriodicCaptureThread( OpenSLMediaPlayerHQVisualizer *visualizer) noexcept { LOGD("onLeaveInternalPeriodicCaptureThread()"); JavaVM *vm = jvm_; if (jvm_attached_) { // release global references for (auto &t : jwaveform_data_) { t.release(env_); } for (auto &t : jfft_data_) { t.release(env_); } // detach (void)vm->DetachCurrentThread(); jvm_attached_ = false; } env_ = nullptr; }
void GoogleStoreFront::getProducts(const char ** productIDs) const { __products.clear(); __requestedProducts.clear(); android_app* app = __state; JNIEnv* env = app->activity->env; JavaVM* vm = app->activity->vm; vm->AttachCurrentThread(&env, NULL); while (*productIDs) { __requestedProducts.insert(*productIDs); jstring paramString = env->NewStringUTF(*productIDs++); env->CallVoidMethod(app->activity->clazz, __midQueueSKURequest, paramString); } env->CallVoidMethod(app->activity->clazz, __midFlushSkuDetailsQueue); vm->DetachCurrentThread(); }
int closeKeyboardIME() { ANativeActivity *activity = sf::getNativeActivity(); JavaVM* vm = activity->vm; JNIEnv* env = activity->env; JavaVMAttachArgs attachargs; attachargs.version = JNI_VERSION_1_6; attachargs.name = "NativeThread"; attachargs.group = NULL; jint res = vm->AttachCurrentThread(&env, &attachargs); if (res == JNI_ERR) return EXIT_FAILURE; jclass natact = env->FindClass("android/app/NativeActivity"); jclass context = env->FindClass("android/content/Context"); jfieldID fid = env->GetStaticFieldID(context, "INPUT_METHOD_SERVICE", "Ljava/lang/String;"); jobject svcstr = env->GetStaticObjectField(context, fid); jmethodID getss = env->GetMethodID(natact, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); jobject imm_obj = env->CallObjectMethod(activity->clazz, getss, svcstr); jclass imm_cls = env->GetObjectClass(imm_obj); jmethodID toggleSoftInput = env->GetMethodID(imm_cls, "toggleSoftInput", "(II)V"); env->CallVoidMethod(imm_obj, toggleSoftInput, 1, 0); env->DeleteLocalRef(imm_obj); env->DeleteLocalRef(imm_cls); env->DeleteLocalRef(svcstr); env->DeleteLocalRef(context); env->DeleteLocalRef(natact); vm->DetachCurrentThread(); return EXIT_SUCCESS; }
void show_ads (void) { // Get the android application's activity. ANativeActivity* activity = gEngine.app->activity; JavaVM* jvm = activity->vm; JNIEnv* env = NULL; DTboolean needs_detach = false; int env_stat = jvm->GetEnv( (void**) &env, JNI_VERSION_1_6); if (env_stat == JNI_EDETACHED) { jvm->AttachCurrentThread(&env, 0); needs_detach = true; } ASSERT(env); jclass c_activity = env->GetObjectClass(activity->clazz); jmethodID m_show_ad_popup = env->GetMethodID(c_activity, "showAdPopup", "()V"); env->CallVoidMethod(activity->clazz, m_show_ad_popup); if (needs_detach) jvm->DetachCurrentThread(); }
static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) { JNIEnv *env; JavaVM *vm = AndroidRuntime::getJavaVM(); jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6); jboolean ret = JNI_FALSE; if (status != JNI_OK && status != JNI_EDETACHED) { ALOGE("%s unable to get environment for JNI call", __func__); return false; } if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, &sAttachArgs) != 0) { ALOGE("%s unable to attach thread to VM", __func__); return false; } sAlarmCallback = cb; sAlarmCallbackData = data; jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE; if (sJniAdapterServiceObj) { ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm, (jlong)delay_millis, jshould_wake); } else { ALOGE("JNI ERROR : JNI reference already cleaned : set_wake_alarm_callout", __FUNCTION__); } if (!ret) { sAlarmCallback = NULL; sAlarmCallbackData = NULL; } if (status == JNI_EDETACHED) { vm->DetachCurrentThread(); } return !!ret; }
// static void *TimedEventQueue::ThreadWrapper(void *me) { #ifdef ANDROID_SIMULATOR // The simulator runs everything as one process, so any // Binder calls happen on this thread instead of a thread // in another process. We therefore need to make sure that // this thread can do calls into interpreted code. // On the device this is not an issue because the remote // thread will already be set up correctly for this. JavaVM *vm; int numvms; JNI_GetCreatedJavaVMs(&vm, 1, &numvms); JNIEnv *env; vm->AttachCurrentThread(&env, NULL); #endif setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_FOREGROUND); static_cast<TimedEventQueue *>(me)->threadEntry(); #ifdef ANDROID_SIMULATOR vm->DetachCurrentThread(); #endif return NULL; }
std::string Database::getPath(std::string name) { std::string databasePath; JNIEnv* env; JavaVM* vm = engine->app->activity->vm; vm->AttachCurrentThread(&env, NULL); jclass clazz = env->GetObjectClass(engine->app->activity->clazz); jmethodID methodj = env->GetMethodID(clazz, "getDatabasePath", "(Ljava/lang/String;)Ljava/io/File;"); jobject filej = env->CallObjectMethod(engine->app->activity->clazz, methodj, env->NewStringUTF(name.c_str())); if (filej != NULL) { clazz = env->GetObjectClass(filej); methodj = env->GetMethodID(clazz, "getPath", "()Ljava/lang/String;"); jstring jstr = (jstring)env->CallObjectMethod(filej, methodj); if (jstr != NULL) { const char* str = env->GetStringUTFChars(jstr, NULL); databasePath = str; env->ReleaseStringUTFChars(jstr, str); } } vm->DetachCurrentThread(); return databasePath; }
static int SetThreadEvent(ThreadEvent event) { JavaVM* javaVm = AndroidRuntime::getJavaVM(); switch(event) { case ASSOCIATE_JVM: { if(sCallbackEnv != NULL) { ALOGE( "Attempted to associate callback in '%s'. Callback already associated.", __FUNCTION__ ); return FLP_RESULT_ERROR; } JavaVMAttachArgs args = { JNI_VERSION_1_6, "FLP Service Callback Thread", /* group */ NULL }; jint attachResult = javaVm->AttachCurrentThread(&sCallbackEnv, &args); if (attachResult != 0) { ALOGE("Callback thread attachment error: %d", attachResult); return FLP_RESULT_ERROR; } ALOGV("Callback thread attached: %p", sCallbackEnv); // Send the version to the upper layer. sCallbackEnv->CallVoidMethod( sCallbacksObj, sSetVersion, sFlpInterface->size == sizeof(FlpLocationInterface) ? 2 : 1 ); CheckExceptions(sCallbackEnv, __FUNCTION__); break; } case DISASSOCIATE_JVM: { if (!IsValidCallbackThread()) { ALOGE( "Attempted to dissasociate an unnownk callback thread : '%s'.", __FUNCTION__ ); return FLP_RESULT_ERROR; } if (javaVm->DetachCurrentThread() != 0) { return FLP_RESULT_ERROR; } sCallbackEnv = NULL; break; } default: ALOGE("Invalid ThreadEvent request %d", event); return FLP_RESULT_ERROR; } return FLP_RESULT_SUCCESS; }
void platformDisplayKeyboard(bool pShow) { jint lResult; jint lFlags = 0; JavaVM* lJavaVM = gApp->activity->vm; JNIEnv* lJNIEnv = gApp->activity->env; JavaVMAttachArgs lJavaVMAttachArgs; lJavaVMAttachArgs.version = JNI_VERSION_1_6; lJavaVMAttachArgs.name = "NativeThread"; lJavaVMAttachArgs.group = NULL; lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); if (lResult == JNI_ERR) { return; } // Retrieves NativeActivity. jobject lNativeActivity = gApp->activity->clazz; jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity); // Retrieves Context.INPUT_METHOD_SERVICE. jclass ClassContext = lJNIEnv->FindClass("android/content/Context"); jfieldID FieldINPUT_METHOD_SERVICE = lJNIEnv->GetStaticFieldID(ClassContext, "INPUT_METHOD_SERVICE", "Ljava/lang/String;"); jobject INPUT_METHOD_SERVICE = lJNIEnv->GetStaticObjectField(ClassContext, FieldINPUT_METHOD_SERVICE); //jniCheck(INPUT_METHOD_SERVICE); // Runs getSystemService(Context.INPUT_METHOD_SERVICE). jclass ClassInputMethodManager = lJNIEnv->FindClass( "android/view/inputmethod/InputMethodManager"); jmethodID MethodGetSystemService = lJNIEnv->GetMethodID( ClassNativeActivity, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); jobject lInputMethodManager = lJNIEnv->CallObjectMethod( lNativeActivity, MethodGetSystemService, INPUT_METHOD_SERVICE); // Runs getWindow().getDecorView(). jmethodID MethodGetWindow = lJNIEnv->GetMethodID( ClassNativeActivity, "getWindow", "()Landroid/view/Window;"); jobject lWindow = lJNIEnv->CallObjectMethod(lNativeActivity, MethodGetWindow); jclass ClassWindow = lJNIEnv->FindClass( "android/view/Window"); jmethodID MethodGetDecorView = lJNIEnv->GetMethodID( ClassWindow, "getDecorView", "()Landroid/view/View;"); jobject lDecorView = lJNIEnv->CallObjectMethod(lWindow, MethodGetDecorView); if (pShow) { // Runs lInputMethodManager.showSoftInput(...). jmethodID MethodShowSoftInput = lJNIEnv->GetMethodID( ClassInputMethodManager, "showSoftInput", "(Landroid/view/View;I)Z"); jboolean lResult = lJNIEnv->CallBooleanMethod( lInputMethodManager, MethodShowSoftInput, lDecorView, lFlags); } else { // Runs lWindow.getViewToken() jclass ClassView = lJNIEnv->FindClass( "android/view/View"); jmethodID MethodGetWindowToken = lJNIEnv->GetMethodID( ClassView, "getWindowToken", "()Landroid/os/IBinder;"); jobject lBinder = lJNIEnv->CallObjectMethod(lDecorView, MethodGetWindowToken); // lInputMethodManager.hideSoftInput(...). jmethodID MethodHideSoftInput = lJNIEnv->GetMethodID( ClassInputMethodManager, "hideSoftInputFromWindow", "(Landroid/os/IBinder;I)Z"); jboolean lRes = lJNIEnv->CallBooleanMethod( lInputMethodManager, MethodHideSoftInput, lBinder, lFlags); } // Finished with the JVM. lJavaVM->DetachCurrentThread(); }
~JniThreadBinding() { if (status == JNI_EDETACHED) { jvm->DetachCurrentThread(); } }
static void* msandroid_write_cb(msandroid_sound_write_data* d) { jbyteArray write_buff; jmethodID write_id=0; jmethodID play_id=0; int min_size=-1; int count; int max_size=sndwrite_flush_threshold*(float)d->rate*(float)d->nchannels*2.0; int check_point_size=3*(float)d->rate*(float)d->nchannels*2.0; /*3 seconds*/ int nwrites=0; set_high_prio(); int buff_size = d->write_chunk_size; //JNIEnv *jni_env = ms_get_jni_env(); JNIEnv *jni_env = NULL; JavaVM *jvm = ms_get_jvm(); if (jvm->AttachCurrentThread(&jni_env, NULL)!=0) { ms_fatal("AttachCurrentThread() failed !"); goto end; } // int write (byte[] audioData, int offsetInBytes, int sizeInBytes) write_id = jni_env->GetMethodID(d->audio_track_class,"write", "([BII)I"); if(write_id==0) { ms_error("cannot find AudioTrack.write() method"); goto end; } play_id = jni_env->GetMethodID(d->audio_track_class,"play", "()V"); if(play_id==0) { ms_error("cannot find AudioTrack.play() method"); goto end; } write_buff = jni_env->NewByteArray(buff_size); uint8_t tmpBuff[buff_size]; //start playing jni_env->CallVoidMethod(d->audio_track,play_id); ms_mutex_lock(&d->mutex); ms_bufferizer_flush(d->bufferizer); ms_mutex_unlock(&d->mutex); while(d->started) { int bufferizer_size; ms_mutex_lock(&d->mutex); min_size=-1; count=0; while((bufferizer_size = ms_bufferizer_get_avail(d->bufferizer)) >= d->write_chunk_size) { if (min_size==-1) min_size=bufferizer_size; else if (bufferizer_size<min_size) min_size=bufferizer_size; ms_bufferizer_read(d->bufferizer, tmpBuff, d->write_chunk_size); ms_mutex_unlock(&d->mutex); jni_env->SetByteArrayRegion(write_buff,0,d->write_chunk_size,(jbyte*)tmpBuff); int result = jni_env->CallIntMethod(d->audio_track,write_id,write_buff,0,d->write_chunk_size); d->writtenBytes+=result; if (result <= 0) { ms_error("write operation has failed [%i]",result); } nwrites++; ms_mutex_lock(&d->mutex); count+=d->write_chunk_size; if (count>check_point_size) { if (min_size > max_size) { ms_warning("we are late, flushing %i bytes",min_size); ms_bufferizer_skip_bytes(d->bufferizer,min_size); } count=0; } } if (d->started) { d->sleeping=true; ms_cond_wait(&d->cond,&d->mutex); d->sleeping=false; } ms_mutex_unlock(&d->mutex); } goto end; end: { jvm->DetachCurrentThread(); ms_thread_exit(NULL); return NULL; } }
int WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates* states) { // Prepare the Java virtual machine jint lResult; jint lFlags = 0; JavaVM* lJavaVM = states->activity->vm; JNIEnv* lJNIEnv = states->activity->env; JavaVMAttachArgs lJavaVMAttachArgs; lJavaVMAttachArgs.version = JNI_VERSION_1_6; lJavaVMAttachArgs.name = "NativeThread"; lJavaVMAttachArgs.group = NULL; lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); if (lResult == JNI_ERR) { err() << "Failed to initialize JNI, couldn't get the Unicode value" << std::endl; return 0; } // Retrieve everything we need to create this MotionEvent in Java jlong downTime = AMotionEvent_getDownTime(_event); jlong eventTime = AMotionEvent_getEventTime(_event); jint action = AMotionEvent_getAction(_event); jfloat x = AMotionEvent_getX(_event, 0); jfloat y = AMotionEvent_getY(_event, 0); jfloat pressure = AMotionEvent_getPressure(_event, 0); jfloat size = AMotionEvent_getSize(_event, 0); jint metaState = AMotionEvent_getMetaState(_event); jfloat xPrecision = AMotionEvent_getXPrecision(_event); jfloat yPrecision = AMotionEvent_getYPrecision(_event); jint deviceId = AInputEvent_getDeviceId(_event); jint edgeFlags = AMotionEvent_getEdgeFlags(_event); // Create the MotionEvent object in Java trough its static constructor obtain() jclass ClassMotionEvent = lJNIEnv->FindClass("android/view/MotionEvent"); jmethodID StaticMethodObtain = lJNIEnv->GetStaticMethodID(ClassMotionEvent, "obtain", "(JJIFFFFIFFII)Landroid/view/MotionEvent;"); jobject ObjectMotionEvent = lJNIEnv->CallStaticObjectMethod(ClassMotionEvent, StaticMethodObtain, downTime, eventTime, action, x, y, pressure, size, metaState, xPrecision, yPrecision, deviceId, edgeFlags); // Call its getAxisValue() method to get the delta value of our wheel move event jmethodID MethodGetAxisValue = lJNIEnv->GetMethodID(ClassMotionEvent, "getAxisValue", "(I)F"); jfloat delta = lJNIEnv->CallFloatMethod(ObjectMotionEvent, MethodGetAxisValue, 0x00000001); lJNIEnv->DeleteLocalRef(ClassMotionEvent); lJNIEnv->DeleteLocalRef(ObjectMotionEvent); // Create and send our mouse wheel event Event event; event.type = Event::MouseWheelMoved; event.mouseWheel.delta = static_cast<double>(delta); event.mouseWheel.x = AMotionEvent_getX(_event, 0); event.mouseWheel.y = AMotionEvent_getY(_event, 0); forwardEvent(event); // Detach this thread from the JVM lJavaVM->DetachCurrentThread(); return 1; }
static void sound_read_setup(MSFilter *f) { ms_debug("andsnd_read_preprocess"); msandroid_sound_read_data *d=(msandroid_sound_read_data*)f->data; jmethodID constructor_id=0; jmethodID min_buff_size_id; //jmethodID set_notification_period; int rc; //JNIEnv *jni_env = ms_get_jni_env(); JNIEnv *jni_env = NULL; JavaVM *jvm = ms_get_jvm(); if (jvm->AttachCurrentThread(&jni_env, NULL)!=0) { ms_fatal("AttachCurrentThread() failed !"); return; } d->audio_record_class = (jclass)jni_env->NewGlobalRef(jni_env->FindClass("android/media/AudioRecord")); if (d->audio_record_class == 0) { ms_error("cannot find android/media/AudioRecord"); jvm->DetachCurrentThread(); return; } constructor_id = jni_env->GetMethodID(d->audio_record_class,"<init>", "(IIIII)V"); if (constructor_id == 0) { ms_error("cannot find AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)"); jvm->DetachCurrentThread(); return; } min_buff_size_id = jni_env->GetStaticMethodID(d->audio_record_class,"getMinBufferSize", "(III)I"); if (min_buff_size_id == 0) { ms_error("cannot find AudioRecord.getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)"); jvm->DetachCurrentThread(); return; } d->buff_size = jni_env->CallStaticIntMethod(d->audio_record_class,min_buff_size_id,d->rate,2/*CHANNEL_CONFIGURATION_MONO*/,2/* ENCODING_PCM_16BIT */); d->read_chunk_size = d->buff_size/4; d->buff_size*=2;/*double the size for configuring the recorder: this does not affect latency but prevents "AudioRecordThread: buffer overflow"*/ if (d->buff_size > 0) { ms_message("Configuring recorder with [%i] bits rate [%i] nchanels [%i] buff size [%i], chunk size [%i]" ,d->bits ,d->rate ,d->nchannels ,d->buff_size ,d->read_chunk_size); } else { ms_message("Cannot configure recorder with [%i] bits rate [%i] nchanels [%i] buff size [%i] chunk size [%i]" ,d->bits ,d->rate ,d->nchannels ,d->buff_size ,d->read_chunk_size); return; } d->read_buff = jni_env->NewByteArray(d->buff_size); d->read_buff = (jbyteArray)jni_env->NewGlobalRef(d->read_buff); if (d->read_buff == 0) { ms_error("cannot instanciate read buff"); jvm->DetachCurrentThread(); return; } d->audio_record = jni_env->NewObject(d->audio_record_class ,constructor_id ,sdk_version<11?1/*MIC*/:7/*VOICE_COMMUNICATION*/ ,d->rate ,2/*CHANNEL_CONFIGURATION_MONO*/ ,2/* ENCODING_PCM_16BIT */ ,d->buff_size); d->audio_record = jni_env->NewGlobalRef(d->audio_record); if (d->audio_record == 0) { ms_error("cannot instantiate AudioRecord"); jvm->DetachCurrentThread(); return; } d->min_avail=-1; d->read_samples=0; d->ticker_synchronizer = ms_ticker_synchronizer_new(); d->outgran_ms=20; d->start_time=-1; d->framesize=(d->outgran_ms*d->rate)/1000; d->started=true; // start reader thread rc = ms_thread_create(&d->thread_id, 0, (void*(*)(void*))msandroid_read_cb, d); if (rc) { ms_error("cannot create read thread return code is [%i]", rc); d->started=false; } jvm->DetachCurrentThread(); }
bool startJVM(TCHAR* basedir, TCHAR* appFolder, TCHAR* jar, int argCount, LPTSTR *szArgList) { TCHAR jvmPath[LAUNCHER_MAXPATH+1] = {0}; JavaVMInitArgs jvmArgs; JavaVMOption options[MAX_OPTIONS]; JVM_CREATE createProc; JNIEnv* env; JavaVM* jvm = NULL; char jarASCII[LAUNCHER_MAXPATH] = {0}; char classpath[LAUNCHER_MAXPATH*2] = {0}; char mainclassASCII[LAUNCHER_MAXPATH] = {0}, appClasspath[LAUNCHER_MAXPATH] = {0}; size_t outlen = 0; jclass cls; jmethodID mid; TCHAR argname[MAX_OPTION_NAME + 1] = {0}; TCHAR argvalue[LAUNCHER_MAXPATH] = {0}, mainclass[LAUNCHER_MAXPATH] = {0}; CHAR argvalueASCII[LAUNCHER_MAXPATH] = {0}; HMODULE msvcrtdll; bool runtimeBundled; TCHAR tmpPath[LAUNCHER_MAXPATH] = {0}; TCHAR appid[LAUNCHER_MAXPATH] = {0}; memset(&options, 0, sizeof(JavaVMOption)*MAX_OPTIONS); memset(&jvmArgs, 0, sizeof(JavaVMInitArgs)); makeFullFileName(basedir, _T("\\runtime"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR)); runtimeBundled = fileExists(tmpPath); if (runtimeBundled) { if (!getJvmPath(basedir, jvmPath, LAUNCHER_MAXPATH)) { showError(_T("jvm.dll is not found in bundled runtime."), jvmPath); return false; } //make sure msvcr100 is loaded (or we may fail if copy of it is not installed into system) makeFullFileName(basedir, _T("runtime\\jre\\bin\\msvcr100.dll"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR)); msvcrtdll = ::LoadLibrary(tmpPath); } else { if (!getSystemJvmPath(jvmPath, LAUNCHER_MAXPATH)) { showError(_T("No bundled runtime and can not find system JRE."), jvmPath); return false; } //make sure msvcr100 is loaded (or we may fail if copy of it is not installed into system) makeFullFileName(basedir, _T("\\bin\\msvcr100.dll"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR)); msvcrtdll = ::LoadLibrary(tmpPath); } // Dynamically load the JVM HMODULE jvmLibHandle = LoadLibrary(jvmPath); if (jvmLibHandle == NULL) { DWORD dwErr = GetLastError(); showError(_T("Error loading jvm.dll"), jvmPath); return false; } //convert argument to ASCII string as this is what CreateJVM needs wcstombs_s(&outlen, jarASCII, LAUNCHER_MAXPATH, jar, (size_t) wcslen(jar) + 1); strcpy_s(classpath, LAUNCHER_MAXPATH*2, "-Djava.class.path="); strcat_s(classpath, LAUNCHER_MAXPATH, jarASCII); if (getConfigValue(basedir, CONFIG_CLASSPATH_KEY, argvalue, LAUNCHER_MAXPATH)) { size_t inLen = (size_t) wcslen(argvalue); //convert argument to ASCII string as this is what CreateJVM needs wcstombs_s(&outlen, argvalueASCII, sizeof(argvalueASCII), argvalue, inLen + 1); //compress spaces and replaces them with ; { char *in = argvalueASCII; char *out = argvalueASCII; bool needSemicolon = false; while (*in != 0) { if (*in == ' ') { if (needSemicolon) { *out = ';'; out++; needSemicolon = false; } } else { needSemicolon = true; *out = *in; out++; } in++; } *out = 0; } if (strlen(argvalueASCII) > 0) { strcat_s(classpath, LAUNCHER_MAXPATH, ";"); strcat_s(classpath, LAUNCHER_MAXPATH, argvalueASCII); } } // Set up the VM init args jvmArgs.version = JNI_VERSION_1_2; options[0].optionString = _strdup(classpath); int cnt = 1; if (isDebug) { options[cnt].optionString = _strdup("vfprintf"); options[cnt].extraInfo = vfprintfHook; cnt++; } //Note: should not try to quote the path. Spaces are fine here _stprintf_s(argvalue, _T("-Djava.library.path=%s"), appFolder); wcstombs_s(&outlen, argvalueASCII, sizeof(argvalueASCII), argvalue, wcslen(argvalue) + 1); options[cnt].optionString = _strdup(argvalueASCII); cnt++; //add app specific JVM parameters int idx = 1; int found = 0; do { _stprintf_s(argname, MAX_OPTION_NAME, _T("jvmarg.%d"), idx); found = getConfigValue(basedir, argname, argvalue, LAUNCHER_MAXPATH); if (found) { TCHAR* option = replaceStr(argvalue, _T("$APPDIR"), basedir); char* jvmOption = convertToDupedChar(option); if (jvmOption != NULL) { options[cnt].optionString = jvmOption; cnt++; } idx++; } } while (found && idx < MAX_OPTIONS); cnt = addUserOptions(basedir, options, cnt); jvmArgs.version = 0x00010002; jvmArgs.options = options; jvmArgs.nOptions = cnt; jvmArgs.ignoreUnrecognized = JNI_TRUE; // Create the JVM // NB: need to use ASCII string as UNICODE is not supported createProc = (JVM_CREATE) GetProcAddress(jvmLibHandle, "JNI_CreateJavaVM"); if (createProc == NULL) { showError(_T("Failed to locate JNI_CreateJavaVM"), jvmPath); return false; } if ((*createProc)(&jvm, &env, &jvmArgs) < 0) { showError(_T("Failed to create JVM"), jvmPath); return false; } if (!getConfigValue(basedir, CONFIG_MAINCLASS_KEY, mainclass, LAUNCHER_MAXPATH)) { showError(_T("Package error"), _T("No main class specified. Nothing to launch")); return false; } else { size_t inLen = (size_t) wcslen(mainclass); //convert argument to ASCII string as this is what CreateJVM needs wcstombs_s(&outlen, mainclassASCII, sizeof(mainclassASCII), mainclass, inLen + 1); } cls = env->FindClass(mainclassASCII); if (cls != NULL) { mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); if (mid != NULL) { jclass stringClass = env->FindClass("java/lang/String"); //prepare app arguments if any. Skip value at index 0 - this is path to executable ... //NOTE: // - what if user run in non-English/UTF-8 locale? do we need to convert args? // - extend to pass jvm args and debug args (allow them in front, use marker option to separate them?) int startArgIndex = countNumberOfSystemArguments(argCount, szArgList); jobjectArray args = env->NewObjectArray(argCount - startArgIndex, stringClass, NULL); for(int i=startArgIndex; i<argCount; i++) { size_t inLen = (size_t) wcslen(szArgList[i]); env->SetObjectArrayElement(args, i-startArgIndex, env->NewString((jchar*)szArgList[i], inLen)); } env->CallStaticVoidMethod(cls, mid, args); } else { showError(_T("no main method in the main class!"), mainclass); return false; } } else { showError(_T("no main class."), mainclass); return false; } if (env->ExceptionOccurred()) { showError(_T("Failed due to exception from main class."), mainclass); env->ExceptionDescribe(); } // If application main() exits quickly but application is run on some other thread // (e.g. Swing app performs invokeLater() in main and exits) // then if we return execution to tWinMain it will exit. // This will cause process to exit and application will not actually run. // // To avoid this we are trying to detach jvm from current thread (java.exe does the same) // Because we are doing this on the main JVM thread (i.e. one that was used to create JVM) // this call will spawn "Destroy Java VM" java thread that will shut JVM once there are // no non-daemon threads running, and then return control here. // I.e. this will happen when EDT and other app thread will exit. if (jvm->DetachCurrentThread() != 0) { showError(_T("Detach failed."), NULL); } jvm->DestroyJavaVM(); return true; }