diff options
| author | 2021-02-02 11:46:22 +0100 | |
|---|---|---|
| committer | 2021-04-09 13:31:15 +0200 | |
| commit | e2b48d25a0a5fa9f412d4536d7ddfd320b9b0f14 (patch) | |
| tree | 341c6a250506564672ee3a750284e1e2d30c85f3 | |
| parent | 397cb14bd3201e44e8ddf38592a637d6547c26ec (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.java | 17 | ||||
| -rw-r--r-- | services/core/java/com/android/server/policy/PhoneWindowManager.java | 45 |
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; |