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

Commit 9118c9b5 authored by chaviw's avatar chaviw
Browse files

Call preserveSurfaces when detaching children.

When WM calls detachChildren, it means the app is exiting and we
temporarily want to keep the children around so they aren't removed
during the animation. If the app is quickly relaunched, the children
will remain detached and will not be removed.

Therefore, add a call to preserveSurfaces when detachChildren is called
so it can keep the children around. When the app relaunches, it will tear
down the preserved surface. We also need to ensure the children aren't
reparented to the new surface so we make sure the children weren't
detached previously before reparented them to the new surface.

Test: Quickly close and open app with SV. SV will not leak
Bug: 157439199
Fixes: 155694905
Change-Id: Iea8ed86a9c4a7674804152aa44df7ef3d6341768
parent 28fdf609
Loading
Loading
Loading
Loading
+26 −16
Original line number Original line Diff line number Diff line
@@ -418,25 +418,25 @@ class WindowStateAnimator {
        if (!mDestroyPreservedSurfaceUponRedraw) {
        if (!mDestroyPreservedSurfaceUponRedraw) {
            return;
            return;
        }
        }
        if (mSurfaceController != null) {

            if (mPendingDestroySurface != null) {
        // If we are preserving a surface but we aren't relaunching that means
        // If we are preserving a surface but we aren't relaunching that means
        // we are just doing an in-place switch. In that case any SurfaceFlinger side
        // we are just doing an in-place switch. In that case any SurfaceFlinger side
        // child layers need to be reparented to the new surface to make this
        // child layers need to be reparented to the new surface to make this
        // transparent to the app.
        // transparent to the app.
                if (mWin.mActivityRecord == null || mWin.mActivityRecord.isRelaunching() == false) {
        // If the children are detached, we don't want to reparent them to the new surface.
        // Instead let the children get removed when the old surface is deleted.
        if (mSurfaceController != null && mPendingDestroySurface != null && !mChildrenDetached
                && (mWin.mActivityRecord == null || !mWin.mActivityRecord.isRelaunching())) {
            mPostDrawTransaction.reparentChildren(
            mPostDrawTransaction.reparentChildren(
                    mPendingDestroySurface.getClientViewRootSurface(),
                    mPendingDestroySurface.getClientViewRootSurface(),
                    mSurfaceController.mSurfaceControl).apply();
                    mSurfaceController.mSurfaceControl).apply();
        }
        }
            }
        }


        destroyDeferredSurfaceLocked();
        destroyDeferredSurfaceLocked();
        mDestroyPreservedSurfaceUponRedraw = false;
        mDestroyPreservedSurfaceUponRedraw = false;
    }
    }


    void markPreservedSurfaceForDestroy() {
    private void markPreservedSurfaceForDestroy() {
        if (mDestroyPreservedSurfaceUponRedraw
        if (mDestroyPreservedSurfaceUponRedraw
                && !mService.mDestroyPreservedSurface.contains(mWin)) {
                && !mService.mDestroyPreservedSurface.contains(mWin)) {
            mService.mDestroyPreservedSurface.add(mWin);
            mService.mDestroyPreservedSurface.add(mWin);
@@ -1363,10 +1363,14 @@ class WindowStateAnimator {
        if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
        if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
            final SurfaceControl pendingSurfaceControl = mPendingDestroySurface.mSurfaceControl;
            final SurfaceControl pendingSurfaceControl = mPendingDestroySurface.mSurfaceControl;
            mPostDrawTransaction.reparent(pendingSurfaceControl, null);
            mPostDrawTransaction.reparent(pendingSurfaceControl, null);
            // If the children are detached, we don't want to reparent them to the new surface.
            // Instead let the children get removed when the old surface is deleted.
            if (!mChildrenDetached) {
                mPostDrawTransaction.reparentChildren(
                mPostDrawTransaction.reparentChildren(
                        mPendingDestroySurface.getClientViewRootSurface(),
                        mPendingDestroySurface.getClientViewRootSurface(),
                        mSurfaceController.mSurfaceControl);
                        mSurfaceController.mSurfaceControl);
            }
            }
        }


        SurfaceControl.mergeToGlobalTransaction(mPostDrawTransaction);
        SurfaceControl.mergeToGlobalTransaction(mPostDrawTransaction);
        return true;
        return true;
@@ -1593,6 +1597,12 @@ class WindowStateAnimator {
            mSurfaceController.detachChildren();
            mSurfaceController.detachChildren();
        }
        }
        mChildrenDetached = true;
        mChildrenDetached = true;
        // If the children are detached, it means the app is exiting. We don't want to tear the
        // content down too early, otherwise we could end up with a flicker. By preserving the
        // current surface, we ensure the content remains on screen until the window is completely
        // removed. It also ensures that the old surface is cleaned up when started again since it
        // forces mSurfaceController to be set to null.
        preserveSurfaceLocked();
    }
    }


    void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) {
    void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) {