Move HardwareObserver off of NewWeakGlobalRef

Test: atest android.view.cts.FrameMetricsListenerTest
Bug: 194893628
Change-Id: I352ba74ba03ac998ddcf53a2d5d65f2577e23dd5
This commit is contained in:
John Reck
2021-08-11 13:21:41 -04:00
parent 5029d122d0
commit 31bde04846
3 changed files with 40 additions and 20 deletions

View File

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

View File

@@ -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());

View File

@@ -63,7 +63,8 @@ private:
};
JavaVM* const mVm;
jweak mObserverWeak;
jobject mObserver;
bool mKeepListening = true;
int mNextFree = 0;
int mNextInQueue = 0;