diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 3ffb78161da19..73ebcedbe6e05 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -110,7 +110,7 @@ public final class SurfaceControl implements Parcelable { private static native long nativeReadFromParcel(Parcel in); private static native long nativeCopyFromSurfaceControl(long nativeObject); private static native void nativeWriteToParcel(long nativeObject, Parcel out); - private static native void nativeRelease(long nativeObject); + private static native long nativeGetNativeSurfaceControlFinalizer(); private static native void nativeDisconnect(long nativeObject); private static native void nativeUpdateDefaultBufferSize(long nativeObject, int width, int height); @@ -464,6 +464,12 @@ public final class SurfaceControl implements Parcelable { static GlobalTransactionWrapper sGlobalTransaction; static long sTransactionNestCount = 0; + private static final NativeAllocationRegistry sRegistry = + NativeAllocationRegistry.createMalloced(SurfaceControl.class.getClassLoader(), + nativeGetNativeSurfaceControlFinalizer()); + + private Runnable mFreeNativeResources; + /** * Adds a reparenting listener. * @@ -722,6 +728,8 @@ public final class SurfaceControl implements Parcelable { } if (nativeObject != 0) { mCloseGuard.openWithCallSite("release", callsite); + mFreeNativeResources = + sRegistry.registerNativeAllocation(this, nativeObject); } mNativeObject = nativeObject; mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0; @@ -1150,6 +1158,7 @@ public final class SurfaceControl implements Parcelable { mHeight = h; mLocalOwnerView = localOwnerView; Parcel metaParcel = Parcel.obtain(); + long nativeObject = 0; try { if (metadata != null && metadata.size() > 0) { metaParcel.writeInt(metadata.size()); @@ -1161,17 +1170,16 @@ public final class SurfaceControl implements Parcelable { } metaParcel.setDataPosition(0); } - mNativeObject = nativeCreate(session, name, w, h, format, flags, + nativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0, metaParcel); } finally { metaParcel.recycle(); } - if (mNativeObject == 0) { + if (nativeObject == 0) { throw new OutOfResourcesException( "Couldn't allocate SurfaceControl native object"); } - mNativeHandle = nativeGetHandle(mNativeObject); - mCloseGuard.openWithCallSite("release", callsite); + assignNativeObject(nativeObject, callsite); } /** @@ -1283,9 +1291,6 @@ public final class SurfaceControl implements Parcelable { if (mCloseGuard != null) { mCloseGuard.warnIfOpen(); } - if (mNativeObject != 0) { - nativeRelease(mNativeObject); - } } finally { super.finalize(); } @@ -1303,7 +1308,7 @@ public final class SurfaceControl implements Parcelable { */ public void release() { if (mNativeObject != 0) { - nativeRelease(mNativeObject); + mFreeNativeResources.run(); mNativeObject = 0; mNativeHandle = 0; mCloseGuard.close(); diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 68db603c36717..422bdc98e9b54 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -1530,12 +1530,14 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_VintfRuntimeInfo), REG_JNI(register_android_service_DataLoaderService), REG_JNI(register_android_view_DisplayEventReceiver), - REG_JNI(register_android_view_InputApplicationHandle), - REG_JNI(register_android_view_InputWindowHandle), REG_JNI(register_android_view_Surface), REG_JNI(register_android_view_SurfaceControl), REG_JNI(register_android_view_SurfaceControlHdrLayerInfoListener), REG_JNI(register_android_view_SurfaceSession), + REG_JNI(register_android_view_InputApplicationHandle), + // This must be called after register_android_view_SurfaceControl since it has a dependency + // on the Java SurfaceControl object that references a native resource via static request. + REG_JNI(register_android_view_InputWindowHandle), REG_JNI(register_android_view_CompositionSamplingListener), REG_JNI(register_android_view_TextureView), REG_JNI(register_android_view_TunnelModeEnabledListener), diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index b11f22a030d98..049b26e772ff0 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -368,11 +368,14 @@ static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, return reinterpret_cast(surface.get()); } -static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) { - sp ctrl(reinterpret_cast(nativeObject)); +static void release(SurfaceControl* ctrl) { ctrl->decStrong((void *)nativeCreate); } +static jlong nativeGetNativeSurfaceControlFinalizer(JNIEnv* env, jclass clazz) { + return static_cast(reinterpret_cast(&release)); +} + static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) { SurfaceControl* const ctrl = reinterpret_cast(nativeObject); if (ctrl != NULL) { @@ -1925,8 +1928,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeCopyFromSurfaceControl }, {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteToParcel }, - {"nativeRelease", "(J)V", - (void*)nativeRelease }, + {"nativeGetNativeSurfaceControlFinalizer", "()J", + (void*) nativeGetNativeSurfaceControlFinalizer }, {"nativeDisconnect", "(J)V", (void*)nativeDisconnect }, {"nativeUpdateDefaultBufferSize", "(JII)V",