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

Commit ab8ed02c authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Consume sync draw handlers if the surface is destroyed

After requesting blast sync, the window may want to remove
itself and there won't be a finish draw event. Then the
handlers of sync such as seamless rotation keeps waiting
until timeout. So simply notify them to clear the state
if the window surface is destroyed.

Bug: 222048036
Test: atest WindowStateTests#testApplyWithNextDraw
Test: 1. Enable auto rotation and launcher is portrait only.
      2. Launch Settings while holding device in landscape.
      3. Use gesture navigation to swipe up.
      4. Click app icon above the task view.
      5. Click the task view to back to Settings.
      6. The status/nav bars should be visible immediately.
         (No timeout from SecondaryHomeHandle0)
Change-Id: I2c8edf230a149b520032ec132e5df1aaa6683ef8
parent 4fa92e4a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3583,6 +3583,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        // Clear animating flags now, since the surface is now gone. (Note this is true even
        // if the surface is saved, to outside world the surface is still NO_SURFACE.)
        mAnimatingExit = false;

        if (useBLASTSync()) {
            immediatelyNotifyBlastSync();
        }
    }

    void onSurfaceShownChanged(boolean shown) {
+21 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
@@ -491,6 +492,26 @@ public class WindowStateTests extends WindowTestsBase {
        assertThat(app.getDisplayId(), is(mDisplayContent.getDisplayId()));
    }

    @Test
    public void testApplyWithNextDraw() {
        final WindowState win = createWindow(null, TYPE_APPLICATION_OVERLAY, "app");
        final SurfaceControl.Transaction[] handledT = { null };
        // The normal case that the draw transaction is applied with finishing drawing.
        win.applyWithNextDraw(t -> handledT[0] = t);
        assertTrue(win.useBLASTSync());
        final SurfaceControl.Transaction drawT = new StubTransaction();
        win.prepareDrawHandlers();
        assertTrue(win.finishDrawing(drawT));
        assertEquals(drawT, handledT[0]);
        assertFalse(win.useBLASTSync());

        // If the window is gone before reporting drawn, the sync state should be cleared.
        win.applyWithNextDraw(t -> handledT[0] = t);
        win.destroySurfaceUnchecked();
        assertFalse(win.useBLASTSync());
        assertNotEquals(drawT, handledT[0]);
    }

    @Test
    public void testSeamlesslyRotateWindow() {
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");