updatePowerStateLocked更新电源的状态,是PowerManagerService的核心方法,当电源状态发生改变最终都会调用到updatePowerStateLocked方法,下面分析这个方法的实现。
private void updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {
return;
}
try {
// 第一步:更新基本状态
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
updateScreenBrightnessBoostLocked(mDirty);
// 第二步: 更新wakelock和用户活动
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;
}
}
// 第三步:更新display power state
boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
// 第四步:更新dream state
updateDreamLocked(dirtyPhase2, displayBecameReady);
// 第五步:发送通知
finishWakefulnessChangeIfNeededLocked();
//第六步:更新底层wakeLock
updateSuspendBlockerLocked();
}
}
在PowerManagerService服务中有个很重要的变量,就是mDirty,这个变量按位来存贮PowerManagerService中的各种变化状态,每当和PMS相关发生了变化,就会第一时间来更新mDirty的相应的位,将相应的位置为1,mDirty变量按位来存储一些Power相关的标志位,然后该方法根据mDirty变量来更新Power的各个状态。
在SystemReady方法中会更新mDirty这个状态,把mDirty置位为DIRTY_BATTERY_STATE,接收BatterySevice发出来的广播,也会设置mDirty这个标志位。这个方法中集中处理了电源状态的更新逻辑,当系统的电源相关发生一些变化的时候都会调用这个方法更新电源状态。
该方法的处理主要分为几个步骤,我们一个一个步骤的来进行分析:
第一步:更新基本的状态信息
updateIsPowerLocked(mDirty)
private void updateIsPoweredLocked(int dirty) {
if ((dirty & DIRTY_BATTERY_STATE) != 0) {
//电池状态发生变化
……
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;
……
//插拔充电器或者USB是否唤醒屏幕
(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);
……
}
//如果充电状态或者低电量状态发生变化,调用updateLowPowerLocked 更新电源信息
if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
……
updateLowPowerModeLocked();
}
}
}
该方法中更新了电池当前的电量,当前是否正常充电,充电的类型,以及batteryLow的电量和mBatteryLevelLow是否是低电量状态
当电源的充电状态或者充电类型发生变化, 根据设置来决定是否唤醒系统。
当电源充电状态发生变化或者低电量的值发生变化的时候,调用updateLowPowerModeLocked()更新低电量的状态。
<pre name="code" class="java">void updateLowPowerModeLocked() {
if (mIsPowered && mLowPowerModeSetting) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE, 0);
mLowPowerModeSetting = false;
}
//是否可以自动进入低电量状态的省电模式
final boolean autoLowPowerModeEnabled = !mIsPowered && mAutoLowPowerModeConfigured
&& !mAutoLowPowerModeSnoozing && mBatteryLevelLow;
//当前是否是低电量模式
final boolean lowPowerModeEnabled = mLowPowerModeSetting || autoLowPowerModeEnabled;
if (mLowPowerModeEnabled != lowPowerModeEnabled) {
mLowPowerModeEnabled = lowPowerModeEnabled;
powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);
BackgroundThread.getHandler().post(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)
.putExtra(PowerManager.EXTRA_POWER_SAVE_MODE, mLowPowerModeEnabled)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
……intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(intent);
}
});
}
}
该方法中首先判断手机是否在充电,如果手机在充电,退出LowPowerMode模式,同时把设置中的mLowPowerModeSetting置为false。 autoLowPowerModeEnabled变量表示是否可以自动进入低电量省电模式,需要满足几个条件:
1.未充电 2.设置了可以自动进入低电量省电模式 3.目前处于低电量的状态
mLowPowerModeEnabled变量表示当前是否进入低电量省电模式
当手机的低电量模式发生了变化,就发送ACTION_POWER_SAVE_MODE_CHANGING的通知,回调关于该模式变化的监听,通知相关的服务Power Save Mode发生了变化。
PowerUI接收到低电量省电模式的广播,就会弹出低电量省电模式的提醒界面
updateStayOnLocked(mDirty)
该方法根据当前的充电状态,来判断充电的时候手机是否保持唤醒。
<pre name="code" class