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

Commit 5057590f authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Fix issue with leaked preserved surface

Imagine a non-app-window going through the following sequence:

1. Window starts out visible
2. Client sets to GONE
3. Exit animation starts.
4. Client sets to VISIBLE
5. Before it can redraw, Client sets to GONE again

In that case we preserve the surface because we need to client to
force-retrieve a new surface. However, we never mark the surface
as to be destroyed because we never enter the path in
WSA.prepareSurfaceLocked that would mark the preserved surface to
be destroyed, which is only the case when the client redraws.

Fix this by also marking it as to be destroyed when the surface
gets hidden.

Test: Above flow. See bug for test app.
Change-Id: Ic554ae787e7d2130b93b993fadf8c302913ed6ee
Fixes: 77633603
parent 082147cf
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -4101,11 +4101,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        mDestroying = true;

        final boolean hasSurface = mWinAnimator.hasSurface();
        if (hasSurface) {

        // Use pendingTransaction here so hide is done the same transaction as the other
        // animations when exiting
        mWinAnimator.hide(getPendingTransaction(), "onExitAnimationDone");
        }

        // If we have an app token, we ask it to destroy the surface for us, so that it can take
        // care to ensure the activity has actually stopped and the surface is not still in use.
+6 −0
Original line number Diff line number Diff line
@@ -301,6 +301,12 @@ class WindowStateAnimator {
        if (!mLastHidden) {
            //dump();
            mLastHidden = true;

            // We may have a preserved surface which we no longer need. If there was a quick
            // VISIBLE, GONE, VISIBLE, GONE sequence, the surface may never draw, so we don't mark
            // it to be destroyed in prepareSurfaceLocked.
            markPreservedSurfaceForDestroy();

            if (mSurfaceController != null) {
                mSurfaceController.hide(transaction, reason);
            }