Android 6.0 PowerManagerService 之 updatePowerStateLocked函数
2016-12-06 16:17
288 查看
updatePowerStateLocked
/** * Updates the global power state based on dirty bits recorded in mDirty. * * This is the main function that performs power state transitions. * We centralize them here so that we can recompute the power state completely * each time something important changes, and ensure that we do it the same * way each time. The point is to gather all of the transition logic here. */ 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); } }
updateIsPoweredLocked
/** * Updates the value of mIsPowered. * Sets DIRTY_IS_POWERED if a change occurred. */ 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);//从BatteryService获取 mPlugType = mBatteryManagerInternal.getPlugType(); mBatteryLevel = mBatteryManagerInternal.getBatteryLevel(); mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow(); if (DEBUG_SPEW) { Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered + ", mIsPowered=" + mIsPowered + ", oldPlugType=" + oldPlugType + ", mPlugType=" + mPlugType + ", mBatteryLevel=" + mBatteryLevel); } if (wasPowered != mIsPowered || oldPlugType != mPlugType) { mDirty |= DIRTY_IS_POWERED; // 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)) {//是否需要唤醒设备 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();//更新低功耗模式 } } }首先systemReady函数会把mDirty置位为DIRTY_BATTERY_STATE,还有收BatterySevice发出来的广播,也会置这个标志位
private final class BatteryReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { synchronized (mLock) { handleBatteryStateChangedLocked(); } } }
private void handleBatteryStateChangedLocked() { mDirty |= DIRTY_BATTERY_STATE; updatePowerStateLocked(); }
shouldWakeUpWhenPluggedOrUnpluggedLocked
private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked( boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) { // Don't wake when powered unless configured to do so. if (!mWakeUpWhenPluggedOrUnpluggedConfig) { return false; } // Don't wake when undocked from wireless charger. // See WirelessChargerDetector for justification. if (wasPowered && !mIsPowered && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { return false; } // Don't 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 becoming powered, then don't wake. if (mIsPowered && mWakefulness == WAKEFULNESS_DREAMING) { return false; } // Don't wake while theater mode is enabled. if (mTheaterModeEnabled && !mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig) { return false; } // Otherwise wake up! return true; }
updateStayOnLocked
继续分析updatePowerStateLocked函数,分析updateStayOnLocked函数。一般这个函数mStatyon为fasle,除非在资源中设置哪种充电状态下可以长亮。/** * Updates the value of mStayOn. * Sets DIRTY_STAY_ON if a change occurred. */ private void updateStayOnLocked(int dirty) { if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {//当dirty是电池状态和设置的状态改变时 final boolean wasStayOn = mStayOn; if (mStayOnWhilePluggedInSetting != 0 //这个值从资源中读取,一般设置的话代表哪种充电时可以常亮 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {//看有没有设mMaximumScreenOffTimeoutFromDeviceAdmin屏幕最大亮屏时间,没设默认最大。那么这个函数返回是false mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting); } else { mStayOn = false; } if (mStayOn != wasStayOn) { mDirty |= DIRTY_STAY_ON; } } }
updateScreenBrightnessBoostLocked
这个函数是更新屏幕是否保持最亮状态private void updateScreenBrightnessBoostLocked(int dirty) { //这个状态实在boostScreenBrightnessInternal函数中设置最亮时置位,当然下面发送消息MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT也会将这个标志位置位 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);//发送一个延迟的消息,到最亮屏幕结束的时候接受到消息,将标志位置为DIRTY_SCREEN_BRIGHTNESS_BOOST后,重新再回到这个函数 return; } } mScreenBrightnessBoostInProgress = false; mNotifier.onScreenBrightnessBoostChanged(); userActivityNoUpdateLocked(now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); } } }
接下来看updatePowerStateLocked函数的另一个阶段,
// 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全部给dirtyPhase1,并且在这个循环中使用这个dirty dirtyPhase2 |= dirtyPhase1;//dirtyPhase2 会把之前所有的mDirty状态全部或上,然后用这个状态继续下面的函数 mDirty = 0; updateWakeLockSummaryLocked(dirtyPhase1); updateUserActivitySummaryLocked(now, dirtyPhase1); if (!updateWakefulnessLocked(dirtyPhase1)) { break; } }
updateWakeLockSummaryLocked
/** * Updates the value of mWakeLockSummary to summarize the state of all active wake locks. * Note that most wake-locks are ignored when the system is asleep. * * This function must have no other side-effects. */ @SuppressWarnings("deprecation") 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);//下面根据各种状态,将上面或上的mWakeLockSummary,减去 } 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) {//只要有屏幕锁,cpu锁必须持有 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)); } } }
updateUserActivitySummaryLocked
/** * Updates the value of mUserActivitySummary to summarize the user requested * state of the system such as whether the screen should be bright or dim. * Note that user activity is ignored when the system is asleep. * * This function must have no other side-effects. */ 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) {//userActivity的time大于上次唤醒时间 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;//该值为-1,下面就不会发送消息了 } } if (mUserActivitySummary != 0 && 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)); } } }
MSG_USER_ACTIVITY_TIMEOUT的消息处理
/** * Handler for asynchronous operations performed by the power manager. */ private final class PowerManagerHandler extends Handler { public PowerManagerHandler(Looper looper) { super(looper, null, true /*async*/); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_USER_ACTIVITY_TIMEOUT: handleUserActivityTimeout(); break; case MSG_SANDMAN: handleSandman(); break; case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT: handleScreenBrightnessBoostTimeout(); break; } } }
updateWakefulnessLocked
/** * Updates the wakefulness of the device. * * This is the function that decides whether the device should start dreaming * based on the current wake locks and user activity state. It may modify mDirty * if the wakefulness changes. * * Returns true if the wakefulness changed and we need to restart power state calculation. */ 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()) { 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; }
再来看看isItBedTimeYetLocked函数,isBeingKeptAwakeLocked函数,如果isBeingKeptAwakeLocked返回true代表处于亮屏状态,isItBedTimeYetLocked返回false,上面的for死循环退出
/** * Returns true if the device is being kept awake by a wake lock, user activity * or the stay on while powered setting. We also keep the phone awake when * the proximity sensor returns a positive result so that the device does not * lock while in a phone call. This function only controls whether the device * will go to sleep or dream which is independent of whether it will be allowed * to suspend. */ private boolean isBeingKeptAwakeLocked() { return mStayOn || mProximityPositive || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0 || mScreenBrightnessBoostInProgress; }
如果isBeingKeptAwakeLocked返回false,并且mBootCompleted 为true开机完成了。那么updateWakefulnessLocked函数进入判断条件
那再来看看shouldNapAtBedTimeLocked函数,就是看有没有做梦这个设置,如果没有直接到goToSleepNoUpdateLocked函数,到了goToSleepNoUpdateLocked函数后将mWakefulness 设为WAKEFULNESS_DOZING显示返回true还要继续循环,下次到updateWakefulnessLocked这个函数,不是awake类型的,也返回false,直接退出死循环了。到napNoUpdateLocked函数也是一样的先是将mWakefulness置为WAKEFULNESS_DREAMING,返回true,继续循环,下次不是awake类型就返回false,退出循环了。
/** * Returns true if the device should automatically nap and start dreaming when the user * activity timeout has expired and it's bedtime. */ private boolean shouldNapAtBedTimeLocked() { return mDreamsActivateOnSleepSetting || (mDreamsActivateOnDockSetting && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED); }
下篇博客继续分析updatePowerStateLocked中的
// Phase 2: Update display power state.
boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
相关文章推荐
- Android 6.0 PowerManagerService 一
- Android 6.0 PowerManagerService 之 Display
- Android 6.0 PowerManagerService状态分析
- Android PowerManagerService分析
- Android 6.0 之AlarmManagerService源码分析
- Android5.1 PowerManagerService深入分析
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- 浅谈Android system_service 注册Service、APP获取并访问服务(PMS:PowerManagerService)为例
- android 6.0 activitymanagerservice keyword
- android PowerManagerService分析
- android PowerManagerService分析
- Android7.0 PowerManagerService 之亮灭屏(二) PMS 电源状态管理updatePowerStateLocked()
- Android入门进阶教程(16)-ActivityThead、ActivityManagerService 详解
- Android解析ActivityManagerService(一)AMS启动流程和AMS家族
- Android 4.4 KitKat NotificationManagerService使用详解与原理分析(二)__原理分析
- Android Audio System 之三: AudioPolicyService 和 AudioPolicyManager
- Android PackageManagerService分析二:安装APK
- Android M PackageManagerService解析