summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Robert Horvath <robhor@google.com> 2021-02-02 11:46:22 +0100
committer Robert Horvath <robhor@google.com> 2021-04-09 13:31:15 +0200
commite2b48d25a0a5fa9f412d4536d7ddfd320b9b0f14 (patch)
tree341c6a250506564672ee3a750284e1e2d30c85f3
parent397cb14bd3201e44e8ddf38592a637d6547c26ec (diff)
On quiescent boot, report screenTurningOff, skip screenTurningOn
Fixes an issue where ActivityStacks were resumed while the screen was off and PowerManager wakefulness was asleep after a quiescent boot. To keep ActivityStacks paused, PhoneWindowManager acquires a "sleep token". In #screenTurningOff, this token is acquired, and in #screenTurningOn it is released. Before, PhoneWindowManager#systemBooted always called #screenTurningOn. In a quiescent boot, this led to the sleep token being released and ActivityStacks being resumed, even though the screen did not actually turn on. With this change, DisplayPowerController calls #screenTurningOff during a quiescent boot, acquiring the sleep token, and #systemBooted skips calling #screenTurningOn, preventing the sleep token from being released again. To finish up boot, #enableScreen is called (last part of #finishScreenTurningOn), which stops the boot animation process, signals SurfaceFlinger and ActivityManager that boot has completed. Bug: 171827143 Test: atest QuiescentBootTests#testQuiescentBoot_activitiesNotResumedAfterBoot Test: adb reboot quiescent adb shell dumpsys power: Verify wakefulness asleep adb shell dumpsys activity activities: Verify stack is sleeping (isSleeping=true), state is STOPPED (state=STOPPED) Change-Id: Ieb0b805c33b3da4261856b724f32412c2660f4c9
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java17
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java45
2 files changed, 45 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index cb8541eb5e94..5cd0534c8e93 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -140,6 +140,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private static final int RAMP_STATE_SKIP_INITIAL = 1;
private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
+ private static final int REPORTED_TO_POLICY_UNREPORTED = -1;
private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
@@ -311,8 +312,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private long mScreenOnBlockStartRealTime;
private long mScreenOffBlockStartRealTime;
- // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
- private int mReportedScreenStateToPolicy;
+ // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields.
+ private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED;
// If the last recorded screen state was dozing or not.
private boolean mDozing;
@@ -1440,12 +1441,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private boolean setScreenState(int state, boolean reportOnly) {
final boolean isOff = (state == Display.STATE_OFF);
- if (mPowerState.getScreenState() != state) {
+ if (mPowerState.getScreenState() != state
+ || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
// If we are trying to turn screen off, give policy a chance to do something before we
// actually turn the screen off.
if (isOff && !mScreenOffBecauseOfProximity) {
- if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
+ if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON
+ || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
blockScreenOff();
mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker);
@@ -1456,7 +1459,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
- if (!reportOnly) {
+ if (!reportOnly && mPowerState.getScreenState() != state) {
Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
// TODO(b/153319140) remove when we can get this from the above trace invocation
SystemProperties.set("debug.tracing.screen_state", String.valueOf(state));
@@ -1486,7 +1489,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mWindowManagerPolicy.screenTurnedOff(mDisplayId);
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
}
- if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
+ if (!isOff
+ && (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF
+ || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
if (mPowerState.getColorFadeLevel() == 0.0f) {
blockScreenOn();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c7789eecc68f..45e6cdce768b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -405,6 +405,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private boolean mEnableCarDockHomeCapture = true;
boolean mBootMessageNeedsHiding;
+ volatile boolean mBootAnimationDismissable;
private KeyguardServiceDelegate mKeyguardDelegate;
private boolean mKeyguardBound;
final Runnable mWindowManagerDrawCallback = new Runnable() {
@@ -4305,6 +4306,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
0 /* cookie */);
updateScreenOffSleepToken(false);
mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
+ mBootAnimationDismissable = false;
synchronized (mLock) {
if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
@@ -4379,6 +4381,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */);
+ enableScreen(listener, true /* report */);
+ }
+
+ private void enableScreen(ScreenOnListener listener, boolean report) {
final boolean enableScreen;
final boolean awake = mDefaultDisplayPolicy.isAwake();
synchronized (mLock) {
@@ -4396,17 +4402,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- if (listener != null) {
- listener.onScreenOn();
- }
+ if (report) {
+ if (listener != null) {
+ listener.onScreenOn();
+ }
- for (int i = mScreenOnListeners.size() - 1; i >= 0; i--) {
- final ScreenOnListener screenOnListener = mScreenOnListeners.valueAt(i);
- if (screenOnListener != null) {
- screenOnListener.onScreenOn();
+ for (int i = mScreenOnListeners.size() - 1; i >= 0; i--) {
+ final ScreenOnListener screenOnListener = mScreenOnListeners.valueAt(i);
+ if (screenOnListener != null) {
+ screenOnListener.onScreenOn();
+ }
}
+ mScreenOnListeners.clear();
}
- mScreenOnListeners.clear();
if (enableScreen) {
try {
@@ -4614,13 +4622,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
- screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener());
- screenTurnedOn(DEFAULT_DISPLAY);
+
+ int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState();
+ boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON;
+ boolean defaultScreenTurningOn = mDefaultDisplayPolicy.getScreenOnListener() != null;
+ if (defaultDisplayOn || defaultScreenTurningOn) {
+ // Now that system is booted, wait for keyguard and windows to be drawn before
+ // updating the orientation listener, stopping the boot animation and enabling screen.
+ screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener());
+ screenTurnedOn(DEFAULT_DISPLAY);
+ } else {
+ // We're not turning the screen on, so don't wait for keyguard to be drawn
+ // to dismiss the boot animation and finish booting
+ mBootAnimationDismissable = true;
+ enableScreen(null, false /* report */);
+ }
}
@Override
public boolean canDismissBootAnimation() {
- return mDefaultDisplayPolicy.isKeyguardDrawComplete();
+ // Allow to dismiss the boot animation if the keyguard has finished drawing,
+ // or mBootAnimationDismissable has been set
+ return mDefaultDisplayPolicy.isKeyguardDrawComplete() || mBootAnimationDismissable;
}
ProgressDialog mBootMsgDialog = null;