diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 6fafa9f7360d5..6d9a00804e320 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -59,11 +59,10 @@ import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE; import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; +import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; -import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; @@ -169,6 +168,7 @@ import android.os.UserHandle; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.Slog; +import android.util.SparseBooleanArray; import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.DisplayCutout; @@ -439,11 +439,6 @@ class DisplayContent extends WindowContainer mTapExcludeProvidingWindows = new ArraySet<>(); - private boolean mHaveBootMsg = false; - private boolean mHaveApp = false; - private boolean mHaveWallpaper = false; - private boolean mHaveKeyguard = true; - private final LinkedList mTmpUpdateAllDrawn = new LinkedList(); private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult = @@ -3350,34 +3345,38 @@ class DisplayContent extends WindowContainer { - if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) { + final WindowState visibleNotDrawnWindow = getWindow(w -> { + if (w.mViewVisibility == View.VISIBLE && !w.mObscured && !w.isDrawnLw()) { return true; } if (w.isDrawnLw()) { - if (w.mAttrs.type == TYPE_BOOT_PROGRESS) { - mHaveBootMsg = true; - } else if (w.mAttrs.type == TYPE_APPLICATION - || w.mAttrs.type == TYPE_DRAWN_APPLICATION) { - mHaveApp = true; - } else if (w.mAttrs.type == TYPE_WALLPAPER) { - mHaveWallpaper = true; - } else if (w.mAttrs.type == TYPE_STATUS_BAR) { - mHaveKeyguard = mWmService.mPolicy.isKeyguardDrawnLw(); + final int type = w.mAttrs.type; + if (type == TYPE_BOOT_PROGRESS || type == TYPE_BASE_APPLICATION + || type == TYPE_WALLPAPER) { + drawnWindowTypes.put(type, true); + } else if (type == TYPE_STATUS_BAR) { + drawnWindowTypes.put(TYPE_STATUS_BAR, mWmService.mPolicy.isKeyguardDrawnLw()); } } return false; }); - if (visibleWindow != null) { - // We have a visible window. + if (visibleNotDrawnWindow != null) { + // Wait for the visible window to be drawn. return true; } @@ -3389,22 +3388,27 @@ class DisplayContent extends WindowContainer= 0; i--) { + if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) { + return; + } + } } if (!mBootAnimationStopped) { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index ae4074275b97a..ade0b146dd9aa 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -39,6 +39,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; +import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; @@ -46,6 +47,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; import static com.android.dx.mockito.inline.extended.ExtendedMockito.same; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; @@ -396,6 +398,59 @@ public class DisplayContentTests extends WindowTestsBase { mWm.mRoot.getTopFocusedDisplayContent().getDisplayId()); } + @Test + public void testShouldWaitForSystemDecorWindowsOnBoot_OnDefaultDisplay() { + mWm.mSystemBooted = true; + final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked(); + final WindowState[] windows = createNotDrawnWindowsOn(defaultDisplay, + TYPE_WALLPAPER, TYPE_APPLICATION); + + // Verify waiting for windows to be drawn. + assertTrue(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot()); + + // Verify not waiting for drawn windows. + makeWindowsDrawn(windows); + assertFalse(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot()); + } + + @Test + public void testShouldWaitForSystemDecorWindowsOnBoot_OnSecondaryDisplay() { + mWm.mSystemBooted = true; + final DisplayContent secondaryDisplay = createNewDisplay(); + final WindowState[] windows = createNotDrawnWindowsOn(secondaryDisplay, + TYPE_WALLPAPER, TYPE_APPLICATION); + + // Verify not waiting for display without system decorations. + doReturn(false).when(secondaryDisplay).supportsSystemDecorations(); + assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot()); + + // Verify waiting for non-drawn windows on display with system decorations. + reset(secondaryDisplay); + doReturn(true).when(secondaryDisplay).supportsSystemDecorations(); + assertTrue(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot()); + + // Verify not waiting for drawn windows on display with system decorations. + makeWindowsDrawn(windows); + assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot()); + } + + private WindowState[] createNotDrawnWindowsOn(DisplayContent displayContent, int... types) { + final WindowState[] windows = new WindowState[types.length]; + for (int i = 0; i < types.length; i++) { + final int type = types[i]; + windows[i] = createWindow(null /* parent */, type, displayContent, "window-" + type); + windows[i].mHasSurface = false; + } + return windows; + } + + private static void makeWindowsDrawn(WindowState[] windows) { + for (WindowState window : windows) { + window.mHasSurface = true; + window.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN; + } + } + /** * This tests setting the maximum ui width on a display. */