Android 8.1 PowerManagerService分析(二) ——updatePowerStateLocked()方法

本文深入分析了Android 8.1 PowerManagerService中的核心方法`updatePowerStateLocked()`,详细讲解了其内部调用的各个子方法,包括`updateIsPoweredLocked()`、`updateStayOnLocked()`、`updateScreenBrightnessBoostLocked()`等,这些方法涉及电源状态更新、屏幕亮度、用户活动和唤醒锁的管理。通过对这些方法的分析,揭示了PowerManagerService如何处理系统电源状态变化并作出相应调整。
摘要由CSDN通过智能技术生成

欢迎大家关注我的掘金帐号
我会在那里定期更新最新版本的Android Framework源码模块分析~~

Android 8.1 PowerManagerService分析(一)中对PMS的启动流程进行了分析,本篇对PMS中的一些核心方法进行分析。

1.2.updatePowerStateLocked方法详解

接着上文分析,在systemReady()方法的最后,调用了updatePowerStateLocked()方法:

public void systemReady(IAppOpsService appOps) {
   
synchronized (mLock) {
   
    mSystemReady = true;
    ........
    mDirty |= DIRTY_BATTERY_STATE;
    updatePowerStateLocked();
}

updatePowerStateLocked()方法是整个PMS中的核心方法,也是整个PSM中最重要的一个方法,它用来更新整个电源状态的改变,并进行重新计算。PMS中使用一个int值mDirty作为标志位判断电源状态是否发生变化,当电源状态发生改变时,如亮灭屏、电池状态改变、暗屏…都会调用该方法,在该方法中调用了其他同级方法进行更新,下面逐个进行分析,先看其代码:

private void updatePowerStateLocked() {
   
    if (!mSystemReady || mDirty == 0) {
   
	   return;
        }
	try {
   
	// Phase 0: Basic state updates.
	//更新电池信息
	updateIsPoweredLocked(mDirty);
	//更新屏幕保持唤醒标识值mStayOn
	updateStayOnLocked(mDirty);
	//亮度增强相关
	updateScreenBrightnessBoostLocked(mDirty);
	
	final long now = SystemClock.uptimeMillis();
	int dirtyPhase2 = 0;
	for (;;) {
   
	    int dirtyPhase1 = mDirty;
	    dirtyPhase2 |= dirtyPhase1;
	    mDirty = 0;
	    //更新统计wakelock的标记值mWakeLockSummary
	    updateWakeLockSummaryLocked(dirtyPhase1);
	    //更新统计userActivity的标记值mUserActivitySummary和休眠到达时间
	    updateUserActivitySummaryLocked(now, dirtyPhase1);
	    //用来更新屏幕唤醒状态,状态改变返回true
	    if (!updateWakefulnessLocked(dirtyPhase1)) {
   
	        break;
	    }
	}
	// Phase 2: Update display power state.
	//和Display交互,请求Display状态
	boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
	// Phase 3: Update dream state (depends on display ready signal).
	//更新屏保
	updateDreamLocked(dirtyPhase2, displayBecameReady);
	// Phase 4: Send notifications, if needed.
	//如果wakefulness改变,做最后的收尾工作
	finishWakefulnessChangeIfNeededLocked();
	// Phase 5: Update suspend blocker.
	// Because we might release the last suspend blocker here, we need to make 
	//surewe finished everything else first!
	//更新Suspend锁
	updateSuspendBlockerLocked();
	} finally {
   
	    Trace.traceEnd(Trace.TRACE_TAG_POWER);
	}
}

如果没有进行特定场景的分析,这块可能很难理解,在后续的分析中会对特定场景进行分析,这样更能理解方法的使用,如果这里还不太理解,不用太担心。

在整个方法中,当系统没有准备就绪或者mDirty没有进行置位时,不会执行后续步骤,直接return;接下来对该方法中的内容进行分析,由于此方法非常重要,因此这里将所有的方法都贴出来。

1.2.1.updateIsPoweredLocker()

这个方法主要功能有两个:

  • 1.USB插播亮屏入口点;
  • 2.更新低电量模式;

该方法如下:

/**
* 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;//是否处于低电量
/*---------------------BatteryService交互Begin-----------------------------*/
mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.
                         BATTERY_PLUGGED_ANY);
mPlugType = mBatteryManagerInternal.getPlugType();
mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();
/*---------------------BatteryService交互 End-----------------------------*/
//充电状态改变
if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
   
    mDirty |= DIRTY_IS_POWERED;
    //是否连接无线充电
    final boolean dockedOnWirelessCharger = 
           mWirelessChargerDetector.update(
            mIsPowered, mPlugType, mBatteryLevel);
    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);
    if (dockedOnWirelessCharger) {
   
        mNotifier.onWirelessChargingStarted();
    }
}
//上次是否充电和当前是否充电不同||上次电量是否处于低电量和当前是否处于
//低电量不同
if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
   
    //上次处于低电量&&当前不处于低电量
    if (oldLevelLow != mBatteryLevelLow && !mBatteryLevelLow) {
   
        //当电池处于低电量模式触发值时,用户是否关闭了低电量模式
        mAutoLowPowerModeSnoozing = false;
    }
    //更新低电量模式
    updateLowPowerModeLocked();
      }
    }
}

从代码中看出,只有满足mDirty&DIRTY_BATTERY_STATE!=0时才会执行这个方法,满足此条件的有两处:

  • 第一处:在调用systemServer()方法中:
public void systemReady(IAppOpsService appOps) {
   
    .................
    mDirty |= DIRTY_BATTERY_STATE;
    updatePowerStateLocked();
    .................
}
  • 第二处:在监听电量状态改变的广播中:
//监听ACTION_BATTERY_CHANGED
private final class BatteryReceiver extends BroadcastReceiver {
   
    @Override
    public void onReceive(Context context, Intent intent) {
   
        synchronized (mLock) {
   
        //设置mDirty |= DIRTY_BATTERY_STAT
        handleBatteryStateChangedLocked();
      }
   }
}

因此可以看到,这个方法跟电池有关,只要电池状态发生变化,就能够调用执行到这个方法进行操作。

在这个方法中,通过BatteryService的本地服务BatteryManagerInternal,和BatteryService进行交互,刷新电池信息,并记录上次的电池数据;然后判断是插拔USB是否需要唤醒屏幕。我们在插拔USB时,可以唤醒屏幕就是从这里为入口进行唤醒的。然后更新用户活动事件;之后会处理低电量时的操作,

  • 11
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值