diff options
3 files changed, 53 insertions, 46 deletions
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 03cae429904f..48da52b8f8d2 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -258,9 +258,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree ActivityRecord mActivityRecord; /** - * See {@link #canTurnScreenOn()} + * @see #currentLaunchCanTurnScreenOn() */ - private boolean mCanTurnScreenOn = true; + private boolean mCurrentLaunchCanTurnScreenOn = true; /** * If we are running an animation, this determines the transition type. Must be one of @@ -985,7 +985,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree + " " + this); mAppStopped = false; // Allow the window to turn the screen on once the app is resumed again. - setCanTurnScreenOn(true); + setCurrentLaunchCanTurnScreenOn(true); if (!wasStopped) { destroySurfaces(true /*cleanupOnResume*/); } @@ -2403,21 +2403,25 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } /** - * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()} + * Sets whether the current launch can turn the screen on. + * @see #currentLaunchCanTurnScreenOn() */ - void setCanTurnScreenOn(boolean canTurnScreenOn) { - mCanTurnScreenOn = canTurnScreenOn; + void setCurrentLaunchCanTurnScreenOn(boolean currentLaunchCanTurnScreenOn) { + mCurrentLaunchCanTurnScreenOn = currentLaunchCanTurnScreenOn; } /** * Indicates whether the current launch can turn the screen on. This is to prevent multiple * relayouts from turning the screen back on. The screen should only turn on at most * once per activity resume. + * <p> + * Note this flag is only meaningful when {@link WindowManager.LayoutParams#FLAG_TURN_SCREEN_ON} + * or {@link ActivityRecord#canTurnScreenOn} is set. * - * @return true if the screen can be turned on. + * @return {@code true} if the activity is ready to turn on the screen. */ - boolean canTurnScreenOn() { - return mCanTurnScreenOn; + boolean currentLaunchCanTurnScreenOn() { + return mCurrentLaunchCanTurnScreenOn; } /** diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index bf874be41c5b..6705f14dfa20 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2381,10 +2381,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void prepareWindowToDisplayDuringRelayout(boolean wasVisible) { // We need to turn on screen regardless of visibility. - boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0; + final boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0 + || (mAppToken != null && mAppToken.mActivityRecord.canTurnScreenOn()); // The screen will turn on if the following conditions are met - // 1. The window has the flag FLAG_TURN_SCREEN_ON + // 1. The window has the flag FLAG_TURN_SCREEN_ON or ActivityRecord#canTurnScreenOn. // 2. The WMS allows theater mode. // 3. No AWT or the AWT allows the screen to be turned on. This should only be true once // per resume to prevent the screen getting getting turned on for each relayout. Set @@ -2398,7 +2399,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP boolean allowTheaterMode = mWmService.mAllowTheaterModeWakeFromLayout || Settings.Global.getInt(mWmService.mContext.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0) == 0; - boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn(); + boolean canTurnScreenOn = mAppToken == null || mAppToken.currentLaunchCanTurnScreenOn(); if (allowTheaterMode && canTurnScreenOn && !mPowerManagerWrapper.isInteractive()) { if (DEBUG_VISIBILITY || DEBUG_POWER) { @@ -2409,7 +2410,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } if (mAppToken != null) { - mAppToken.setCanTurnScreenOn(false); + mAppToken.setCurrentLaunchCanTurnScreenOn(false); } } 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 1b57c7924ecb..36698eae274c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -302,43 +302,38 @@ public class WindowStateTests extends WindowTestsBase { @Test public void testPrepareWindowToDisplayDuringRelayout() { - testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/); - testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/); - - // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON - // before calling prepareWindowToDisplayDuringRelayout for windows with flag in the same - // appWindowToken. + // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before + // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same appWindowToken. final AppWindowToken appWindowToken = createAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); final WindowState first = createWindow(null, TYPE_APPLICATION, appWindowToken, "first"); final WindowState second = createWindow(null, TYPE_APPLICATION, appWindowToken, "second"); second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; - reset(sPowerManagerWrapper); - first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/); - verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString()); - assertTrue(appWindowToken.canTurnScreenOn()); - - reset(sPowerManagerWrapper); - second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/); - verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString()); - assertFalse(appWindowToken.canTurnScreenOn()); + testPrepareWindowToDisplayDuringRelayout(first, false /* expectedWakeupCalled */, + true /* expectedCurrentLaunchCanTurnScreenOn */); + testPrepareWindowToDisplayDuringRelayout(second, true /* expectedWakeupCalled */, + false /* expectedCurrentLaunchCanTurnScreenOn */); // Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON // from the same appWindowToken. Only one should trigger the wakeup. - appWindowToken.setCanTurnScreenOn(true); + appWindowToken.setCurrentLaunchCanTurnScreenOn(true); first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; - reset(sPowerManagerWrapper); - first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/); - verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString()); - assertFalse(appWindowToken.canTurnScreenOn()); + testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */, + false /* expectedCurrentLaunchCanTurnScreenOn */); + testPrepareWindowToDisplayDuringRelayout(second, false /* expectedWakeupCalled */, + false /* expectedCurrentLaunchCanTurnScreenOn */); - reset(sPowerManagerWrapper); - second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/); - verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString()); - assertFalse(appWindowToken.canTurnScreenOn()); + // Without window flags, the state of ActivityRecord.canTurnScreenOn should still be able to + // turn on the screen. + appWindowToken.setCurrentLaunchCanTurnScreenOn(true); + first.mAttrs.flags &= ~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; + doReturn(true).when(appWindowToken.mActivityRecord).canTurnScreenOn(); + + testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */, + false /* expectedCurrentLaunchCanTurnScreenOn */); // Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an // appWindowToken. Both windows have the FLAG_TURNS_SCREEN_ON so both should call wakeup @@ -360,6 +355,22 @@ public class WindowStateTests extends WindowTestsBase { verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString()); } + private void testPrepareWindowToDisplayDuringRelayout(WindowState appWindow, + boolean expectedWakeupCalled, boolean expectedCurrentLaunchCanTurnScreenOn) { + reset(sPowerManagerWrapper); + appWindow.prepareWindowToDisplayDuringRelayout(false /* wasVisible */); + + if (expectedWakeupCalled) { + verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString()); + } else { + verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString()); + } + // If wakeup is expected to be called, the currentLaunchCanTurnScreenOn should be false + // because the state will be consumed. + assertThat(appWindow.mAppToken.currentLaunchCanTurnScreenOn(), + is(expectedCurrentLaunchCanTurnScreenOn)); + } + @Test public void testCanAffectSystemUiFlags() { final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); @@ -487,15 +498,6 @@ public class WindowStateTests extends WindowTestsBase { assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20))); } - private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) { - reset(sPowerManagerWrapper); - final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); - root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; - - root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/); - verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString()); - } - @Test public void testVisibilityChangeSwitchUser() { final WindowState window = createWindow(null, TYPE_APPLICATION, "app"); |