From 84293fb9625a3ab7d7d302436bea05441b8d7316 Mon Sep 17 00:00:00 2001 From: Jamie Gennis Date: Fri, 17 Jun 2011 16:35:35 -0700 Subject: [PATCH] SurfaceTexture: attach to Dalvik when needed. This change fixes a bug in the SurfaceTexture JNI where a thread that the Dalvik VM was not aware of calls the onFrameAvailable callback. When this happens the callback needs to first attach the thread to the VM before attempting to post the onFrameAvailable event for Java code to handle. Change-Id: I6a5470c32611ea6f38e9167779450f50635cabd3 --- core/jni/android/graphics/SurfaceTexture.cpp | 32 +++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index 3f922f6206218..0d28cb1793585 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -91,6 +91,8 @@ public: virtual void onFrameAvailable(); private: + static JNIEnv* getJNIEnv(); + jobject mWeakThiz; jclass mClazz; }; @@ -101,17 +103,37 @@ JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env, mClazz((jclass)env->NewGlobalRef(clazz)) {} +JNIEnv* JNISurfaceTextureContext::getJNIEnv() { + JNIEnv* env; + JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; + JavaVM* vm = AndroidRuntime::getJavaVM(); + int result = vm->AttachCurrentThread(&env, (void*) &args); + if (result != JNI_OK) { + LOGE("thread attach failed: %#x", result); + return NULL; + } + return env; +} + JNISurfaceTextureContext::~JNISurfaceTextureContext() { - JNIEnv *env = AndroidRuntime::getJNIEnv(); - env->DeleteGlobalRef(mWeakThiz); - env->DeleteGlobalRef(mClazz); + JNIEnv* env = getJNIEnv(); + if (env != NULL) { + env->DeleteGlobalRef(mWeakThiz); + env->DeleteGlobalRef(mClazz); + } else { + LOGW("leaking JNI object references"); + } } void JNISurfaceTextureContext::onFrameAvailable() { - JNIEnv *env = AndroidRuntime::getJNIEnv(); - env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); + JNIEnv *env = getJNIEnv(); + if (env != NULL) { + env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); + } else { + LOGW("onFrameAvailable event will not posted"); + } } // ----------------------------------------------------------------------------