Merge "Improvements to power manager turning on screen."
This commit is contained in:
committed by
Android (Google) Code Review
commit
6bba4afaa4
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user