Android7.0 PowerManagerService 之亮灭屏(二) PMS 电源状态管理updatePowerStateLocked()...
本篇注意接着上篇【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);}}
三、综述
不废话了,一图省千言万语
Android7.0 PowerManagerService 之亮灭屏(二) PMS 电源状态管理updatePowerStateLocked()...相关推荐
- Android 知识点 109 —— Android7.0 PowerManagerService 之亮灭屏
原文地址: https://www.cnblogs.com/dyufei/p/8017604.html 写的太好了,粘过来! 本篇从按下power按键后,按键事件从InputManagerServic ...
- Android 系统(41)---Android7.0 PowerManagerService亮灭屏分析(二)
Android7.0 PowerManagerService亮灭屏分析(二) 3029 在PowerManagerService中对各种状态进行判断后,将其数值封装进DisplayPowerReque ...
- Android7.0 PowerManagerService亮灭屏分析(二)
在PowerManagerService中对各种状态进行判断后,将其数值封装进DisplayPowerRequest中传入DisplayPowerController中进一步处理.在亮屏过程中Disp ...
- Android 系统(40)--Android7.0 PowerManagerService亮灭屏分析(一)
Android7.0 PowerManagerService亮灭屏分析(一) 可以导致手机亮灭屏的因素有多种,而在本文中主要讲解按power键亮灭屏过程以及来电亮屏.在亮灭屏过程power中主要的实现 ...
- Android7.0 PowerManagerService亮灭屏分析(一)
绪论 可以导致手机亮灭屏的因素有多种,而在本文中主要讲解按power键亮灭屏过程以及来电亮屏.在亮灭屏过程power中主要的实现类与功能如下所述: PowerManagerService.java:以 ...
- Android 系统(42)---Android7.0 PowerManagerService亮灭屏分析(三)
Android7.0 PowerManagerService亮灭屏分析(三) 在前面两部分已经对绘制windows与设置设备状态进行了详细讲解. 之后接着就该对亮度值进行设置, 实现亮屏动作了. 在D ...
- Android7.0 PowerManagerService亮灭屏分析(三)
在前面两部分已经对绘制windows与设置设备状态进行了详细讲解. 之后接着就该对亮度值进行设置, 实现亮屏动作了. 在DisplayPowerController中的animateScreenBri ...
- Android 8.0 手机亮灭屏
本文主要跟踪分析通过按松power键来唤醒,熄灭屏幕的逻辑.下面是一些相关类的介绍 PowerManagerService.java:简称PMS,负责Andorid系统中电源管理方面的工作.作为系统核 ...
- Android 8.1 DisplayPowerController(二) Proximity Sensor的亮灭屏
概述 P-Sensor亮屏和按Power键亮屏流程还是有些不同之处,如开始调用位置.PowerManagerService中的流程等,由于在平常遇到过许多PSensor亮屏相关Bug,因此这里独立地进 ...
最新文章
- 机器能否拥有像人类一样的意识?Science长文综述解读
- [笔记]React+Cordova踩坑
- 【leetcode】Intersection of Two Linked Lists
- pyperclip模块
- Consumer接口练习之按要求打印信息
- 类加载器 jboss_JBoss AS 7类加载说明
- Spring中的@Cacheable开销
- 作业帮电脑版在线使用_作业帮:创新科技驱动在线教育新模式
- 用ajax传值input file,获取 input type=file 标签的内容,并使用ajax进行请求到服务器...
- c enum能像java一样吗_不一样的Java Enum
- 调用方法try起来的好处_Java:一个重要的停止线程方法——interrupt
- 英伟达CUDA 10终于开放下载了
- JAVA POI读取Excel中Cell为null的处理
- flink checkpoint 恢复_Apache Flink 管理大型状态之增量 Checkpoint 详解
- TracKit-Ocean:目标跟踪网络(二) -- 运行问题及解决逻辑设计
- 第二代支付系统专题之报文篇(一)小额支付报文完整版(含二代新增功能业务说明)...
- java 单点登录(SSO)
- Matplotlab可视化学习笔记(二):如何绘制柱状图
- 使用python爬取电子书_怎样用python3爬取电子书网站所有下载链接
- cocos2d-x android 直接加载下载到sd的zip里的资源文件(一)
热门文章
- golang sync.map
- disruptor消费者模型
- netstat -anp | grep 8199 查看端口占用情况
- jq阻止事件冒泡(点击子级不触发父级)的两种方法
- mysql 关于binlog的一些命令
- Datatables + Bootstrap
- windows平台下subversion服务器端配置
- Nginx [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)
- hash表冲突处理方法
- G1垃圾收集器之RSet