这篇博客我们主要分析下PowerManagerService的各个状态,主要从goToSleep,wakeUp,userActivity,nap函数作为入口分析。
一、PowerManagerService的goToSleep函数
goToSleep函数主要调用了goToSleepInternal函数:
我们再来看看goToSleepNoUpdateLocked函数
- private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
- if (eventTime < mLastWakeTime
- || mWakefulness == WAKEFULNESS_ASLEEP
- || mWakefulness == WAKEFULNESS_DOZING
- || !mBootCompleted || !mSystemReady) {
- return false;
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
- try {
- switch (reason) {//打印原因
- case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
- Slog.i(TAG, "Going to sleep due to device administration policy "
- + "(uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
- Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH:
- Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
- Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:
- Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_HDMI:
- Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")...");
- break;
- default:
- Slog.i(TAG, "Going to sleep by application request (uid " + uid +")...");
- reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
- break;
- }
- mLastSleepTime = eventTime;
- mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DOZING, reason);//置状态
- // Report the number of wake locks that will be cleared by going to sleep.
- int numWakeLocksCleared = 0;
- final int numWakeLocks = mWakeLocks.size();
- for (int i = 0; i < numWakeLocks; i++) {//统计将会被清除的WakeLock
- final WakeLock wakeLock = mWakeLocks.get(i);
- switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
- case PowerManager.FULL_WAKE_LOCK:
- case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
- case PowerManager.SCREEN_DIM_WAKE_LOCK:
- numWakeLocksCleared += 1;
- break;
- }
- }
- EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
- // Skip dozing if requested.
- if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
- reallyGoToSleepNoUpdateLocked(eventTime, uid);//有这个flag直接进入sleep。而不用先进入WAKEFULNESS_DOZING状态
- }
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
上面函数会先调用setWakefulnessLocked来设置PowerManagerService的状态,我们来看下这个函数:
我们来看这个Notifier的onWakefulnessChangeStarted函数:
- public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
- final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
- // Tell the activity manager about changes in wakefulness, not just interactivity.
- // It needs more granularity than other components.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mActivityManagerInternal.onWakefulnessChanged(wakefulness);//调用AMS的onWakefulnessChanged函数
- }
- });
- // Handle any early interactive state changes.
- // Finish pending incomplete ones from a previous cycle.
- if (mInteractive != interactive) {
- // Finish up late behaviors if needed.
- if (mInteractiveChanging) {
- handleLateInteractiveChange();
- }
- // Start input as soon as we start waking up or going to sleep.
- mInputManagerInternal.setInteractive(interactive);//Input设置状态,在PhoneWindowManager那篇博客有分析
- mInputMethodManagerInternal.setInteractive(interactive);
- // Notify battery stats.
- try {
- mBatteryStats.noteInteractive(interactive);
- } catch (RemoteException ex) { }
- // Handle early behaviors.
- mInteractive = interactive;
- mInteractiveChangeReason = reason;
- mInteractiveChanging = true;
- handleEarlyInteractiveChange();
- }
- }
我们再回过头分析goToSleepNoUpdateLocked函数,如果睡眠的话,会调用reallyGoToSleepNoUpdateLocked函数,其实也就是将状态设置成睡眠的。
- private boolean reallyGoToSleepNoUpdateLocked(long eventTime, int uid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime
- + ", uid=" + uid);
- }
- if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
- || !mBootCompleted || !mSystemReady) {
- return false;
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "reallyGoToSleep");
- try {
- Slog.i(TAG, "Sleeping (uid " + uid +")...");
- setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);//设置Power状态
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
二、PowerManagerService的updatePowerStateLocked函数
我们来看下PowerManagerService最核心的函数updatePowerStateLocked:
- private void updatePowerStateLocked() {
- if (!mSystemReady || mDirty == 0) {
- return;
- }
- if (!Thread.holdsLock(mLock)) {
- Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
- try {
- // Phase 0: Basic state updates.
- updateIsPoweredLocked(mDirty);
- updateStayOnLocked(mDirty);
- updateScreenBrightnessBoostLocked(mDirty);
- // Phase 1: Update wakefulness.
- // Loop because the wake lock and user activity computations are influenced
- // by changes in wakefulness.
- final long now = SystemClock.uptimeMillis();
- int dirtyPhase2 = 0;
- for (;;) {
- int dirtyPhase1 = mDirty;
- dirtyPhase2 |= dirtyPhase1;
- mDirty = 0;
- updateWakeLockSummaryLocked(dirtyPhase1);
- updateUserActivitySummaryLocked(now, dirtyPhase1);
- if (!updateWakefulnessLocked(dirtyPhase1)) {
- break;
- }
- }
- // Phase 2: Update display power state.
- boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
- // Phase 3: Update dream state (depends on display ready signal).
- updateDreamLocked(dirtyPhase2, displayBecameReady);
- // Phase 4: Send notifications, if needed.
- finishWakefulnessChangeIfNeededLocked();
- // Phase 5: Update suspend blocker.
- // Because we might release the last suspend blocker here, we need to make sure
- // we finished everything else first!
- updateSuspendBlockerLocked();
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
2.1 updateIsPoweredLocked函数
我们先来看第一个函数updateIsPoweredLocked函数,主要是电池的一些状态。当收到电池广播时,就是更新电池信息。
- private void updateIsPoweredLocked(int dirty) {
- if ((dirty & DIRTY_BATTERY_STATE) != 0) {
- final boolean wasPowered = mIsPowered;
- final int oldPlugType = mPlugType;
- final boolean oldLevelLow = mBatteryLevelLow;
- mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);//是否充电
- mPlugType = mBatteryManagerInternal.getPlugType();
- mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();//现在的电量
- mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();
- if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
- mDirty |= DIRTY_IS_POWERED;
- // Update wireless dock detection state.
- final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
- mIsPowered, mPlugType, mBatteryLevel);
- final long now = SystemClock.uptimeMillis();
- if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,//充电方式改变是否需要点亮屏幕
- dockedOnWirelessCharger)) {
- wakeUpNoUpdateLocked(now, "android.server.power:POWER", Process.SYSTEM_UID,
- mContext.getOpPackageName(), Process.SYSTEM_UID);
- }
- userActivityNoUpdateLocked(//触发userActivity事件
- now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
- // Tell the notifier whether wireless charging has started so that
- // it can provide feedback to the user.
- if (dockedOnWirelessCharger) {
- mNotifier.onWirelessChargingStarted();
- }
- }
- if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {//更新低功耗相关配置
- if (oldLevelLow != mBatteryLevelLow && !mBatteryLevelLow) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateIsPoweredLocked: resetting low power snooze");
- }
- mAutoLowPowerModeSnoozing = false;
- }
- updateLowPowerModeLocked();
- }
- }
- }
上面函数就是保存了一些电池信息,然后充电方式改变后是否唤醒屏幕,一些更新低功耗的配置。
2.2 updateStayOnLocked函数
再来看updateStayOnLocked函数,mStayOnWhilePluggedInSetting这个配置为0,所以mStayOn只能为false
- private void updateStayOnLocked(int dirty) {
- if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
- final boolean wasStayOn = mStayOn;
- if (mStayOnWhilePluggedInSetting != 0
- && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
- mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting);
- } else {
- mStayOn = false;
- }
- if (mStayOn != wasStayOn) {
- mDirty |= DIRTY_STAY_ON;
- }
- }
- }
2.3 updateScreenBrightnessBoostLocked函数
再来看updateScreenBrightnessBoostLocked函数,看这个接口之前我们先来看下这个接口:boostScreenBrightnessInternal 将屏幕点最亮
- private void boostScreenBrightnessInternal(long eventTime, int uid) {
- synchronized (mLock) {
- if (!mSystemReady || mWakefulness == WAKEFULNESS_ASLEEP
- || eventTime < mLastScreenBrightnessBoostTime) {
- return;
- }
- Slog.i(TAG, "Brightness boost activated (uid " + uid +")...");
- mLastScreenBrightnessBoostTime = eventTime;
- if (!mScreenBrightnessBoostInProgress) {
- mScreenBrightnessBoostInProgress = true;//屏幕最亮的状态变量
- mNotifier.onScreenBrightnessBoostChanged();
- }
- mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST;
- userActivityNoUpdateLocked(eventTime,
- PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
- updatePowerStateLocked();
- }
- }
再来看updateScreenBrightnessBoostLocked函数
- private void updateScreenBrightnessBoostLocked(int dirty) {
- if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) {
- if (mScreenBrightnessBoostInProgress) {//将屏幕最亮
- final long now = SystemClock.uptimeMillis();
- mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
- if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
- final long boostTimeout = mLastScreenBrightnessBoostTime +
- SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
- if (boostTimeout > now) {//还没到时间(最亮屏幕)
- Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, boostTimeout);
- return;//发送消息退出
- }
- }
- mScreenBrightnessBoostInProgress = false;//状态改变
- mNotifier.onScreenBrightnessBoostChanged();
- userActivityNoUpdateLocked(now,//触发userActivity事件
- PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
- }
- }
- }
最终我们会把mScreenBrightnessBoostInProgress 变量传到DisplayPowerController中去,在那里会把它设置最亮。
2.4 updateWakeLockSummaryLocked函数
updateWakeLockSummaryLocked函数,将各个锁的状态汇总。
- private void updateWakeLockSummaryLocked(int dirty) {
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
- mWakeLockSummary = 0;
- final int numWakeLocks = mWakeLocks.size();
- for (int i = 0; i < numWakeLocks; i++) {
- final WakeLock wakeLock = mWakeLocks.get(i);
- switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
- case PowerManager.PARTIAL_WAKE_LOCK:
- if (!wakeLock.mDisabled) {
- // We only respect this if the wake lock is not disabled.
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- break;
- case PowerManager.FULL_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
- break;
- case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT;
- break;
- case PowerManager.SCREEN_DIM_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_SCREEN_DIM;
- break;
- case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
- break;
- case PowerManager.DOZE_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_DOZE;
- break;
- case PowerManager.DRAW_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_DRAW;
- break;
- }
- }
- // Cancel wake locks that make no sense based on the current state.
- if (mWakefulness != WAKEFULNESS_DOZING) {
- mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
- }
- if (mWakefulness == WAKEFULNESS_ASLEEP
- || (mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
- mWakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
- | WAKE_LOCK_BUTTON_BRIGHT);
- if (mWakefulness == WAKEFULNESS_ASLEEP) {
- mWakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
- }
- }
- // Infer implied wake locks where necessary based on the current state.
- if ((mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE) {
- mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
- } else if (mWakefulness == WAKEFULNESS_DREAMING) {
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- }
- if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
- + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
- }
- }
- }
2.5 updateUserActivitySummaryLocked函数
再来看updateUserActivitySummaryLocked是来改变userActivity事件的时间
- private void updateUserActivitySummaryLocked(long now, int dirty) {
- // Update the status of the user activity timeout timer.
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
- | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
- mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);//取消消息
- long nextTimeout = 0;
- if (mWakefulness == WAKEFULNESS_AWAKE
- || mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_DOZING) {
- final int sleepTimeout = getSleepTimeoutLocked();//各种进入睡眠,屏幕灭屏,亮度调低时间
- final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
- final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
- mUserActivitySummary = 0;
- if (mLastUserActivityTime >= mLastWakeTime) {
- nextTimeout = mLastUserActivityTime
- + screenOffTimeout - screenDimDuration;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;//亮屏
- } else {
- nextTimeout = mLastUserActivityTime + screenOffTimeout;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;//暗屏
- }
- }
- }
- if (mUserActivitySummary == 0
- && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
- nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
- if (now < nextTimeout) {
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
- } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
- if (mUserActivitySummary == 0) {
- if (sleepTimeout >= 0) {
- final long anyUserActivity = Math.max(mLastUserActivityTime,
- mLastUserActivityTimeNoChangeLights);
- if (anyUserActivity >= mLastWakeTime) {
- nextTimeout = anyUserActivity + sleepTimeout;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- }
- }
- } else {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- nextTimeout = -1;
- }
- }
- if (mUserActivitySummary != 0 && nextTimeout >= 0) {//不为0,发送消息继续执行这个函数,为0说明要灭屏了不用发消息。
- Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, nextTimeout);
- }
- } else {
- mUserActivitySummary = 0;
- }
- }
- }
2.6 updateWakefulnessLocked函数
我们再来看updateWakefulnessLocked,这个函数必须返回false,才能跳出循环。
- private boolean updateWakefulnessLocked(int dirty) {
- boolean changed = false;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
- | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
- | DIRTY_DOCK_STATE)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {//如果状态不是wake的返回false
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
- }
- final long time = SystemClock.uptimeMillis();
- if (shouldNapAtBedTimeLocked()) {
- changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
- } else {
- changed = goToSleepNoUpdateLocked(time,
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
- }
- }
- }
- return changed;
- }
isBeingKeptAwakeLocked需要返回false
- private boolean isBeingKeptAwakeLocked() {
- return mStayOn// 常为false
- || mProximityPositive//距离传感器
- || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0//是否有屏幕持锁
- || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT//userActivity事件
- | USER_ACTIVITY_SCREEN_DIM)) != 0
- || mScreenBrightnessBoostInProgress;//最亮事件
- }
只有mWakefulness == WAKEFULNESS_AWAKE和isBeingKeptAwakeLocked为true这两个条件才能进入这个判断,只要不满足直接为false,也就能跳出循环了。
再来看这个函数,我们两个配置全为false,只能返回false
2.7 updateDisplayPowerStateLocked函数
再后面调用updateDisplayPowerStateLocked函数,我们之前分析过了,就是把一些状态传到DisplayPowerControlller来设置背光等。这里就不分析了。
2.8 updateDreamLocked函数
- private void updateDreamLocked(int dirty, boolean displayBecameReady) {
- if ((dirty & (DIRTY_WAKEFULNESS
- | DIRTY_USER_ACTIVITY
- | DIRTY_WAKE_LOCKS
- | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS
- | DIRTY_IS_POWERED
- | DIRTY_STAY_ON
- | DIRTY_PROXIMITY_POSITIVE
- | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) {
- if (mDisplayReady) {
- scheduleSandmanLocked();
- }
- }
- }
scheduleSandmanLocked就是发送一个消息,这是一个异步过程。
- private void handleSandman() { // runs on handler thread
- // Handle preconditions.
- final boolean startDreaming;
- final int wakefulness;
- synchronized (mLock) {
- mSandmanScheduled = false;
- wakefulness = mWakefulness;
- if (mSandmanSummoned && mDisplayReady) {// 在goToSleep和nap中将mSandmanSummoned置为true
- startDreaming = canDreamLocked() || canDozeLocked();//是否能做梦
- mSandmanSummoned = false;
- } else {
- startDreaming = false;
- }
- }
- // Start dreaming if needed.
- // We only control the dream on the handler thread, so we don't need to worry about
- // concurrent attempts to start or stop the dream.
- final boolean isDreaming;
- if (mDreamManager != null) {
- // Restart the dream whenever the sandman is summoned.
- if (startDreaming) {
- mDreamManager.stopDream(false /*immediate*/);
- mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);//开始做梦
- }
- isDreaming = mDreamManager.isDreaming();
- } else {
- isDreaming = false;
- }
- // Update dream state.
- synchronized (mLock) {
- // Remember the initial battery level when the dream started.
- if (startDreaming && isDreaming) {//正在做梦
- mBatteryLevelWhenDreamStarted = mBatteryLevel;
- if (wakefulness == WAKEFULNESS_DOZING) {
- Slog.i(TAG, "Dozing...");
- } else {
- Slog.i(TAG, "Dreaming...");
- }
- }
- // If preconditions changed, wait for the next iteration to determine
- // whether the dream should continue (or be restarted).
- if (mSandmanSummoned || mWakefulness != wakefulness) {
- return; // wait for next cycle
- }
- // Determine whether the dream should continue.
- if (wakefulness == WAKEFULNESS_DREAMING) {
- if (isDreaming && canDreamLocked()) {
- if (mDreamsBatteryLevelDrainCutoffConfig >= 0
- && mBatteryLevel < mBatteryLevelWhenDreamStarted
- - mDreamsBatteryLevelDrainCutoffConfig
- && !isBeingKeptAwakeLocked()) {
- // If the user activity timeout expired and the battery appears
- // to be draining faster than it is charging then stop dreaming
- // and go to sleep.
- Slog.i(TAG, "Stopping dream because the battery appears to "
- + "be draining faster than it is charging. "
- + "Battery level when dream started: "
- + mBatteryLevelWhenDreamStarted + "%. "
- + "Battery level now: " + mBatteryLevel + "%.");
- } else {
- return; // continue dreaming
- }
- }
- // Dream has ended or will be stopped. Update the power state.
- if (isItBedTimeYetLocked()) {
- goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
- updatePowerStateLocked();
- } else {
- wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), "android.server.power:DREAM",
- Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID);
- updatePowerStateLocked();
- }
- } else if (wakefulness == WAKEFULNESS_DOZING) {
- if (isDreaming) {//还在做梦退出
- return; // continue dozing
- }
- // Doze has ended or will be stopped. Update the power state.
- reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);// 设置成睡眠状态
- updatePowerStateLocked();
- }
- }
- // Stop dream.
- if (isDreaming) {
- mDreamManager.stopDream(false /*immediate*/);//停止做梦
- }
- }
上面这个函数是异步执行的,那就是updatePowerState会继续执行,这个函数的作用就是等做梦结束会把power的状态由WAKEFULNESS_DOZING变成睡眠状态
说了这么多那到底把这状态改成睡眠状态后有和之前的Dozing状态什么区别呢?
2.8.1 睡眠状态和Dozing状态区别
1. finishWakefulnessChangeIfNeededLocked函数中,只有在睡眠状态才会调用mNotifier.onWakefulnessChangeFinished
- private void finishWakefulnessChangeIfNeededLocked() {
- if (mWakefulnessChanging && mDisplayReady) {
- if (mWakefulness == WAKEFULNESS_DOZING
- && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
- return; // wait until dream has enabled dozing
- }
- mWakefulnessChanging = false;
- mNotifier.onWakefulnessChangeFinished();
- }
- }
- private void updateUserActivitySummaryLocked(long now, int dirty) {
- // Update the status of the user activity timeout timer.
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
- | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
- mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
- long nextTimeout = 0;
- if (mWakefulness == WAKEFULNESS_AWAKE
- || mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_DOZING) {
- ......
- }
- else {
- mUserActivitySummary = 0;
- }
- }
3. 第三个区别最重要,看下面函数,当是睡眠状态返回POLICY_OFF,而是Dozing状态最终返回的是POLICY_DIM状态。
- private int getDesiredScreenPolicyLocked() {
- if (mWakefulness == WAKEFULNESS_ASLEEP) {
- return DisplayPowerRequest.POLICY_OFF;
- }
- if (mWakefulness == WAKEFULNESS_DOZING) {
- if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
- return DisplayPowerRequest.POLICY_DOZE;
- }
- if (mDozeAfterScreenOffConfig) {
- return DisplayPowerRequest.POLICY_OFF;
- }
- // Fall through and preserve the current screen policy if not configured to
- // doze after screen off. This causes the screen off transition to be skipped.
- }
- if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
- || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
- || !mBootCompleted
- || mScreenBrightnessBoostInProgress) {
- return DisplayPowerRequest.POLICY_BRIGHT;
- }
- return DisplayPowerRequest.POLICY_DIM;
- }
- private boolean updateDisplayPowerStateLocked(int dirty) {
- final boolean oldDisplayReady = mDisplayReady;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
- | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
- mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
needDisplaySuspendBlockerLocked函数如果DisplayPowerRequest是暗的时候就会返回 true,导致Displays锁不能释放。也就不会睡眠了
- private boolean needDisplaySuspendBlockerLocked() {
- if (!mDisplayReady) {
- return true;
- }
- if (mDisplayPowerRequest.isBrightOrDim()) {
- // If we asked for the screen to be on but it is off due to the proximity
- // sensor then we may suspend but only if the configuration allows it.
- // On some hardware it may not be safe to suspend because the proximity
- // sensor may not be correctly configured as a wake-up source.
- if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
- || !mSuspendWhenScreenOffDueToProximityConfig) {
- return true;
- }
- }
- if (mScreenBrightnessBoostInProgress) {
- return true;
- }
- // Let the system suspend if the screen is off or dozing.
- return false;
- }
三、wakeUp函数
wakeUp函数最终调用了wakeUpNoUpdateLocked函数之后也调用了updatePowerState函数
- private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
- String opPackageName, int opUid) {
- if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
- || !mBootCompleted || !mSystemReady) {
- return false;
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
- try {
- switch (mWakefulness) {
- case WAKEFULNESS_ASLEEP:
- Slog.i(TAG, "Waking up from sleep (uid " + reasonUid +")...");
- break;
- case WAKEFULNESS_DREAMING:
- Slog.i(TAG, "Waking up from dream (uid " + reasonUid +")...");
- break;
- case WAKEFULNESS_DOZING:
- Slog.i(TAG, "Waking up from dozing (uid " + reasonUid +")...");
- break;
- }
- mLastWakeTime = eventTime;
- setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);//设置状态
- mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);//通知
- userActivityNoUpdateLocked(//触发userActivity事件
- eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
四、userActivity函数
这个函数也是调用了userActivityNoUpdateLocked函数之后调用updatePowerState函数
- private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
- if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
- || !mBootCompleted || !mSystemReady) {
- return false;
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity");
- try {
- if (eventTime > mLastInteractivePowerHintTime) {
- powerHintInternal(POWER_HINT_INTERACTION, 0);
- mLastInteractivePowerHintTime = eventTime;
- }
- mNotifier.onUserActivity(event, uid);//通知
- if (mWakefulness == WAKEFULNESS_ASLEEP
- || mWakefulness == WAKEFULNESS_DOZING
- || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
- return false;
- }
- if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {//记录userActivity时间
- if (eventTime > mLastUserActivityTimeNoChangeLights
- && eventTime > mLastUserActivityTime) {
- mLastUserActivityTimeNoChangeLights = eventTime;
- mDirty |= DIRTY_USER_ACTIVITY;
- return true;
- }
- } else {//记录userActivity发生时间
- if (eventTime > mLastUserActivityTime) {
- mLastUserActivityTime = eventTime;
- mDirty |= DIRTY_USER_ACTIVITY;
- return true;
- }
- }
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return false;
- }
五、nap函数
nap函数最后调用了napNoUpdateLocked,之后也会调用updatePowerState函数
- private boolean napNoUpdateLocked(long eventTime, int uid) {
- if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
- || !mBootCompleted || !mSystemReady) {
- return false;
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "nap");
- try {
- Slog.i(TAG, "Nap time (uid " + uid +")...");
- mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DREAMING, 0);//设置状态
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }