Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bba4afa authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Improvements to power manager turning on screen."

parents f2bf48b7 beae3bd6
Loading
Loading
Loading
Loading
+97 −31
Original line number Diff line number Diff line
@@ -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) {