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

Commit 97afa758 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Unset window destroying state only if its surface is destroyed

Otherwise if mDestroying is unset unexpectedly, the pending
destroing surface of the window will show on screen again.
E.g. from ActivityRecord#notifyAppResumed
  -> ActivityRecord#destroySurfaces
   -> WindowStatedestroySurface(
       cleanupOnResume=true, appStopped=false)

Fix: 377179807
Flag: EXEMPT bugfix
Test: atest WindowStateTests#testDestroySurface
Test: Set the root view of a dialog in an activity to GONE.
      Switch to another activity and switch back before the
      previous activity stopped. The dialog should not appear
      on screen.
Change-Id: I380e87e0df40d5d5dda8ea71d1164cf9259da555
parent 247a20f2
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -3380,8 +3380,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            if (cleanupOnResume) {
                requestUpdateWallpaperIfNeeded();
            }
            if (!mHasSurface) {
                mDestroying = false;
                destroyedSomething = true;
            }

            // Since mDestroying will affect ActivityRecord#allDrawn, we need to perform another
            // traversal in case we are waiting on this window to start the transition.
+23 −0
Original line number Diff line number Diff line
@@ -352,6 +352,29 @@ public class WindowStateTests extends WindowTestsBase {
        assertTrue(windows.isEmpty());
    }

    @Test
    public void testDestroySurface() {
        final WindowState win = createWindow(null, TYPE_APPLICATION, "win");
        win.mHasSurface = win.mAnimatingExit = true;
        win.mWinAnimator.mSurfaceControl = mock(SurfaceControl.class);
        win.onExitAnimationDone();

        assertFalse("Case 1 destroySurface no-op",
                win.destroySurface(false /* cleanupOnResume */, false /* appStopped */));
        assertTrue(win.mHasSurface);
        assertTrue(win.mDestroying);

        assertFalse("Case 2 destroySurface no-op",
                win.destroySurface(true /* cleanupOnResume */, false /* appStopped */));
        assertTrue(win.mHasSurface);
        assertTrue(win.mDestroying);

        assertTrue("Case 3 destroySurface destroys surface",
                win.destroySurface(false /* cleanupOnResume */, true /* appStopped */));
        assertFalse(win.mDestroying);
        assertFalse(win.mHasSurface);
    }

    @Test
    public void testPrepareWindowToDisplayDuringRelayout() {
        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before