Merge "Wait for system decor windows on all displays during boot"
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user