Merge "Wait for system decor windows on all displays during boot"

This commit is contained in:
Riddle Hsu
2019-10-03 14:05:57 +00:00
committed by Android (Google) Code Review
3 changed files with 96 additions and 35 deletions

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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.
*/