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

Commit 43b0f37a authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Surface: Release references to BlastBufferQueue and SurfaceControl on Surface#destroy

SurfaceView clients may hold on to surface references. In S this means
they would extend the lifetime of the SurfaceControl resulting in
"leaking" buffers until the references are cleared or the app is
terminated.

Fix this by calling a new destroy function on Surface which will
explicitly remove references to the SurfaceControl and BBQ it holds.
This is safe because SurfaceView controls the lifecycle of the Surface
and knows when the Surface will become invalid. Once invalid, the Surface
cannot become valid again.

Test: repro steps in bug
Bug: 198133921
Change-Id: I5c7e43736f025fc0965eae2f19719ba40df3cb70
Merged-In: I5c7e43736f025fc0965eae2f19719ba40df3cb70
parent 67179b8e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ public class Surface implements Parcelable {

    private static native int nativeSetFrameRate(
            long nativeObject, float frameRate, int compatibility, int changeFrameRateStrategy);
    private static native void nativeDestroy(long nativeObject);

    public static final @android.annotation.NonNull Parcelable.Creator<Surface> CREATOR =
            new Parcelable.Creator<Surface>() {
@@ -339,6 +340,9 @@ public class Surface implements Parcelable {
     */
    @UnsupportedAppUsage
    public void destroy() {
        if (mNativeObject != 0) {
            nativeDestroy(mNativeObject);
        }
        release();
    }

+1 −1
Original line number Diff line number Diff line
@@ -903,7 +903,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        mSurfaceAlpha = 1f;

        synchronized (mSurfaceControlLock) {
            mSurface.release();
            mSurface.destroy();
            if (mBlastBufferQueue != null) {
                mBlastBufferQueue.destroy();
                mBlastBufferQueue = null;
+6 −0
Original line number Diff line number Diff line
@@ -449,6 +449,11 @@ static jint nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong nativeObject, jf
                        int(changeFrameRateStrategy));
}

static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
    sp<Surface> surface(reinterpret_cast<Surface*>(nativeObject));
    surface->destroy();
}

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

static const JNINativeMethod gSurfaceMethods[] = {
@@ -477,6 +482,7 @@ static const JNINativeMethod gSurfaceMethods[] = {
        {"nativeSetAutoRefreshEnabled", "(JZ)I", (void*)nativeSetAutoRefreshEnabled},
        {"nativeSetFrameRate", "(JFII)I", (void*)nativeSetFrameRate},
        {"nativeGetFromBlastBufferQueue", "(JJ)J", (void*)nativeGetFromBlastBufferQueue},
        {"nativeDestroy", "(J)V", (void*)nativeDestroy},
};

int register_android_view_Surface(JNIEnv* env)