-
and5.1PowerManagerService
深入分析
(三)
updatePowerStateLocked
函数
PMS
更新各个状态
,最终都会调用
updatePowerStateLocked
函数,下面我们来分析下
[java] view
plain copy
private void
updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {//mD
irty=0
代表没有变化,或者系统没有准备好,直
接退出<
/p>
return;
}
if
(!ock(mLock)) {
(TAG
,
manager
lock
was
not
held
when
calling
updatePowerStateLocked
}
egin(_TAG_POWER,
try {
// Phase 0: Basic state
updates.
upd
ateIsPoweredLocked(mDirty);//
更新电源状态
updateStayOnLocked(mDirty);
updateScreenBrightnessBoost
Locked(mDirty);
updateIsPoweredLocked
函数,先是要
dirty
有
DIRTY_BA
TTE
RY_STATE
标志位。我们在下
面分析下,什么时候会有这
个标志位
[java] view plain copy
private void updateIsPoweredLocked(int
dirty) {
if
((dirty & DIRTY_BA
TTERY_STATE) != 0) {
final boolean
wasPowered = mIsPowered;
final int oldPlugType = mPlugType;
final boolean
oldLevelLow = mBatteryLevelLow;
mIsPowered
=
red(Y_PLUGGED_ANY);//
这些都是
从
BatteryService
获取
mPlugType = gType();
mBatteryLevel =
teryLevel();
mBatteryLevelLow = teryLevelLow();
if (DEBUG_SPEW) {
Slog.d(TAG
,
+
+
+
+
}
if
(wasPowered != mIsPowered || oldPlugType !=
mPlugType)
{//
是否充电或者充电类
型改变了
mDirty |=
DIRTY_IS_POWERED;//mDirty
置位
// Update wireless dock
detection state.
final
boolean
dockedOnWirelessCharger
=
p>
(//
无
线充电相关
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 = Millis();
if (shouldWakeU
pWhenPluggedOrUnpluggedLocked(wasPowered,
oldPlugType,
dockedOnWirelessCharger))
{//
是否需要唤醒设备
wakeUpNoUpdateLocked(now,
_UID);
}
userActivityNoU
pdateLocked(//
触发
userActivity
now,
_ACTIVITY_EVENT_OTHER,
0,
_UID);
//
Tell the notifier whether wireless charging has
started so that
// it can provide feedback to the user.
if
(dockedOnWirelessCharger)
{//
无线充电相关
lessChargingStarted();
}
}
if
(wasPowered != mIsPowered || oldLevelLow !=
mBatteryLevelLow) {
if (oldLevelLow != mBatteryLevelLow &&
!mBatteryLevelLow) {
if (DEBUG_SPEW) {
Slog.d(TAG,
}
mAutoLowPowerModeSnoozing = false;
}
updateLowPowerModeLocked();
//
更新低功耗模式
}
}
}
首
先
p>
systemReady
函
数
最
终
会
把
< br>mDirty
置
位
为
DIRTY_BATTERY_STATE
,
还<
/p>
有
收
BatterySevice
发出来的广播,最总也会置这个标志位。
[java] view plain copy
private final class BatteryReceiver
extends BroadcastReceiver {
@Override
public void
onReceive(Context context, Intent intent) {
synchronized
(mLock) {
handleBatteryStateChangedLocked();
}
}
}
[java] view plain copy
private void
handleBatteryStateChangedLocked() {
mDirty |=
DIRTY_BATTERY_STA
TE;
updatePowerStateLocked();
}
再来看看电池状态发生什么变化要唤醒设备:
[java] view plain copy
private boolean
shouldWakeUpWhenPluggedOrUnpluggedLocked(
boolean
wasPowered, int oldPlugType, boolean
dockedOnWirelessCharger) {
// Don't wake when powered unless
configured to do so.
if
(!mWakeUpWhenPluggedOrUnpluggedConfig) {//
< br>如果资源中没有配置这项,直接退出
不唤醒设备
return false;
}
// Don't wake when undocked from
wireless charger.
// See WirelessChargerDetector for
justification.
if
(wasPowered && !mIsPowered
&&
oldPlugType
==
TTERY_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 ==
TTERY_PLUGGE
D_WIRELESS//
插入动
作,现在是无线充电
&&
!dockedOnWirelessCharger) {
return false;
}
//
If already dreaming and becoming powered, then
don't wake.
if
(mIsPowered && mWakefulness ==
W
AKEFULNESS_DREAMING)
{//
正在充电,但是
mWakefulness
是做梦状态
return false;
}
//
Don't wake while theater mode is enabled.
if
(mTheaterModeEnabled &&
!mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig)
{
return false;
}
// Otherwise
wake up!
return
true;//
其他就唤醒设备
}
继续分析
updatePowerS
tateLocked
函数,分析
updateStayOnL
ocked
函数。一般这个函数
mStatyon
为
fasle
,除非在资源中设置哪种充电状态下可
以长亮。
[java] view plain copy
private void updateStayOnLocked(int
dirty) {
if
((dirty & (DIRTY_BATTERY_STA
TE |
DIRTY_SETTINGS)) != 0) {//
当
d
irty
是电池状
态和设置的状态改变时
final boolean
wasStayOn = mStayOn;
if (mStayOnWhilePluggedInSetting != 0//
这个值从资源中读取,
一般设置的话代表哪
种充电时可以常亮
&&
!isMaximumScreenOffTimeou
tFromDeviceAdminEnforcedLocked())
{//
p>
看有没有设
mMaximumScreenOffTimeoutF
romDeviceAdmin
屏幕最大亮屏时间,没设默认最
大。那么这个函数返回是
false
mStayOn
=
red(mStayOnWhilePluggedInSetting);
} else {
mStayOn =
false;
}
if (mStayOn != wasStayOn) {
mDirty |=
DIRTY_STAY_ON;
}
}
}
继续分析
updatePowerS
tateLocked
函数的
updateScreenBri
ghtnessBoostLocked
函数,这个函
数是更新
屏幕是否保持最亮状态
[java] view plain
copy
private void
updateScreenBrightnessBoostLocked(int dirty) {
if
((dirty
&
DIRTY_SCREEN_BRIGHTNESS_BOOST)
!=
0)
{//
< br>这
个
状
态
实
在
boostScreenBrightnessInte
rnal
函
数
中
设
置
最
亮
时
置
位
,
当
p>
然
下
面
发
送
消
息
MSG_SCR
EEN_BRIGHTNESS_BOOST_TIMEOUT
也会将这个标志位置位<
/p>
if
(mScreenBrightnessBoostInProgress)
{//
当前正在最亮屏幕这个状态
final long now = Millis();
Messages(MSG_SC
REEN_BRIGHTNESS_BOOST_TIMEOUT);
if
(mLastScreenBrightnessBoostTime > mLastSleepTime)
{
final long
boostTimeout = mLastScreenBrightnessBoostTime +
SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
if
(boostTimeout > now)
{//
看当前时间是否小于最亮屏幕结束的时间
Message
msg
=
Message(MSG
_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
nchronous(true);
ssageAtTime(msg,
boostTimeou
t);//
发送一个延迟的
消
息
,
到
最
亮
屏
幕
结
束
的
时
候
接
受
到
消
息
,
将
标
志
位<
/p>
置
为
DIRTY_SCREEN_BRI
GHTNESS_BOOST
后,重新再回到这个函数
return;
}
}
mScreenBrightnessBoostInProgress
=
false;//
回到这个函数时
,直接将这个屏幕
最亮状态的标志位改成
false
userActivityNoU
pdateLocked(now,//
触发一个
userAc
tivity
_ACTIVITY_EVENT_OTHER,
0,
_UID);
}
}
}
下面看看
MSG_SCREEN_B
RIGHTNESS_BOOST_TIMEOUT
消息的处理函数。
< br>
[java] view plain copy
case
MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
handleScreenBrightnessBoostTimeout();
break;
[java] view
plain copy
private void
handleScreenBrightnessBoostTimeout() { // runs on
handler thread
synchronized (mLock) {
if (DEBUG_SPEW) {
Slog.d(TAG
,
}
mDirty |=
DIRTY_SCREEN_BRIGHTNESS_BOOST;
updatePowerStateLocked();
}
}
接下来看
updatePowerStateLocked
函数的另一个阶段:
< br>