Loading services/core/java/com/android/server/wm/AppWindowToken.java +13 −9 Original line number Diff line number Diff line Loading @@ -260,9 +260,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 Loading Loading @@ -1002,7 +1002,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*/); } Loading Loading @@ -2420,21 +2420,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; } /** Loading services/core/java/com/android/server/wm/WindowState.java +5 −4 Original line number Diff line number Diff line Loading @@ -2393,10 +2393,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 Loading @@ -2410,7 +2411,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) { Loading @@ -2421,7 +2422,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } if (mAppToken != null) { mAppToken.setCanTurnScreenOn(false); mAppToken.setCurrentLaunchCanTurnScreenOn(false); } } Loading services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +35 −33 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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"); Loading Loading @@ -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"); Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +13 −9 Original line number Diff line number Diff line Loading @@ -260,9 +260,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 Loading Loading @@ -1002,7 +1002,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*/); } Loading Loading @@ -2420,21 +2420,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; } /** Loading
services/core/java/com/android/server/wm/WindowState.java +5 −4 Original line number Diff line number Diff line Loading @@ -2393,10 +2393,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 Loading @@ -2410,7 +2411,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) { Loading @@ -2421,7 +2422,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } if (mAppToken != null) { mAppToken.setCanTurnScreenOn(false); mAppToken.setCurrentLaunchCanTurnScreenOn(false); } } Loading
services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +35 −33 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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"); Loading Loading @@ -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"); Loading