diff options
| author | 2011-09-21 10:55:12 -0700 | |
|---|---|---|
| committer | 2011-09-21 13:15:02 -0700 | |
| commit | beae3bd6d34472d27ac5698f8d9bcbc12d0cf4f0 (patch) | |
| tree | cc0e7eeb8aa6d53c11412a31bb506e6d5fb274f1 | |
| parent | a80599f5be394edd9f3918ba03c490850a1d9e7f (diff) | |
Improvements to power manager turning on screen.
The keyguard/window manager recently got a facility to report when it is
okay to turn the screen on, when it knows the lock screen is displayed.
The power manager was using this wrong, just using it to drive the
flags given to the input system. Duh.
This change now uses the information to determine when to turn the screen
brightness up from 0. For an OLED screen, this is the time when the
user can actually see anything on the screen.
For LCD screens this may not be optimal, because the LCD may start running
before its backlight is turned on, so if you look carefully you may see
stuff before it is lit up. On the other hand, it is good to turn on the
display as early as possible (before waiting for the keyguard) because it
can take a little bit of time to get that and the touch screen going. By
only waiting on the display brightness, we allow turning on the screen
in the kernel to proceed in parallel with ensuring the keyguard is displayed.
Change-Id: I7ee4ce19fd4efd5b51872b855af6263f53cd6c30
| -rw-r--r-- | services/java/com/android/server/PowerManagerService.java | 128 |
1 files changed, 97 insertions, 31 deletions
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 0934cd02f8bd..785db9829992 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -79,6 +79,8 @@ public class PowerManagerService extends IPowerManager.Stub private static final String TAG = "PowerManagerService"; static final String PARTIAL_NAME = "PowerManagerService"; + static final boolean DEBUG_SCREEN_ON = false; + private static final boolean LOG_PARTIAL_WL = false; // Indicates whether touch-down cycles should be logged as part of the @@ -162,6 +164,8 @@ public class PowerManagerService extends IPowerManager.Stub private final int[] mBroadcastQueue = new int[] { -1, -1, -1 }; private final int[] mBroadcastWhy = new int[3]; private boolean mPreparingForScreenOn = false; + private boolean mSkippedScreenOn = false; + private boolean mInitialized = false; private int mPartialCount = 0; private int mPowerState; // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER, @@ -557,6 +561,9 @@ public class PowerManagerService extends IPowerManager.Stub nativeInit(); synchronized (mLocks) { updateNativePowerStateLocked(); + // We make sure to start out with the screen on due to user activity. + // (They did just boot their device, after all.) + forceUserActivityLocked(); } } @@ -1123,7 +1130,8 @@ public class PowerManagerService extends IPowerManager.Stub + " " + ((mNextTimeout-now)/1000) + "s from now"); pw.println(" mDimScreen=" + mDimScreen + " mStayOnConditions=" + mStayOnConditions - + " mPreparingForScreenOn=" + mPreparingForScreenOn); + + " mPreparingForScreenOn=" + mPreparingForScreenOn + + " mSkippedScreenOn=" + mSkippedScreenOn); pw.println(" mScreenOffReason=" + mScreenOffReason + " mUserState=" + mUserState); pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1] @@ -1312,8 +1320,16 @@ public class PowerManagerService extends IPowerManager.Stub } } - private void sendNotificationLocked(boolean on, int why) - { + private void sendNotificationLocked(boolean on, int why) { + if (!mInitialized) { + // No notifications sent until first initialization is done. + // This is so that when we are moving from our initial state + // which looks like the screen was off to it being on, we do not + // go through the process of waiting for the higher-level user + // space to be ready before turning up the display brightness. + // (And also do not send needless broadcasts about the screen.) + return; + } if (!on) { mStillNeedSleepNotification = false; } @@ -1360,7 +1376,9 @@ public class PowerManagerService extends IPowerManager.Stub // The broadcast queue has changed; make sure the screen is on if it // is now possible for it to be. - updateNativePowerStateLocked(); + if (mSkippedScreenOn) { + updateLightsLocked(mPowerState, SCREEN_ON_BIT); + } // Now send the message. if (index >= 0) { @@ -1380,7 +1398,7 @@ public class PowerManagerService extends IPowerManager.Stub synchronized (mLocks) { if (mPreparingForScreenOn) { mPreparingForScreenOn = false; - updateNativePowerStateLocked(); + updateLightsLocked(mPowerState, SCREEN_ON_BIT); EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 4, mBroadcastWakeLock.mCount); mBroadcastWakeLock.release(); @@ -1453,7 +1471,7 @@ public class PowerManagerService extends IPowerManager.Stub synchronized (mLocks) { EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, mBroadcastWakeLock.mCount); - updateNativePowerStateLocked(); + updateLightsLocked(mPowerState, SCREEN_ON_BIT); mBroadcastWakeLock.release(); } } @@ -1646,6 +1664,11 @@ public class PowerManagerService extends IPowerManager.Stub }; private int setScreenStateLocked(boolean on) { + if (DEBUG_SCREEN_ON) { + RuntimeException e = new RuntimeException("here"); + e.fillInStackTrace(); + Slog.i(TAG, "Set screen state: " + on, e); + } int err = Power.setScreenState(on); if (err == 0) { mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0); @@ -1696,7 +1719,7 @@ public class PowerManagerService extends IPowerManager.Stub } else { newState &= ~BATTERY_LOW_BIT; } - if (newState == mPowerState) { + if (newState == mPowerState && mInitialized) { return; } @@ -1722,10 +1745,7 @@ public class PowerManagerService extends IPowerManager.Stub + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0)); } - if (mPowerState != newState) { - updateLightsLocked(newState, 0); - mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK); - } + final boolean stateChanged = mPowerState != newState; if (oldScreenOn != newScreenOn) { if (newScreenOn) { @@ -1777,10 +1797,24 @@ public class PowerManagerService extends IPowerManager.Stub EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason, mTotalTouchDownTime, mTouchCycles); if (err == 0) { - mPowerState |= SCREEN_ON_BIT; sendNotificationLocked(true, -1); + // Update the lights *after* taking care of turning the + // screen on, so we do this after our notifications are + // enqueued and thus will delay turning on the screen light + // until the windows are correctly displayed. + if (stateChanged) { + updateLightsLocked(newState, 0); + } + mPowerState |= SCREEN_ON_BIT; } + } else { + // Update the lights *before* taking care of turning the + // screen off, so we can initiate any animations that are desired. + if (stateChanged) { + updateLightsLocked(newState, 0); + } + // cancel light sensor task mHandler.removeCallbacks(mAutoBrightnessTask); mLightSensorPendingDecrease = false; @@ -1803,30 +1837,20 @@ public class PowerManagerService extends IPowerManager.Stub mLastTouchDown = 0; } } + } else if (stateChanged) { + // Screen on/off didn't change, but lights may have. + updateLightsLocked(newState, 0); } - + + mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK); + updateNativePowerStateLocked(); + + mInitialized = true; } } - + private void updateNativePowerStateLocked() { - if ((mPowerState & SCREEN_ON_BIT) != 0) { - // Don't turn screen on until we know we are really ready to. - // This is to avoid letting the screen go on before things like the - // lock screen have been displayed. - if (mPreparingForScreenOn) { - // Currently waiting for confirmation from the policy that it - // is okay to turn on the screen. Don't allow the screen to go - // on until that is done. - return; - } - for (int i=0; i<mBroadcastQueue.length; i++) { - if (mBroadcastQueue[i] == 1) { - // A screen on is currently enqueued. - return; - } - } - } nativeSetPowerState( (mPowerState & SCREEN_ON_BIT) != 0, (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT); @@ -1852,8 +1876,43 @@ public class PowerManagerService extends IPowerManager.Stub mBatteryService.getBatteryLevel() <= Power.LOW_BATTERY_THRESHOLD); } + private boolean shouldDeferScreenOnLocked() { + if (mPreparingForScreenOn) { + // Currently waiting for confirmation from the policy that it + // is okay to turn on the screen. Don't allow the screen to go + // on until that is done. + if (DEBUG_SCREEN_ON) Slog.i(TAG, + "updateLights: delaying screen on due to mPreparingForScreenOn"); + return true; + } else { + // If there is a screen-on command in the notification queue, we + // can't turn the screen on until it has been processed (and we + // have set mPreparingForScreenOn) or it has been dropped. + for (int i=0; i<mBroadcastQueue.length; i++) { + if (mBroadcastQueue[i] == 1) { + if (DEBUG_SCREEN_ON) Slog.i(TAG, + "updateLights: delaying screen on due to notification queue"); + return true; + } + } + } + return false; + } + private void updateLightsLocked(int newState, int forceState) { final int oldState = mPowerState; + + // If the screen is not currently on, we will want to delay actually + // turning the lights on if we are still getting the UI put up. + if ((oldState&SCREEN_ON_BIT) == 0 || mSkippedScreenOn) { + // Don't turn screen on until we know we are really ready to. + // This is to avoid letting the screen go on before things like the + // lock screen have been displayed. + if ((mSkippedScreenOn=shouldDeferScreenOnLocked())) { + newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT); + } + } + if ((newState & SCREEN_ON_BIT) != 0) { // Only turn on the buttons or keyboard if the screen is also on. // We should never see the buttons on but not the screen. @@ -1960,6 +2019,13 @@ public class PowerManagerService extends IPowerManager.Stub } mScreenBrightness.setTargetLocked(brightness, steps, INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue); + if (DEBUG_SCREEN_ON) { + RuntimeException e = new RuntimeException("here"); + e.fillInStackTrace(); + Slog.i(TAG, "Setting screen brightness: " + brightness, e); + mScreenBrightness.setTargetLocked(brightness, steps, + INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue); + } } if (mSpew) { |