From 2430cb4edb8574c187076d0633f355ced31bcb2a Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 18 May 2022 22:40:21 +0800 Subject: [PATCH] Do not wait for invisible activity when turning on screen The activity may somehow keep its surface while it is invisible. That causes its window WindowState#isVisible() still returns true and is added to the waiting list. Because the invisible activity won't redraw, that leads to 1s screen on timeout. Bug: 231390641 Test: atest WindowStateTests#testRequestDrawIfNeeded Change-Id: I0374e61641b02bc59c4edf308ec6d3f6683409c2 --- services/core/java/com/android/server/wm/WindowState.java | 1 + .../src/com/android/server/wm/WindowStateTests.java | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 3e0ed32eb3c98..614cebd69a8d3 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2171,6 +2171,7 @@ class WindowState extends WindowContainer implements WindowManagerP return; } if (mActivityRecord != null) { + if (!mActivityRecord.mVisibleRequested) return; if (mActivityRecord.allDrawn) { // The allDrawn of activity is reset when the visibility is changed to visible, so // the content should be ready if allDrawn is set. 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 b6998d84afa35..e6e7f8c334174 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -673,6 +673,14 @@ public class WindowStateTests extends WindowTestsBase { // Keyguard host window should be always contained. The drawn app or app with starting // window are unnecessary to draw. assertEquals(Arrays.asList(keyguardHostWindow, startingWindow), outWaitingForDrawn); + + // No need to wait for a window of invisible activity even if the window has surface. + final WindowState invisibleApp = mAppWindow; + invisibleApp.mActivityRecord.mVisibleRequested = false; + invisibleApp.mActivityRecord.allDrawn = false; + outWaitingForDrawn.clear(); + invisibleApp.requestDrawIfNeeded(outWaitingForDrawn); + assertTrue(outWaitingForDrawn.isEmpty()); } @UseTestDisplay(addWindows = W_ABOVE_ACTIVITY)