Loading services/java/com/android/server/PowerManagerService.java +97 −31 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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(); } } Loading Loading @@ -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] Loading Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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(); Loading Loading @@ -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(); } } Loading Loading @@ -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); Loading Loading @@ -1696,7 +1719,7 @@ public class PowerManagerService extends IPowerManager.Stub } else { newState &= ~BATTERY_LOW_BIT; } if (newState == mPowerState) { if (newState == mPowerState && mInitialized) { return; } Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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); Loading @@ -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. Loading Loading @@ -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) { Loading Loading
services/java/com/android/server/PowerManagerService.java +97 −31 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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(); } } Loading Loading @@ -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] Loading Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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(); Loading Loading @@ -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(); } } Loading Loading @@ -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); Loading Loading @@ -1696,7 +1719,7 @@ public class PowerManagerService extends IPowerManager.Stub } else { newState &= ~BATTERY_LOW_BIT; } if (newState == mPowerState) { if (newState == mPowerState && mInitialized) { return; } Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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); Loading @@ -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. Loading Loading @@ -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) { Loading