@@ -271,6 +271,12 @@ final class DisplayPowerController {
271271 // When the screen turns on again, we report user activity to the power manager.
272272 private boolean mScreenOffBecauseOfProximity ;
273273
274+ // True if the screen on is being blocked.
275+ private boolean mScreenOnWasBlocked ;
276+
277+ // The elapsed real time when the screen on was blocked.
278+ private long mScreenOnBlockStartRealTime ;
279+
274280 // Set to true if the light sensor is enabled.
275281 private boolean mLightSensorEnabled ;
276282
@@ -513,7 +519,7 @@ private void initialize() {
513519 final Executor executor = AsyncTask .THREAD_POOL_EXECUTOR ;
514520 Display display = mDisplayManager .getDisplay (Display .DEFAULT_DISPLAY );
515521 mPowerState = new DisplayPowerState (
516- mElectronBeamAnimatesBacklightConfig ? null : new ElectronBeam (display ),
522+ new ElectronBeam (display ),
517523 new PhotonicModulator (executor ,
518524 mLights .getLight (LightsService .LIGHT_ID_BACKLIGHT ),
519525 mSuspendBlocker ));
@@ -553,7 +559,6 @@ private void updatePowerState() {
553559 final boolean mustNotify ;
554560 boolean mustInitialize = false ;
555561 boolean updateAutoBrightness = mTwilightChanged ;
556- boolean screenOnWasBlocked = false ;
557562 mTwilightChanged = false ;
558563
559564 synchronized (mLock ) {
@@ -662,18 +667,24 @@ private void updatePowerState() {
662667 // It is relatively short but if we cancel it and switch to the
663668 // on animation immediately then the results are pretty ugly.
664669 if (!mElectronBeamOffAnimator .isStarted ()) {
665- if (mPowerRequest .blockScreenOn && !mPowerState .isScreenOn ()) {
666- if (DEBUG ) {
667- Slog .d (TAG , "Blocked screen on while screen currently off." );
668- }
669- screenOnWasBlocked = true ;
670+ // Turn the screen on. The contents of the screen may not yet
671+ // be visible if the electron beam has not been dismissed because
672+ // its last frame of animation is solid black.
673+ setScreenOn (true );
674+
675+ if (mPowerRequest .blockScreenOn
676+ && mPowerState .getElectronBeamLevel () == 0.0f ) {
677+ blockScreenOn ();
670678 } else {
671- setScreenOn ( true );
679+ unblockScreenOn ( );
672680 if (USE_ELECTRON_BEAM_ON_ANIMATION ) {
673681 if (!mElectronBeamOnAnimator .isStarted ()) {
674682 if (mPowerState .getElectronBeamLevel () == 1.0f ) {
675683 mPowerState .dismissElectronBeam ();
676- } else if (mPowerState .prepareElectronBeam (true )) {
684+ } else if (mPowerState .prepareElectronBeam (
685+ mElectronBeamAnimatesBacklightConfig ?
686+ ElectronBeam .MODE_BLANK :
687+ ElectronBeam .MODE_WARM_UP )) {
677688 mElectronBeamOnAnimator .start ();
678689 } else {
679690 mElectronBeamOnAnimator .end ();
@@ -684,22 +695,6 @@ private void updatePowerState() {
684695 mPowerState .dismissElectronBeam ();
685696 }
686697 }
687- } else {
688- // FIXME: If the electron beam off animation is playing then we have a bit
689- // of a problem. The window manager policy would only have requested
690- // to block screen on if it was about to start preparing the keyguard.
691- // It's already too late to do anything about that. Ideally we would
692- // let the animation play out first but that would require making
693- // some pretty deep changes to the power manager and we don't have
694- // time just now. For now, short-circuit the animation and get ready.
695- if (mPowerRequest .blockScreenOn ) {
696- if (DEBUG ) {
697- Slog .d (TAG , "Blocked screen on while screen off animation running." );
698- }
699- screenOnWasBlocked = true ;
700- setScreenOn (false );
701- mElectronBeamOffAnimator .end ();
702- }
703698 }
704699 } else {
705700 // Want screen off.
@@ -708,7 +703,10 @@ private void updatePowerState() {
708703 if (!mElectronBeamOffAnimator .isStarted ()) {
709704 if (mPowerState .getElectronBeamLevel () == 0.0f ) {
710705 setScreenOn (false );
711- } else if (mPowerState .prepareElectronBeam (false )
706+ } else if (mPowerState .prepareElectronBeam (
707+ mElectronBeamAnimatesBacklightConfig ?
708+ ElectronBeam .MODE_BLANK :
709+ ElectronBeam .MODE_COOL_DOWN )
712710 && mPowerState .isScreenOn ()) {
713711 mElectronBeamOffAnimator .start ();
714712 } else {
@@ -723,7 +721,7 @@ private void updatePowerState() {
723721 // We mostly care about the screen state here, ignoring brightness changes
724722 // which will be handled asynchronously.
725723 if (mustNotify
726- && !screenOnWasBlocked
724+ && !mScreenOnWasBlocked
727725 && !mElectronBeamOnAnimator .isStarted ()
728726 && !mElectronBeamOffAnimator .isStarted ()
729727 && mPowerState .waitUntilClean (mCleanListener )) {
@@ -740,6 +738,26 @@ private void updatePowerState() {
740738 }
741739 }
742740
741+ private void blockScreenOn () {
742+ if (!mScreenOnWasBlocked ) {
743+ mScreenOnWasBlocked = true ;
744+ if (DEBUG ) {
745+ Slog .d (TAG , "Blocked screen on." );
746+ mScreenOnBlockStartRealTime = SystemClock .elapsedRealtime ();
747+ }
748+ }
749+ }
750+
751+ private void unblockScreenOn () {
752+ if (mScreenOnWasBlocked ) {
753+ mScreenOnWasBlocked = false ;
754+ if (DEBUG ) {
755+ Slog .d (TAG , "Unblocked screen on after " +
756+ (SystemClock .elapsedRealtime () - mScreenOnBlockStartRealTime ) + " ms" );
757+ }
758+ }
759+ }
760+
743761 private void setScreenOn (boolean on ) {
744762 if (!mPowerState .isScreenOn () == on ) {
745763 mPowerState .setScreenOn (on );
0 commit comments