diff options
3 files changed, 63 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 06cea3741aa1..c95111fd4927 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -41,7 +41,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.logWithStack; -import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM; import android.annotation.CallSuper; @@ -70,7 +69,6 @@ import android.view.animation.Animation; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ToBooleanFunction; -import com.android.server.policy.WindowManagerPolicy; import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.SurfaceAnimator.Animatable; @@ -2165,15 +2163,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } void waitForAllWindowsDrawn() { - final WindowManagerPolicy policy = mWmService.mPolicy; forAllWindows(w -> { - final boolean keyguard = policy.isKeyguardHostWindow(w.mAttrs); - if (w.isVisibleLw() && (w.mActivityRecord != null || keyguard)) { - w.mWinAnimator.mDrawState = DRAW_PENDING; - // Force add to mResizingWindows. - w.resetLastContentInsets(); - mWaitingForDrawn.add(w); - } + w.requestDrawIfNeeded(mWaitingForDrawn); }, true /* traverseTopToBottom */); } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 6918c966a3ec..2a8de3f95f46 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1726,6 +1726,39 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP && isDrawnLw() && !isAnimating(TRANSITION | PARENTS); } + /** @see WindowManagerInternal#waitForAllWindowsDrawn */ + void requestDrawIfNeeded(List<WindowState> outWaitingForDrawn) { + if (!isVisible()) { + return; + } + if (mActivityRecord != null) { + 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. + return; + } + if (mAttrs.type == TYPE_APPLICATION_STARTING) { + if (isDrawnLw()) { + // Unnecessary to redraw a drawn starting window. + return; + } + } else if (mActivityRecord.startingWindow != null) { + // If the activity has an active starting window, there is no need to wait for the + // main window. + return; + } + } else if (!mPolicy.isKeyguardHostWindow(mAttrs)) { + return; + // Always invalidate keyguard host window to make sure it shows the latest content + // because its visibility may not be changed. + } + + mWinAnimator.mDrawState = DRAW_PENDING; + // Force add to {@link WindowManagerService#mResizingWindows}. + resetLastContentInsets(); + outWaitingForDrawn.add(this); + } + @Override void onMovedByResize() { ProtoLog.d(WM_DEBUG_RESIZE, "onMovedByResize: Moving %s", this); 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 8ade4d27e495..0018c633e675 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -32,7 +32,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; +import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -82,7 +84,9 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; import java.util.LinkedList; +import java.util.List; /** * Tests for the {@link WindowState} class. @@ -532,6 +536,31 @@ public class WindowStateTests extends WindowTestsBase { } @Test + public void testRequestDrawIfNeeded() { + final WindowState startingApp = createWindow(null /* parent */, + TYPE_BASE_APPLICATION, "startingApp"); + final WindowState startingWindow = createWindow(null /* parent */, + TYPE_APPLICATION_STARTING, startingApp.mToken, "starting"); + startingApp.mActivityRecord.startingWindow = startingWindow; + final WindowState keyguardHostWindow = mStatusBarWindow; + final WindowState allDrawnApp = mAppWindow; + allDrawnApp.mActivityRecord.allDrawn = true; + + // The waiting list is used to ensure the content is ready when turning on screen. + final List<WindowState> outWaitingForDrawn = mDisplayContent.mWaitingForDrawn; + final List<WindowState> visibleWindows = Arrays.asList(mChildAppWindowAbove, + keyguardHostWindow, allDrawnApp, startingApp, startingWindow); + visibleWindows.forEach(w -> { + w.mHasSurface = true; + w.requestDrawIfNeeded(outWaitingForDrawn); + }); + + // 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); + } + + @Test public void testGetTransformationMatrix() { final int PARENT_WINDOW_OFFSET = 1; final int DISPLAY_IN_PARENT_WINDOW_OFFSET = 2; |