本篇注意接着上篇【Android7.0 PowerManagerService 之亮灭屏(一)】继续分析量灭屏的流程,这篇主要分析PMS的状态计算和更新流程,也是PMS中最为重要和复杂的一部分电源状态管理。
接上篇继续,在Notifier的广播处理完毕后就会调用PMS的内部函数updatePowerStateLocked()来更新全局电源状态。
任何涉及到电源的操作(如量灭屏和应用获取wakeLock锁等)PMS都会调用updatePowerStateLocked()来更新电源的全局状态。PMS用mDirty 来记录电源的状态变化,mDirty是按位操作的(状态变化在系统中一共定义了12个,每一个状态都是2的倍数安位操作即可取得或设置状态)updatePowerStateLocked()的作用就是根据目的前电源状态属性的设置和值的变化来更新mDirty中相应位的值。
这个函数看似很短其实很复杂,可是说是PMS的核心。在看代码前先有个大概的认识和了解以免写入代码的汪洋大海中找不到方向,这样看代码就会比较轻松很容易理解。
其实总结起来此函数主要做了如下两件事:
- 1)判断手机的电源状态(是否充电以及电池状态)和影响电源状态的事件(USB插拔,充电方式变化等)将相应的电源状态更新到mDirty中记录
2)更新wakefulnes,在一个死循环里(当updateWakefulnessLocked返回false跳出循环)判断是否有wakeLock事件,系统是否应该休眠,更新屏幕超时时间等
好了,让我们具体分析吧。
一、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); } }
二、updatePowerStateLocked()具体分析
1)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; //如果充电则设置mDirty // Update wireless dock detection state. final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update( mIsPowered, mPlugType, mBatteryLevel); //无线充电 // Treat plugging and unplugging the devices as a user activity. // Users find it disconcerting when they plug or unplug the device // and it shuts off right away. // Some devices also wake the device when plugged or unplugged because // they don't have a charging LED. final long now = SystemClock.uptimeMillis(); if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType, dockedOnWirelessCharger)) { //插拔USB是否需要点亮屏幕 wakeUpNoUpdateLocked(now, "android.server.power:POWER", Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID); } userActivityNoUpdateLocked( //重新设置最后一次用户事件的时间点,亮屏超时是根据最后一次无用户事件开始算的 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)updateStayOnLocked()
更新充电状态
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; } } }
3)updateScreenBrightnessBoostLocked()
更新屏幕亮度超时时间,发送 MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT
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, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); } } }
4)Update wakefulness()
进入循环,三个函数分别做下面三件事
A:updateWakeLockSummaryLocked() 将wakeLock的类型记录并与Wakefulness状态结合重新算出新的mWakeLockSummary值
B:updateUserActivitySummaryLocked()更新屏幕超时时间(根据最后一次用户事件与dim持续时间来计算屏幕超时的时间,与现在的时间进行对比,决定屏幕继续高亮还是变为dim状态)
C:updateWakefulnessLocked()根据是否有wakeLock,用户活动是否需要睡眠(当device拿着一个wake lock,有用户事件,有距离传感器等都不会灭屏睡眠)
for循环的第一项循环中将所有的状态都更新且此时没有重要的mDirty发生变化,则在下一次循环中mDirty的值为0, updateWakefulnessLocked返回false,就会跳出循环.
A:updateWakeLockSummaryLocked()
private void updateWakeLockSummaryLocked(int dirty) { if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) { mWakeLockSummary = 0; final int numWakeLocks = mWakeLocks.size(); //获取所有的wakeLocks for (int i = 0; i < numWakeLocks; i++) { //遍历所有的wakeLocks记录在mWakeLockSummary中 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) { //根据当前的屏幕状态, 取消不必要的wakeLocks mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW); } if (mWakefulness == WAKEFULNESS_ASLEEP //如果屏幕为休眠,就将屏幕高亮,dim锁取消 || (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; //当WakeLock为亮屏锁或dim锁时,要保持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)); } } }
B:updateUserActivitySummaryLocked()
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); //获取dim持续时长 final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager; mUserActivitySummary = 0; if (mLastUserActivityTime >= mLastWakeTime) { //最后一次的用户时间大于最后一次屏幕醒来的时间 nextTimeout = mLastUserActivityTime //计算下一次屏幕要变为dim的时间 + screenOffTimeout - screenDimDuration; if (now < nextTimeout) { mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; //屏幕未超时则为屏幕高亮 } else { nextTimeout = mLastUserActivityTime + screenOffTimeout; //重置屏幕超时时间 if (now < nextTimeout) { //进入dim阶段了 mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; } } } if (mUserActivitySummary == 0 && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) { nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout; if (now < nextTimeout) { //根据请求的policy来判断屏幕是高亮,还是dim状态 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; //设置dream状态 } } } else { mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; nextTimeout = -1; } } if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) { if ((mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) { // Device is being kept awake by recent user activity if (nextTimeout >= now && mOverriddenTimeout == -1) { // Save when the next timeout would have occurred mOverriddenTimeout = nextTimeout; } } mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; nextTimeout = -1; } if (mUserActivitySummary != 0 && nextTimeout >= 0) { //mUserActivitySummary有值, 并且nextTimeout大于等于0, 发超时消息 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, nextTimeout); //发送屏幕超时消息 } } else { mUserActivitySummary = 0; } if (DEBUG_SPEW) { Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness=" + PowerManagerInternal.wakefulnessToString(mWakefulness) + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary) + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout)); } } }
C:updateWakefulnessLocked()
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()) { //mWakefulness为AWAKE且休眠时间到,则执行休眠 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; }
5)updateDisplayPowerStateLocked()
获取需要请求的设备电源状态(判断是否开启亮度自动调节开关、距离传感器)并计算屏幕亮度值等记录到DisplayPowerRequest中。经过DMS传入DPC中进行处理。
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(); //根据mWakefulness与mWakeLockSummary获得,设备新状态是DIM, BRIGHT, OFF还是DOZE // Determine appropriate screen brightness and auto-brightness adjustments. boolean brightnessSetByUser = true; int screenBrightness = mScreenBrightnessSettingDefault; float screenAutoBrightnessAdjustment = 0.0f; //亮度自动调节 boolean autoBrightness = (mScreenBrightnessModeSetting == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); //是否开启亮度自动调节 if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) { screenBrightness = mScreenBrightnessOverrideFromWindowManager; autoBrightness = false; brightnessSetByUser = false; } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) { screenBrightness = mTemporaryScreenBrightnessSettingOverride; } else if (isValidBrightness(mScreenBrightnessSetting)) { screenBrightness = mScreenBrightnessSetting; } if (autoBrightness) { screenBrightness = mScreenBrightnessSettingDefault; //亮度自动调节 if (isValidAutoBrightnessAdjustment( mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) { screenAutoBrightnessAdjustment = mTemporaryScreenAutoBrightnessAdjustmentSettingOverride; } else if (isValidAutoBrightnessAdjustment( mScreenAutoBrightnessAdjustmentSetting)) { screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting; } } screenBrightness = Math.max(Math.min(screenBrightness, //获得请求亮度 mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum); screenAutoBrightnessAdjustment = Math.max(Math.min( screenAutoBrightnessAdjustment, 1.0f), -1.0f); // Update display power request. //将数据记录在mDisplayPowerRequest中 mDisplayPowerRequest.screenBrightness = screenBrightness; mDisplayPowerRequest.screenAutoBrightnessAdjustment = screenAutoBrightnessAdjustment; mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser; mDisplayPowerRequest.useAutoBrightness = autoBrightness; mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked(); mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled; mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress; mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight; if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager; if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND && (mWakeLockSummary & WAKE_LOCK_DRAW) != 0) { mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE; } mDisplayPowerRequest.dozeScreenBrightness = mDozeScreenBrightnessOverrideFromDreamManager; } else { mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN; mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity); //调用requestPowerState获取电源状态 mRequestWaitForNegativeProximity = false; if (DEBUG_SPEW) { Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady + ", policy=" + mDisplayPowerRequest.policy + ", mWakefulness=" + mWakefulness + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary) + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary) + ", mBootCompleted=" + mBootCompleted + ", mScreenBrightnessBoostInProgress=" + mScreenBrightnessBoostInProgress); } } return mDisplayReady && !oldDisplayReady; }
6)updateDreamLocked()
此函数的作用就是异步处理Dream,在Dream结束后系统休眠。具体是通过发送Dream消息在handleSandman函数中处理()详细过程不再展开。
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(); } } } private void scheduleSandmanLocked() { if (!mSandmanScheduled) { mSandmanScheduled = true; Message msg = mHandler.obtainMessage(MSG_SANDMAN); msg.setAsynchronous(true); mHandler.sendMessage(msg); } }
7)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(); } }
8)updateSuspendBlockerLocked()
更新睡眠锁,以及是否持锁和释放锁
private void updateSuspendBlockerLocked() { final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0); final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked(); final boolean autoSuspend = !needDisplaySuspendBlocker; final boolean interactive = mDisplayPowerRequest.isBrightOrDim(); // Disable auto-suspend if needed. // FIXME We should consider just leaving auto-suspend enabled forever since // we already hold the necessary wakelocks. if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(false); } // First acquire suspend blockers if needed. if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.acquire(); mHoldingWakeLockSuspendBlocker = true; } if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.acquire(); mHoldingDisplaySuspendBlocker = true; } // Inform the power HAL about interactive mode. // Although we could set interactive strictly based on the wakefulness // as reported by isInteractive(), it is actually more desirable to track // the display policy state instead so that the interactive state observed // by the HAL more accurately tracks transitions between AWAKE and DOZING. // Refer to getDesiredScreenPolicyLocked() for details. if (mDecoupleHalInteractiveModeFromDisplayConfig) { // When becoming non-interactive, we want to defer sending this signal // until the display is actually ready so that all transitions have // completed. This is probably a good sign that things have gotten // too tangled over here... if (interactive || mDisplayReady) { setHalInteractiveModeLocked(interactive); } } // Then release suspend blockers if needed. if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.release(); mHoldingWakeLockSuspendBlocker = false; } if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.release(); mHoldingDisplaySuspendBlocker = false; } // Enable auto-suspend if needed. if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(true); } }
三、综述
不废话了,一图省千言万语