and51PowerManagerService深入分析三updatePowerStateLocked函数.docx
《and51PowerManagerService深入分析三updatePowerStateLocked函数.docx》由会员分享,可在线阅读,更多相关《and51PowerManagerService深入分析三updatePowerStateLocked函数.docx(15页珍藏版)》请在冰豆网上搜索。
and51PowerManagerService深入分析三updatePowerStateLocked函数
and5.1PowerManagerService深入分析(三)updatePowerStateLocked函数
PMS更新各个状态,最终都会调用updatePowerStateLocked函数,下面我们来分析下
[java]viewplaincopy
privatevoidupdatePowerStateLocked(){
if(!
mSystemReady||mDirty==0){//mDirty=0代表没有变化,或者系统没有准备好,直接退出
return;
}
if(!
Thread.holdsLock(mLock)){
Slog.wtf(TAG,"PowermanagerlockwasnotheldwhencallingupdatePowerStateLocked");
}
Trace.traceBegin(Trace.TRACE_TAG_POWER,"updatePowerState");
try{
//Phase0:
Basicstateupdates.
updateIsPoweredLocked(mDirty);//更新电源状态
updateStayOnLocked(mDirty);
updateScreenBrightnessBoostLocked(mDirty);
updateIsPoweredLocked函数,先是要dirty有DIRTY_BATTERY_STATE标志位。
我们在下面分析下,什么时候会有这个标志位
[java]viewplaincopy
privatevoidupdateIsPoweredLocked(intdirty){
if((dirty&DIRTY_BATTERY_STATE)!
=0){
finalbooleanwasPowered=mIsPowered;
finalintoldPlugType=mPlugType;
finalbooleanoldLevelLow=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;//mDirty置位
//Updatewirelessdockdetectionstate.
finalbooleandockedOnWirelessCharger=mWirelessChargerDetector.update(//无线充电相关
mIsPowered,mPlugType,mBatteryLevel);
//Treatpluggingandunpluggingthedevicesasauseractivity.
//Usersfinditdisconcertingwhentheyplugorunplugthedevice
//anditshutsoffrightaway.
//Somedevicesalsowakethedevicewhenpluggedorunpluggedbecause
//theydon'thaveachargingLED.
finallongnow=SystemClock.uptimeMillis();
if(shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered,oldPlugType,
dockedOnWirelessCharger)){//是否需要唤醒设备
wakeUpNoUpdateLocked(now,Process.SYSTEM_UID);
}
userActivityNoUpdateLocked(//触发userActivity
now,PowerManager.USER_ACTIVITY_EVENT_OTHER,0,Process.SYSTEM_UID);
//Tellthenotifierwhetherwirelesscharginghasstartedsothat
//itcanprovidefeedbacktotheuser.
if(dockedOnWirelessCharger){//无线充电相关
mNotifier.onWirelessChargingStarted();
}
}
if(wasPowered!
=mIsPowered||oldLevelLow!
=mBatteryLevelLow){
if(oldLevelLow!
=mBatteryLevelLow&&!
mBatteryLevelLow){
if(DEBUG_SPEW){
Slog.d(TAG,"updateIsPoweredLocked:
resettinglowpowersnooze");
}
mAutoLowPowerModeSnoozing=false;
}
updateLowPowerModeLocked();//更新低功耗模式
}
}
}
首先systemReady函数最终会把mDirty置位为DIRTY_BATTERY_STATE,还有收BatterySevice发出来的广播,最总也会置这个标志位。
[java]viewplaincopy
privatefinalclassBatteryReceiverextendsBroadcastReceiver{
@Override
publicvoidonReceive(Contextcontext,Intentintent){
synchronized(mLock){
handleBatteryStateChangedLocked();
}
}
}
[java]viewplaincopy
privatevoidhandleBatteryStateChangedLocked(){
mDirty|=DIRTY_BATTERY_STATE;
updatePowerStateLocked();
}
再来看看电池状态发生什么变化要唤醒设备:
[java]viewplaincopy
privatebooleanshouldWakeUpWhenPluggedOrUnpluggedLocked(
booleanwasPowered,intoldPlugType,booleandockedOnWirelessCharger){
//Don'twakewhenpoweredunlessconfiguredtodoso.
if(!
mWakeUpWhenPluggedOrUnpluggedConfig){//如果资源中没有配置这项,直接退出不唤醒设备
returnfalse;
}
//Don'twakewhenundockedfromwirelesscharger.
//SeeWirelessChargerDetectorforjustification.
if(wasPowered&&!
mIsPowered
&&oldPlugType==BatteryManager.BATTERY_PLUGGED_WIRELESS){//这是一个拔出的工作,然后之前的无线充电
returnfalse;
}
//Don'twakewhendockedonwirelesschargerunlesswearecertainofit.
//SeeWirelessChargerDetectorforjustification.
if(!
wasPowered&&mIsPowered
&&mPlugType==BatteryManager.BATTERY_PLUGGED_WIRELESS//插入动作,现在是无线充电
&&!
dockedOnWirelessCharger){
returnfalse;
}
//Ifalreadydreamingandbecomingpowered,thendon'twake.
if(mIsPowered&&mWakefulness==WAKEFULNESS_DREAMING){//正在充电,但是mWakefulness是做梦状态
returnfalse;
}
//Don'twakewhiletheatermodeisenabled.
if(mTheaterModeEnabled&&!
mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig){
returnfalse;
}
//Otherwisewakeup!
returntrue;//其他就唤醒设备
}
继续分析updatePowerStateLocked函数,分析updateStayOnLocked函数。
一般这个函数mStatyon为fasle,除非在资源中设置哪种充电状态下可以长亮。
[java]viewplaincopy
privatevoidupdateStayOnLocked(intdirty){
if((dirty&(DIRTY_BATTERY_STATE|DIRTY_SETTINGS))!
=0){//当dirty是电池状态和设置的状态改变时
finalbooleanwasStayOn=mStayOn;
if(mStayOnWhilePluggedInSetting!
=0//这个值从资源中读取,一般设置的话代表哪种充电时可以常亮
&&!
isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()){//看有没有设mMaximumScreenOffTimeoutFromDeviceAdmin屏幕最大亮屏时间,没设默认最大。
那么这个函数返回是false
mStayOn=mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting);
}else{
mStayOn=false;
}
if(mStayOn!
=wasStayOn){
mDirty|=DIRTY_STAY_ON;
}
}
}
继续分析updatePowerStateLocked函数的updateScreenBrightnessBoostLocked函数,这个函数是更新屏幕是否保持最亮状态
[java]viewplaincopy
privatevoidupdateScreenBrightnessBoostLocked(intdirty){
if((dirty&DIRTY_SCREEN_BRIGHTNESS_BOOST)!
=0){//这个状态实在boostScreenBrightnessInternal函数中设置最亮时置位,当然下面发送消息MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT也会将这个标志位置位
if(mScreenBrightnessBoostInProgress){//当前正在最亮屏幕这个状态
finallongnow=SystemClock.uptimeMillis();
mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
if(mLastScreenBrightnessBoostTime>mLastSleepTime){
finallongboostTimeout=mLastScreenBrightnessBoostTime+
SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
if(boostTimeout>now){//看当前时间是否小于最亮屏幕结束的时间
Messagemsg=mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg,boostTimeout);//发送一个延迟的消息,到最亮屏幕结束的时候接受到消息,将标志位置为DIRTY_SCREEN_BRIGHTNESS_BOOST后,重新再回到这个函数
return;
}
}
mScreenBrightnessBoostInProgress=false;//回到这个函数时,直接将这个屏幕最亮状态的标志位改成false
userActivityNoUpdateLocked(now,//触发一个userActivity
PowerManager.USER_ACTIVITY_EVENT_OTHER,0,Process.SYSTEM_UID);
}
}
}
下面看看MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT消息的处理函数。
[java]viewplaincopy
caseMSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
handleScreenBrightnessBoostTimeout();
break;
[java]viewplaincopy
privatevoidhandleScreenBrightnessBoostTimeout(){//runsonhandlerthread
synchronized(mLock){
if(DEBUG_SPEW){
Slog.d(TAG,"handleScreenBrightnessBoostTimeout");
}
mDirty|=DIRTY_SCREEN_BRIGHTNESS_BOOST;
updatePowerStateLocked();
}
}
接下来看updatePowerStateLocked函数的另一个阶段:
[java]viewplaincopy
//Phase1:
Updatewakefulness.
//Loopbecausethewakelockanduseractivitycomputationsareinfluenced
//bychangesinwakefulness.
finallongnow=SystemClock.uptimeMillis();
intdirtyPhase2=0;
for(;;){
intdirtyPhase1=mDirty;//这个循环中每次新的mDirty全部给dirtyPhase1,并且在这个循环中使用这个dirty
dirtyPhase2|=dirtyPhase1;//dirtyPhase2会把之前所有的mDirty状态全部或上,然后用这个状态继续下面的函数
mDirty=0;//mDirty会在这里清零
updateWakeLockSummaryLocked(dirtyPhase1);
updateUserActivitySummaryLocked(now,dirtyPhase1);
if(!
updateWakefulnessLocked(dirtyPhase1)){
break;
}
}
先看下updateWakeLockSummaryLocked函数,更新wakelock的函数
[java]viewplaincopy
privatevoidupdateWakeLockSummaryLocked(intdirty){
if((dirty&(DIRTY_WAKE_LOCKS|DIRTY_WAKEFULNESS))!
=0){
mWakeLockSummary=0;
finalintnumWakeLocks=mWakeLocks.size();
for(inti=0;ifinalWakeLockwakeLock=mWakeLocks.get(i);
switch(wakeLock.mFlags&PowerManager.WAKE_LOCK_LEVEL_MASK){//先根据wakelock的flag,mWakeLockSummary或上各种状态
casePowerManager.PARTIAL_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_CPU;
break;
casePowerManager.FULL_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_SCREEN_BRIGHT|WAKE_LOCK_BUTTON_BRIGHT;
break;
casePowerManager.SCREEN_BRIGHT_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_SCREEN_BRIGHT;
break;
casePowerManager.SCREEN_DIM_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_SCREEN_DIM;
break;
casePowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
//距离传感器相关
mWakeLockSummary|=WAKE_LOCK_PROXIMITY_SCREEN_OFF;
break;
casePowerManager.DOZE_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_DOZE;
break;
}
}
//Cancelwakelocksthatmakenosensebasedonthecurrentstate.
if(mWakefulness!
=WAKEFULNESS_DOZING){//下面根据各种状态,将上面或上的mWakeLockSummary,有的减去
mWakeLockSummary&=~WAKE_LOCK_DOZE;
}
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;
}
}
//Inferimpliedwakelockswherenecessarybasedonthecurrentstate.
if((mWakeLockSummary&(WAKE_LOCK_SCREEN_BRIGHT|WAKE_LOCK_SCREEN_DIM))!
=0){//只要有屏幕锁,cpu锁必须持有
if(mWakefulness==WAKEFULNESS_AWAKE){
mWakeLockSummary|=WAKE_LOCK_CPU|WAKE_LOCK_STAY_AWAKE;
}elseif(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]viewplaincopy
privatevoidupdateUs