Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a8fd9b6 authored by Jamie Gennis's avatar Jamie Gennis
Browse files

SurfaceTexture: detach from Dalvik when necessary.

This change adds a call to detach from the Davlik VM in SurfaceTexture
JNI calls that caused an attach.

Change-Id: I8e0d7d596680bd25ac42f8db4ca8343a62827255
parent 09011777
Loading
Loading
Loading
Loading
+31 −10
Original line number Diff line number Diff line
@@ -91,7 +91,8 @@ public:
    virtual void onFrameAvailable();

private:
    static JNIEnv* getJNIEnv();
    static JNIEnv* getJNIEnv(bool* needsDetach);
    static void detachJNI();

    jobject mWeakThiz;
    jclass mClazz;
@@ -103,8 +104,10 @@ JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
    mClazz((jclass)env->NewGlobalRef(clazz))
{}

JNIEnv* JNISurfaceTextureContext::getJNIEnv() {
    JNIEnv* env;
JNIEnv* JNISurfaceTextureContext::getJNIEnv(bool* needsDetach) {
    *needsDetach = false;
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    if (env == NULL) {
        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
        JavaVM* vm = AndroidRuntime::getJavaVM();
        int result = vm->AttachCurrentThread(&env, (void*) &args);
@@ -112,28 +115,46 @@ JNIEnv* JNISurfaceTextureContext::getJNIEnv() {
            LOGE("thread attach failed: %#x", result);
            return NULL;
        }
        *needsDetach = true;
    }
    return env;
}

void JNISurfaceTextureContext::detachJNI() {
    JavaVM* vm = AndroidRuntime::getJavaVM();
    int result = vm->DetachCurrentThread();
    if (result != JNI_OK) {
        LOGE("thread detach failed: %#x", result);
    }
}

JNISurfaceTextureContext::~JNISurfaceTextureContext()
{
    JNIEnv* env = getJNIEnv();
    bool needsDetach = false;
    JNIEnv* env = getJNIEnv(&needsDetach);
    if (env != NULL) {
        env->DeleteGlobalRef(mWeakThiz);
        env->DeleteGlobalRef(mClazz);
    } else {
        LOGW("leaking JNI object references");
    }
    if (needsDetach) {
        detachJNI();
    }
}

void JNISurfaceTextureContext::onFrameAvailable()
{
    JNIEnv *env = getJNIEnv();
    bool needsDetach = false;
    JNIEnv* env = getJNIEnv(&needsDetach);
    if (env != NULL) {
        env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
    } else {
        LOGW("onFrameAvailable event will not posted");
    }
    if (needsDetach) {
        detachJNI();
    }
}

// ----------------------------------------------------------------------------