1、and51PowerManagerService深入分析三updatePowerStateLocked函数and5.1PowerManagerService深入分析(三)updatePowerStateLocked函数PMS更新各个状态,最终都会调用updatePowerStateLocked函数,下面我们来分析下java view plain copyprivate void updatePowerStateLocked() if (!mSystemReady | mDirty = 0) /mDirty=0代表没有变化,或者系统没有准备好,直接退出 return; if (!Thread.h
2、oldsLock(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(mDirt
3、y); updateIsPoweredLocked函数,先是要dirty有DIRTY_BATTERY_STATE标志位。我们在下面分析下,什么时候会有这个标志位java view plain copyprivate void updateIsPoweredLocked(int dirty) if (dirty & DIRTY_BATTERY_STATE) != 0) final boolean wasPowered = mIsPowered; final int oldPlugType = mPlugType; final boolean oldLevelLow = mBatteryLevel
4、Low; mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);/这些都是从BatteryService获取 mPlugType = mBatteryManagerInternal.getPlugType(); mBatteryLevel = mBatteryManagerInternal.getBatteryLevel(); mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow(); if (DEBUG_SPEW
5、) Slog.d(TAG, updateIsPoweredLocked: wasPowered= + wasPowered + , mIsPowered= + mIsPowered + , oldPlugType= + oldPlugType + , mPlugType= + mPlugType + , mBatteryLevel= + mBatteryLevel); if (wasPowered != mIsPowered | oldPlugType != mPlugType) /是否充电或者充电类型改变了 mDirty |= DIRTY_IS_POWERED;/mDirty置位 / Upd
6、ate 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 o
7、ff right away. / Some devices also wake the device when plugged or unplugged because / they dont have a charging LED. final long now = SystemClock.uptimeMillis(); if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType, dockedOnWirelessCharger) /是否需要唤醒设备 wakeUpNoUpdateLocked(now, Proces
8、s.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.onWirelessChargingSta
9、rted(); if (wasPowered != mIsPowered | oldLevelLow != mBatteryLevelLow) if (oldLevelLow != mBatteryLevelLow & !mBatteryLevelLow) if (DEBUG_SPEW) Slog.d(TAG, updateIsPoweredLocked: resetting low power snooze); mAutoLowPowerModeSnoozing = false; updateLowPowerModeLocked();/更新低功耗模式 首先systemReady函数最终会把m
10、Dirty置位为DIRTY_BATTERY_STATE,还有收BatterySevice发出来的广播,最总也会置这个标志位。java view plain copyprivate final class BatteryReceiver extends BroadcastReceiver Override public void onReceive(Context context, Intent intent) synchronized (mLock) handleBatteryStateChangedLocked(); java view plain copyprivate void hand
11、leBatteryStateChangedLocked() mDirty |= DIRTY_BATTERY_STATE; updatePowerStateLocked(); 再来看看电池状态发生什么变化要唤醒设备:java view plain copyprivate boolean shouldWakeUpWhenPluggedOrUnpluggedLocked( boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) / Dont wake when powered unless configured to
12、 do so. if (!mWakeUpWhenPluggedOrUnpluggedConfig) /如果资源中没有配置这项,直接退出不唤醒设备 return false; / Dont wake when undocked from wireless charger. / See WirelessChargerDetector for justification. if (wasPowered & !mIsPowered & oldPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS) /这是一个 拔出的工作,然后之前的无线充电 return
13、false; / Dont wake when docked on wireless charger unless we are certain of it. / See WirelessChargerDetector for justification. if (!wasPowered & mIsPowered & mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS/插入动作,现在是无线充电 & !dockedOnWirelessCharger) return false; / If already dreaming and becomin
14、g powered, then dont wake. if (mIsPowered & mWakefulness = WAKEFULNESS_DREAMING) /正在充电,但是mWakefulness 是做梦状态 return false; / Dont wake while theater mode is enabled. if (mTheaterModeEnabled & !mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig) return false; / Otherwise wake up! return true;/其他就唤醒设备 继续
15、分析updatePowerStateLocked函数,分析updateStayOnLocked函数。一般这个函数mStatyon为fasle,除非在资源中设置哪种充电状态下可以长亮。java view plain copyprivate void updateStayOnLocked(int dirty) if (dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS) != 0) /当dirty是电池状态和设置的状态改变时 final boolean wasStayOn = mStayOn; if (mStayOnWhilePluggedInSetting
16、 != 0/这个值从资源中读取,一般设置的话代表哪种充电时可以常亮 & !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() /看有没有设mMaximumScreenOffTimeoutFromDeviceAdmin屏幕最大亮屏时间,没设默认最大。那么这个函数返回是false mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting); else mStayOn = false; if (mStayOn != wasStayOn) mDirty
17、|= DIRTY_STAY_ON; 继续分析updatePowerStateLocked函数的updateScreenBrightnessBoostLocked函数,这个函数是更新屏幕是否保持最亮状态java view plain copyprivate void updateScreenBrightnessBoostLocked(int dirty) if (dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) /这个状态实在boostScreenBrightnessInternal函数中设置最亮时置位,当然下面发送消息MSG_SCREEN_BRIGHTN
18、ESS_BOOST_TIMEOUT也会将这个标志位置位 if (mScreenBrightnessBoostInProgress) /当前正在最亮屏幕这个状态 final long now = SystemClock.uptimeMillis(); mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT); if (mLastScreenBrightnessBoostTime mLastSleepTime) final long boostTimeout = mLastScreenBrightnessBoostTime + SCR
19、EEN_BRIGHTNESS_BOOST_TIMEOUT; if (boostTimeout now) /看当前时间是否小于最亮屏幕结束的时间 Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, boostTimeout);/发送一个延迟的消息,到最亮屏幕结束的时候接受到消息,将标志位置为DIRTY_SCREEN_BRIGHTNESS_BOOST后,重新再回到这个函数 return
20、; mScreenBrightnessBoostInProgress = false;/回到这个函数时,直接将这个屏幕最亮状态的标志位改成false userActivityNoUpdateLocked(now,/触发一个userActivity PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); 下面看看MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT消息的处理函数。java view plain copycase MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT: han
21、dleScreenBrightnessBoostTimeout(); break; java view plain copyprivate void handleScreenBrightnessBoostTimeout() / runs on handler thread synchronized (mLock) if (DEBUG_SPEW) Slog.d(TAG, handleScreenBrightnessBoostTimeout); mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST; updatePowerStateLocked(); 接下来看update
22、PowerStateLocked函数的另一个阶段:java view plain copy/ 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;/这个循环中每次新的mDirty全部给di
23、rtyPhase1,并且在这个循环中使用这个dirty dirtyPhase2 |= dirtyPhase1;/dirtyPhase2 会把之前所有的mDirty状态全部或上,然后用这个状态继续下面的函数 mDirty = 0;/mDirty会在这里清零 updateWakeLockSummaryLocked(dirtyPhase1); updateUserActivitySummaryLocked(now, dirtyPhase1); if (!updateWakefulnessLocked(dirtyPhase1) break; 先看下updateWakeLockSummaryLocked
24、函数,更新wakelock的函数java view plain copyprivate 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 (
25、wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) /先根据wakelock的flag,mWakeLockSummary或上各种状态 case PowerManager.PARTIAL_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_CPU; break; case PowerManager.FULL_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT; break; case PowerManag
26、er.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 PowerMana
27、ger.DOZE_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_DOZE; break; / Cancel wake locks that make no sense based on the current state. if (mWakefulness != WAKEFULNESS_DOZING) /下面根据各种状态,将上面或上的mWakeLockSummary,有的减去 mWakeLockSummary &= WAKE_LOCK_DOZE; if (mWakefulness = WAKEFULNESS_ASLEEP | (mWakeLockSummar
28、y & 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 (mWakeLockSum
29、mary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM) != 0) /只要有屏幕锁,cpu锁必须持有 if (mWakefulness = WAKEFULNESS_AWAKE) mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE; else if (mWakefulness = WAKEFULNESS_DREAMING) mWakeLockSummary |= WAKE_LOCK_CPU; if (DEBUG_SPEW) Slog.d(TAG, updateWakeLockSummaryLocked: mWakefulness= + PowerManagerInternal.wakefulnessToString(mWakefulness) + , mWakeLockSummary=0x + Integer.toHexString(mWakeLockSummary); 下面分析下updateUserActivitySummaryLocked函数java view plain copyprivate void updateUs
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1