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
This commit is contained in:
Jamie Gennis
2011-06-17 16:35:35 -07:00
parent f71e546944
commit 84293fb962

View File

@@ -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");
}
}
// ----------------------------------------------------------------------------