diff options
3 files changed, 96 insertions, 35 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 6fafa9f7360d..6d9a00804e32 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<DisplayContent.DisplayChildWindowCo /** A collection of windows that provide tap exclude regions inside of them. */ final ArraySet<WindowState> mTapExcludeProvidingWindows = new ArraySet<>(); - private boolean mHaveBootMsg = false; - private boolean mHaveApp = false; - private boolean mHaveWallpaper = false; - private boolean mHaveKeyguard = true; - private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList(); private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult = @@ -3350,34 +3345,38 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo }, true /* traverseTopToBottom */); } - boolean checkWaitingForWindows() { + /** @return {@code true} if there is window to wait before enabling the screen. */ + boolean shouldWaitForSystemDecorWindowsOnBoot() { + if (!isDefaultDisplay && !supportsSystemDecorations()) { + // Nothing to wait because the secondary display doesn't support system decorations, + // there is no wallpaper, keyguard (status bar) or application (home) window to show + // during booting. + return false; + } - mHaveBootMsg = false; - mHaveApp = false; - mHaveWallpaper = false; - mHaveKeyguard = true; + final SparseBooleanArray drawnWindowTypes = new SparseBooleanArray(); + // Presuppose keyguard is drawn because if its window isn't attached, we don't know if it + // wants to be shown or hidden, then it should not delay enabling the screen. + drawnWindowTypes.put(TYPE_STATUS_BAR, true); - final WindowState visibleWindow = getWindow(w -> { - 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<DisplayContent.DisplayChildWindowCo com.android.internal.R.bool.config_checkWallpaperAtBoot) && !mWmService.mOnlyCore; + final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS); + final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION); + final boolean haveWallpaper = drawnWindowTypes.get(TYPE_WALLPAPER); + final boolean haveKeyguard = drawnWindowTypes.get(TYPE_STATUS_BAR); + ProtoLog.i(WM_DEBUG_SCREEN_ON, - "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b " - + "wallEnabled=%b haveKeyguard=%b", - mWmService.mSystemBooted, mWmService.mShowingBootMessages, mHaveBootMsg, - mHaveApp, mHaveWallpaper, wallpaperEnabled, mHaveKeyguard); + "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b " + + "wallEnabled=%b haveKeyguard=%b", + mWmService.mSystemBooted, mWmService.mShowingBootMessages, haveBootMsg, + haveApp, haveWallpaper, wallpaperEnabled, haveKeyguard); // If we are turning on the screen to show the boot message, don't do it until the boot // message is actually displayed. - if (!mWmService.mSystemBooted && !mHaveBootMsg) { + if (!mWmService.mSystemBooted && !haveBootMsg) { return true; } // If we are turning on the screen after the boot is completed normally, don't do so until // we have the application and wallpaper. if (mWmService.mSystemBooted - && ((!mHaveApp && !mHaveKeyguard) || (wallpaperEnabled && !mHaveWallpaper))) { + && ((!haveApp && !haveKeyguard) || (wallpaperEnabled && !haveWallpaper))) { return true; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 38a22389d529..29c5a1ae913c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3290,10 +3290,12 @@ public class WindowManagerService extends IWindowManager.Stub } // Don't enable the screen until all existing windows have been drawn. - if (!mForceDisplayEnabled - // TODO(multidisplay): Expand to all displays? - && getDefaultDisplayContentLocked().checkWaitingForWindows()) { - return; + if (!mForceDisplayEnabled) { + for (int i = mRoot.getChildCount() - 1; i >= 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 ae4074275b97..ade0b146dd9a 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. */ |