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

Commit 31bde048 authored by John Reck's avatar John Reck
Browse files

Move HardwareObserver off of NewWeakGlobalRef

Test: atest android.view.cts.FrameMetricsListenerTest
Bug: 194893628
Change-Id: I352ba74ba03ac998ddcf53a2d5d65f2577e23dd5
parent 5029d122
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -21,12 +21,14 @@ import android.os.Handler;

import com.android.internal.util.VirtualRefBasePtr;

import java.lang.ref.WeakReference;

/**
 * Provides streaming access to frame stats information from HardwareRenderer to apps.
 *
 * @hide
 */
public class HardwareRendererObserver {
public final class HardwareRendererObserver {
    private final long[] mFrameMetrics;
    private final Handler mHandler;
    private final OnFrameMetricsAvailableListener mListener;
@@ -74,15 +76,14 @@ public class HardwareRendererObserver {
        mFrameMetrics = frameMetrics;
        mHandler = handler;
        mListener = listener;
        mNativePtr = new VirtualRefBasePtr(nCreateObserver(waitForPresentTime));
        mNativePtr = new VirtualRefBasePtr(nCreateObserver(
                new WeakReference<>(this), waitForPresentTime));
    }

    /*package*/ long getNativeInstance() {
        return mNativePtr.get();
    }

    // Called by native on the provided Handler
    @SuppressWarnings("unused")
    private void notifyDataAvailable() {
        mHandler.post(() -> {
            boolean hasMoreData = true;
@@ -98,6 +99,21 @@ public class HardwareRendererObserver {
        });
    }

    private native long nCreateObserver(boolean waitForPresentTime);
    /**
     * called by native
     * @hide
     * @return true to keep listening, false if this is a dead observer
     */
    static boolean invokeDataAvailable(WeakReference<HardwareRendererObserver> weakObserver) {
        HardwareRendererObserver observer = weakObserver.get();
        if (observer != null) {
            observer.notifyDataAvailable();
            return true;
        }
        return false;
    }

    private static native long nCreateObserver(WeakReference<HardwareRendererObserver> observer,
            boolean waitForPresentTime);
    private static native int nGetNextBuffer(long nativePtr, long[] data);
}
+17 −14
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
namespace android {

struct {
    jclass clazz;
    jmethodID callback;
} gHardwareRendererObserverClassInfo;

@@ -38,14 +39,13 @@ static JNIEnv* getenv(JavaVM* vm) {
HardwareRendererObserver::HardwareRendererObserver(JavaVM* vm, jobject observer,
                                                   bool waitForPresentTime)
        : uirenderer::FrameMetricsObserver(waitForPresentTime), mVm(vm) {
    mObserverWeak = getenv(mVm)->NewWeakGlobalRef(observer);
    LOG_ALWAYS_FATAL_IF(mObserverWeak == nullptr,
            "unable to create frame stats observer reference");
    mObserver = getenv(mVm)->NewGlobalRef(observer);
    LOG_ALWAYS_FATAL_IF(mObserver == nullptr, "unable to create frame stats observer reference");
}

HardwareRendererObserver::~HardwareRendererObserver() {
    JNIEnv* env = getenv(mVm);
    env->DeleteWeakGlobalRef(mObserverWeak);
    env->DeleteGlobalRef(mObserver);
}

bool HardwareRendererObserver::getNextBuffer(JNIEnv* env, jlongArray metrics, int* dropCount) {
@@ -66,6 +66,8 @@ bool HardwareRendererObserver::getNextBuffer(JNIEnv* env, jlongArray metrics, in
}

void HardwareRendererObserver::notify(const int64_t* stats) {
    if (!mKeepListening) return;

    FrameMetricsNotification& elem = mRingBuffer[mNextFree];

    if (!elem.hasData.load()) {
@@ -77,18 +79,17 @@ void HardwareRendererObserver::notify(const int64_t* stats) {
        elem.hasData = true;

        JNIEnv* env = getenv(mVm);
        jobject target = env->NewLocalRef(mObserverWeak);
        if (target != nullptr) {
            env->CallVoidMethod(target, gHardwareRendererObserverClassInfo.callback);
            env->DeleteLocalRef(target);
        }
        mKeepListening = env->CallStaticBooleanMethod(gHardwareRendererObserverClassInfo.clazz,
                                                      gHardwareRendererObserverClassInfo.callback,
                                                      mObserver);
    } else {
        mDroppedReports++;
    }
}

static jlong android_graphics_HardwareRendererObserver_createObserver(JNIEnv* env,
                                                                      jobject observerObj,
                                                                      jobject /*clazz*/,
                                                                      jobject weakRefThis,
                                                                      jboolean waitForPresentTime) {
    JavaVM* vm = nullptr;
    if (env->GetJavaVM(&vm) != JNI_OK) {
@@ -97,7 +98,7 @@ static jlong android_graphics_HardwareRendererObserver_createObserver(JNIEnv* en
    }

    HardwareRendererObserver* observer =
            new HardwareRendererObserver(vm, observerObj, waitForPresentTime);
            new HardwareRendererObserver(vm, weakRefThis, waitForPresentTime);
    return reinterpret_cast<jlong>(observer);
}

@@ -114,7 +115,7 @@ static jint android_graphics_HardwareRendererObserver_getNextBuffer(JNIEnv* env,
}

static const std::array gMethods = {
        MAKE_JNI_NATIVE_METHOD("nCreateObserver", "(Z)J",
        MAKE_JNI_NATIVE_METHOD("nCreateObserver", "(Ljava/lang/ref/WeakReference;Z)J",
                               android_graphics_HardwareRendererObserver_createObserver),
        MAKE_JNI_NATIVE_METHOD("nGetNextBuffer", "(J[J)I",
                               android_graphics_HardwareRendererObserver_getNextBuffer),
@@ -123,8 +124,10 @@ static const std::array gMethods = {
int register_android_graphics_HardwareRendererObserver(JNIEnv* env) {

    jclass observerClass = FindClassOrDie(env, "android/graphics/HardwareRendererObserver");
    gHardwareRendererObserverClassInfo.callback = GetMethodIDOrDie(env, observerClass,
                                                                   "notifyDataAvailable", "()V");
    gHardwareRendererObserverClassInfo.clazz =
            reinterpret_cast<jclass>(env->NewGlobalRef(observerClass));
    gHardwareRendererObserverClassInfo.callback = GetStaticMethodIDOrDie(
            env, observerClass, "invokeDataAvailable", "(Ljava/lang/ref/WeakReference;)Z");

    return RegisterMethodsOrDie(env, "android/graphics/HardwareRendererObserver",
                                gMethods.data(), gMethods.size());
+2 −1
Original line number Diff line number Diff line
@@ -63,7 +63,8 @@ private:
    };

    JavaVM* const mVm;
    jweak mObserverWeak;
    jobject mObserver;
    bool mKeepListening = true;

    int mNextFree = 0;
    int mNextInQueue = 0;