From ab8ed02c20ba6e97530b741f5935b99b3cd08f15 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 3 Mar 2022 20:59:58 +0800 Subject: [PATCH] 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 --- .../com/android/server/wm/WindowState.java | 4 ++++ .../android/server/wm/WindowStateTests.java | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index d547275dcf0c2..e698e2f28612e 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3583,6 +3583,10 @@ class WindowState extends WindowContainer 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) { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index a554fab76c2b8..e70dd08af8a14 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -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");