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

Commit 170cdc36 authored by Huihong Luo's avatar Huihong Luo Committed by Automerger Merge Worker
Browse files

Merge "Fix potential ASurfaceTransactionCallback leaks" into sc-dev am: fec5e82e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14968642

Change-Id: I9db798f77359123ba608e3457a3fca4bd62fdf26
parents 25f098a1 fec5e82e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -753,8 +753,12 @@ public class HardwareRenderer {
        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
    }

    private ASurfaceTransactionCallback mASurfaceTransactionCallback;

    /** @hide */
    public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) {
        // ensure callback is kept alive on the java side since weak ref is used in native code
        mASurfaceTransactionCallback = callback;
        nSetASurfaceTransactionCallback(mNativeProxy, callback);
    }

+30 −4
Original line number Diff line number Diff line
@@ -500,6 +500,28 @@ private:
    jobject mObject;
};

class JWeakGlobalRefHolder {
public:
    JWeakGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm) {
        mWeakRef = getenv(vm)->NewWeakGlobalRef(object);
    }

    virtual ~JWeakGlobalRefHolder() {
        if (mWeakRef != nullptr) getenv(mVm)->DeleteWeakGlobalRef(mWeakRef);
        mWeakRef = nullptr;
    }

    jobject ref() { return mWeakRef; }
    JavaVM* vm() { return mVm; }

private:
    JWeakGlobalRefHolder(const JWeakGlobalRefHolder&) = delete;
    void operator=(const JWeakGlobalRefHolder&) = delete;

    JavaVM* mVm;
    jobject mWeakRef;
};

using TextureMap = std::unordered_map<uint32_t, sk_sp<SkImage>>;

struct PictureCaptureState {
@@ -633,15 +655,19 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback(
    } else {
        JavaVM* vm = nullptr;
        LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
        auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(
                vm, env->NewGlobalRef(aSurfaceTransactionCallback));
        auto globalCallbackRef =
                std::make_shared<JWeakGlobalRefHolder>(vm, aSurfaceTransactionCallback);
        proxy->setASurfaceTransactionCallback(
                [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) {
                    JNIEnv* env = getenv(globalCallbackRef->vm());
                    env->CallVoidMethod(globalCallbackRef->object(),
                                        gASurfaceTransactionCallback.onMergeTransaction,
                    jobject localref = env->NewLocalRef(globalCallbackRef->ref());
                    if (CC_UNLIKELY(!localref)) {
                        return;
                    }
                    env->CallVoidMethod(localref, gASurfaceTransactionCallback.onMergeTransaction,
                                        static_cast<jlong>(transObj), static_cast<jlong>(scObj),
                                        static_cast<jlong>(frameNr));
                    env->DeleteLocalRef(localref);
                });
    }
}