Merge "Fix setCanTurnScreenOn for a launching activity"

This commit is contained in:
TreeHugger Robot
2019-07-16 22:20:17 +00:00
committed by Android (Google) Code Review
3 changed files with 53 additions and 46 deletions

View File

@@ -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
@@ -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*/);
}
@@ -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;
}
/**

View File

@@ -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
@@ -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) {
@@ -2421,7 +2422,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
if (mAppToken != null) {
mAppToken.setCanTurnScreenOn(false);
mAppToken.setCurrentLaunchCanTurnScreenOn(false);
}
}

View File

@@ -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");