diff options
5 files changed, 62 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index d9ee9a306f07..13dc0b9be21f 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -710,9 +710,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } - private void initialize() { + private void initialize(int displayState) { mPowerState = new DisplayPowerState(mBlanker, - mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId); + mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId, displayState); if (mColorFadeEnabled) { mColorFadeOnAnimator = ObjectAnimator.ofFloat( @@ -812,11 +812,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mustNotify = !mDisplayReadyLocked; } - // Initialize things the first time the power state is changed. - if (mustInitialize) { - initialize(); - } - // Compute the basic display state using the policy. // We might override this below based on other factors. // Initialise brightness as invalid. @@ -850,6 +845,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } assert(state != Display.STATE_UNKNOWN); + // Initialize things the first time the power state is changed. + if (mustInitialize) { + initialize(state); + } + // Apply the proximity sensor. if (mProximitySensor != null) { if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) { diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java index 54f30a954c33..173adce00cd9 100644 --- a/services/core/java/com/android/server/display/DisplayPowerState.java +++ b/services/core/java/com/android/server/display/DisplayPowerState.java @@ -72,7 +72,8 @@ final class DisplayPowerState { private Runnable mCleanListener; - public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, int displayId) { + DisplayPowerState( + DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState) { mHandler = new Handler(true /*async*/); mChoreographer = Choreographer.getInstance(); mBlanker = blanker; @@ -81,14 +82,14 @@ final class DisplayPowerState { mPhotonicModulator.start(); mDisplayId = displayId; - // At boot time, we know that the screen is on and the electron beam - // animation is not playing. We don't know the screen's brightness though, + // At boot time, we don't know the screen's brightness, // so prepare to set it to a known state when the state is next applied. - // Although we set the brightness to full on here, the display power controller + // Although we set the brightness here, the display power controller // will reset the brightness to a new level immediately before the changes // actually have a chance to be applied. - mScreenState = Display.STATE_ON; - mScreenBrightness = PowerManager.BRIGHTNESS_MAX; + mScreenState = displayState; + mScreenBrightness = (displayState != Display.STATE_OFF) ? PowerManager.BRIGHTNESS_MAX + : PowerManager.BRIGHTNESS_OFF_FLOAT; scheduleScreenUpdate(); mColorFadePrepared = false; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index c073b430c8df..89e7986fc4bc 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -3491,15 +3491,27 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ @Override public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { + final int keyCode = event.getKeyCode(); + final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; + boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 + || event.isWakeKey(); + if (!mSystemBooted) { // If we have not yet booted, don't let key events do anything. + // Exception: Wake and power key events are forwarded to PowerManager to allow it to + // wake from quiescent mode during boot. + if (down && (keyCode == KeyEvent.KEYCODE_POWER + || keyCode == KeyEvent.KEYCODE_TV_POWER)) { + wakeUpFromPowerKey(event.getDownTime()); + } else if (down && (isWakeKey || keyCode == KeyEvent.KEYCODE_WAKEUP) + && isWakeKeyWhenScreenOff(keyCode)) { + wakeUpFromWakeKey(event); + } return 0; } final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; - final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; final boolean canceled = event.isCanceled(); - final int keyCode = event.getKeyCode(); final int displayId = event.getDisplayId(); final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0; @@ -3518,8 +3530,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Basic policy based on interactive state. int result; - boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 - || event.isWakeKey(); if (interactive || (isInjected && !isWakeKey)) { // When the device is interactive or the key is injected pass the // key to the application. @@ -4740,7 +4750,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN); finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN); - screenTurningOn(DEFAULT_DISPLAY, null); + screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener()); screenTurnedOn(DEFAULT_DISPLAY); } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 54d05124c114..db4b6d0a3005 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -1036,12 +1036,12 @@ public final class PowerManagerService extends SystemService userActivityNoUpdateLocked( now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); + updatePowerStateLocked(); if (sQuiescent) { goToSleepNoUpdateLocked(mClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_QUIESCENT, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID); } - updatePowerStateLocked(); } } } @@ -1679,8 +1679,15 @@ public final class PowerManagerService extends SystemService Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid); } - if (eventTime < mLastSleepTime || getWakefulnessLocked() == WAKEFULNESS_AWAKE - || mForceSuspendActive || !mSystemReady) { + if (eventTime < mLastSleepTime || mForceSuspendActive || !mSystemReady) { + return false; + } + + if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) { + if (!mBootCompleted && sQuiescent) { + mDirty |= DIRTY_QUIESCENT; + return true; + } return false; } @@ -2821,7 +2828,7 @@ public final class PowerManagerService extends SystemService * * This function recalculates the display power state each time. * - * @return True if the display became ready. + * @return true if the display became ready. */ private boolean updateDisplayPowerStateLocked(int dirty) { final boolean oldDisplayReady = mDisplayReady; @@ -2830,7 +2837,11 @@ public final class PowerManagerService extends SystemService | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED | DIRTY_QUIESCENT)) != 0) { if ((dirty & DIRTY_QUIESCENT) != 0) { - sQuiescent = false; + if (mDisplayReady) { + sQuiescent = false; + } else { + mDirty |= DIRTY_QUIESCENT; + } } final DisplayPowerRequest displayPowerRequest = mDisplayPowerRequestMapper.get( @@ -5605,7 +5616,7 @@ public final class PowerManagerService extends SystemService * ignore the proximity sensor. We don't turn off the proximity sensor because * we still want it to be reenabled if it's state changes. * - * @return True if the proximity sensor was successfully ignored and we should + * @return true if the proximity sensor was successfully ignored and we should * consume the key event. */ private boolean interceptPowerKeyDownInternal(KeyEvent event) { diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java index 533dc1708896..1d0b595d8fc1 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -877,6 +877,22 @@ public class PowerManagerServiceTest { } @Test + public void testQuiescentBoot_WakeKeyBeforeBootCompleted_AwakeAfterBootCompleted() + throws Exception { + when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), any())).thenReturn("1"); + createService(); + mService.systemReady(null); + + mService.getBinderServiceInstance().wakeUp(mClock.now(), + PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name"); + + mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); + assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo( + DisplayPowerRequest.POLICY_BRIGHT); + } + + @Test public void testIsAmbientDisplayAvailable_available() throws Exception { createService(); when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true); |