Merge "Improvements to power manager turning on screen."

This commit is contained in:
Dianne Hackborn
2011-09-21 16:18:38 -07:00
committed by Android (Google) Code Review

View File

@@ -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) {