and51PowerManagerService深入分析三updatePowerStateLocked函数Word文件下载.docx
《and51PowerManagerService深入分析三updatePowerStateLocked函数Word文件下载.docx》由会员分享,可在线阅读,更多相关《and51PowerManagerService深入分析三updatePowerStateLocked函数Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
![and51PowerManagerService深入分析三updatePowerStateLocked函数Word文件下载.docx](https://file1.bdocx.com/fileroot1/2023-1/4/932432fa-650b-4f93-8ce2-8a449033737c/932432fa-650b-4f93-8ce2-8a449033737c1.gif)
updateIsPoweredLocked函数,先是要dirty有DIRTY_BATTERY_STATE标志位。
我们在下面分析下,什么时候会有这个标志位
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();
=mIsPowered||oldLevelLow!
=mBatteryLevelLow){
if(oldLevelLow!
=mBatteryLevelLow&
&
!
mBatteryLevelLow){
resettinglowpowersnooze"
mAutoLowPowerModeSnoozing=false;
updateLowPowerModeLocked();
//更新低功耗模式
}
首先systemReady函数最终会把mDirty置位为DIRTY_BATTERY_STATE,还有收BatterySevice发出来的广播,最总也会置这个标志位。
privatefinalclassBatteryReceiverextendsBroadcastReceiver{
@Override
publicvoidonReceive(Contextcontext,Intentintent){
synchronized(mLock){
handleBatteryStateChangedLocked();
privatevoidhandleBatteryStateChangedLocked(){
mDirty|=DIRTY_BATTERY_STATE;
updatePowerStateLocked();
再来看看电池状态发生什么变化要唤醒设备:
privatebooleanshouldWakeUpWhenPluggedOrUnpluggedLocked(
booleanwasPowered,intoldPlugType,booleandockedOnWirelessCharger){
//Don'
twakewhenpoweredunlessconfiguredtodoso.
mWakeUpWhenPluggedOrUnpluggedConfig){//如果资源中没有配置这项,直接退出不唤醒设备
returnfalse;
twakewhenundockedfromwirelesscharger.
//SeeWirelessChargerDetectorforjustification.
if(wasPowered&
mIsPowered
&
oldPlugType==BatteryManager.BATTERY_PLUGGED_WIRELESS){//这是一个拔出的工作,然后之前的无线充电
twakewhendockedonwirelesschargerunlesswearecertainofit.
wasPowered&
mIsPowered
mPlugType==BatteryManager.BATTERY_PLUGGED_WIRELESS//插入动作,现在是无线充电
dockedOnWirelessCharger){
//Ifalreadydreamingandbecomingpowered,thendon'
twake.
if(mIsPowered&
mWakefulness==WAKEFULNESS_DREAMING){//正在充电,但是mWakefulness是做梦状态
twakewhiletheatermodeisenabled.
if(mTheaterModeEnabled&
mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig){
//Otherwisewakeup!
returntrue;
//其他就唤醒设备
继续分析updatePowerStateLocked函数,分析updateStayOnLocked函数。
一般这个函数mStatyon为fasle,除非在资源中设置哪种充电状态下可以长亮。
privatevoidupdateStayOnLocked(intdirty){
(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函数,这个函数是更新屏幕是否保持最亮状态
privatevoidupdateScreenBrightnessBoostLocked(intdirty){
DIRTY_SCREEN_BRIGHTNESS_BOOST)!
=0){//这个状态实在boostScreenBrightnessInternal函数中设置最亮时置位,当然下面发送消息MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT也会将这个标志位置位
if(mScreenBrightnessBoostInProgress){//当前正在最亮屏幕这个状态
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后,重新再回到这个函数
mScreenBrightnessBoostInProgress=false;
//回到这个函数时,直接将这个屏幕最亮状态的标志位改成false
userActivityNoUpdateLocked(now,//触发一个userActivity
PowerManager.USER_ACTIVITY_EVENT_OTHER,0,Process.SYSTEM_UID);
下面看看MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT消息的处理函数。
caseMSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
handleScreenBrightnessBoostTimeout();
break;
privatevoidhandleScreenBrightnessBoostTimeout(){//runsonhandlerthread
handleScreenBrightnessBoostTimeout"
mDirty|=DIRTY_SCREEN_BRIGHTNESS_BOOST;
接下来看updatePowerStateLocked函数的另一个阶段:
//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);
updateWakefulnessLocked(dirtyPhase1)){
先看下updateWakeLockSummaryLocked函数,更新wakelock的函数
privatevoidupdateWakeLockSummaryLocked(intdirty){
(DIRTY_WAKE_LOCKS|DIRTY_WAKEFULNESS))!
mWakeLockSummary=0;
finalintnumWakeLocks=mWakeLocks.size();
for(inti=0;
i<
numWakeLocks;
i++){
finalWakeLockwakeLock=mWakeLocks.get(i);
switch(wakeLock.mFlags&
PowerManager.WAKE_LOCK_LEVEL_MASK){//先根据wakelock的flag,mWakeLockSummary或上各种状态
casePowerManager.PARTIAL_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_CPU;
casePowerManager.FULL_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_SCREEN_BRIGHT|WAKE_LOCK_BUTTON_BRIGHT;
casePowerManager.SCREEN_BRIGHT_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_SCREEN_BRIGHT;
casePowerManager.SCREEN_DIM_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_SCREEN_DIM;
casePowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
//距离传感器相关
mWakeLockSummary|=WAKE_LOCK_PROXIMITY_SCREEN_OFF;
casePowerManager.DOZE_WAKE_LOCK:
mWakeLockSummary|=WAKE_LOCK_DOZE;
//Cancelwakelocksthatmakenosensebasedonthecurrentstate.
if(mWakefulness!
=WAKEFULNESS_DOZING){//下面根据各种状态,将上面或上的mWakeLockSummary,有的减去
mWakeLockSummary&
=~WAKE_LOCK_DOZE;
if(mWakefulness==WAKEFULNESS_ASLEEP
||(mWakeLockSummary&
WAKE_LOCK_DOZE)!
=~(WAKE_LOCK_SCREEN_BRIGHT|WAKE_LOCK_SCREEN_DIM
|WAKE_LOCK_BUTTON_BRIGHT);
if(mWakefulness==WAKEFULNESS_ASLEEP){
=~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){
updateWakeLockSummaryLocked:
mWakefulness="
+PowerManagerInternal.wakefulnessToString(mWakefulness)
mWakeLockSummary=0x"
+Integer.toHexString(mWakeLockSummary));
下面分析下updateUserActivitySummaryLocked函数
privatevoidupdateUs