
Android PowerState
PowerState 是 PowerManagerService(PMS)中描述设备电源状态的核心数据结构,它像一个"状态快照",集中存储了屏幕、CPU、休眠、亮度等关键电源属性,是 PMS 决策设备电源行为的核心依据。
PowerState 是什么?
PowerState 是 Android Framework 层(Java)定义的不可变数据载体,专门用于封装设备当前或目标的电源状态信息。它并非服务或逻辑类,而是一个纯数据类(POJO),核心作用是:
- 统一存储电源相关的状态参数(如屏幕是否亮、亮度等级、休眠状态);
- 作为 PMS 中
updatePowerStateLocked()方法的输入/输出,传递状态信息; - 简化状态判断逻辑,避免分散的状态变量导致的逻辑混乱。
PowerState 的代码位于 frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java(内部静态类),是 PMS 实现"状态驱动"的基础。
核心代码实现
1. 基础定义(Java 层)
PowerState 作为 PMS 的内部静态类存在,核心字段覆盖了设备电源的关键维度,以下是简化后的核心实现:
java
// PowerManagerService 内部的 PowerState 核心定义
private static final class PowerState {
// 1. 屏幕核心状态
boolean screenOn; // 屏幕是否点亮(true=亮,false=灭)
boolean screenBright; // 屏幕是否处于高亮度模式(区别于低亮/息屏)
int screenBrightness; // 屏幕亮度值(0-255,对应系统亮度等级)
int screenAutoBrightness; // 自动亮度模式下的计算值(-1 表示未启用自动亮度)
// 2. 休眠/唤醒状态
boolean deviceIdle; // 设备是否进入空闲休眠(Doze 模式)
boolean wakefulness; // 设备唤醒状态(WAKEFULNESS_AWAKE/ASLEEP/DOZING 等)
long sleepTimeout; // 距离自动休眠的剩余时间(ms)
// 3. 功耗模式相关
boolean lowPowerMode; // 是否启用低功耗模式(省电模式)
int batteryLevel; // 当前电池电量(0-100)
boolean isCharging; // 是否处于充电状态
// 4. 唤醒锁相关(简化)
boolean hasWakeLock; // 是否有活跃的唤醒锁阻止休眠
String wakeLockReason; // 持有唤醒锁的原因(如"前台应用""充电")
// 构造方法:初始化默认状态
public PowerState() {
// 默认状态:屏幕亮、非空闲、非低功耗、无唤醒锁
screenOn = true;
screenBright = true;
screenBrightness = 255; // 最大亮度
deviceIdle = false;
wakefulness = WAKEFULNESS_AWAKE;
lowPowerMode = false;
hasWakeLock = false;
}
// 拷贝方法:生成新的 PowerState(避免直接修改原对象)
public PowerState copy() {
PowerState newState = new PowerState();
newState.screenOn = this.screenOn;
newState.screenBright = this.screenBright;
newState.screenBrightness = this.screenBrightness;
newState.deviceIdle = this.deviceIdle;
newState.wakefulness = this.wakefulness;
newState.lowPowerMode = this.lowPowerMode;
newState.hasWakeLock = this.hasWakeLock;
newState.wakeLockReason = this.wakeLockReason;
return newState;
}
// 状态对比:判断两个 PowerState 是否一致(用于检测状态变化)
public boolean equals(PowerState other) {
if (other == null) return false;
return screenOn == other.screenOn
&& screenBrightness == other.screenBrightness
&& wakefulness == other.wakefulness
&& lowPowerMode == other.lowPowerMode;
}
}
2. 关键字段详解
| 字段名 | 类型 | 核心含义 | 取值示例 |
|---|---|---|---|
screenOn |
boolean | 屏幕基础状态 | true(亮屏)/false(息屏) |
screenBrightness |
int | 屏幕亮度值 | 0(最暗)~255(最亮) |
wakefulness |
int | 设备唤醒级别 | WAKEFULNESS_AWAKE(唤醒)、WAKEFULNESS_ASLEEP(休眠)、WAKEFULNESS_DOZING(浅休眠/Doze) |
deviceIdle |
boolean | 空闲休眠状态 | true(Doze 模式)/false(正常状态) |
lowPowerMode |
boolean | 低功耗模式 | true(省电模式开启)/false(正常模式) |
hasWakeLock |
boolean | 唤醒锁状态 | true(有应用持有唤醒锁)/false(无唤醒锁) |
3. PowerState 的核心方法
PowerState 作为数据载体,核心方法集中在对象拷贝 和状态对比,这是因为 PMS 中需要频繁生成"目标状态"并与"当前状态"对比,避免直接修改原状态导致的逻辑混乱:
copy():生成当前状态的深拷贝,用于构建"目标状态"(PMS 会先基于当前状态拷贝出新对象,再修改字段得到目标状态);equals():对比两个 PowerState 是否一致,用于判断是否需要执行状态变更(如屏幕亮度/开关的实际操作)。
在 PMS 中的核心应用
PowerState 并非孤立存在,而是 PMS 核心方法 updatePowerStateLocked() 的核心交互对象,以下是其完整应用流程:
1. 初始化默认状态
PMS 启动时会创建初始的 PowerState 对象,作为设备的默认电源状态:
java
// PMS 初始化时创建默认 PowerState
private PowerState mCurrentPowerState; // 当前电源状态
private PowerState mTargetPowerState; // 目标电源状态
@Override
public void onStart() {
// 初始化当前状态为默认值(屏幕亮、最大亮度、非休眠)
mCurrentPowerState = new PowerState();
}
2. 构建目标状态
在 updatePowerStateLocked() 中,PMS 会基于当前状态、唤醒锁、充电状态等,构建目标 PowerState:
java
// PMS 核心方法:更新电源状态(简化版)
private void updatePowerStateLocked() {
// 1. 拷贝当前状态,生成目标状态(避免直接修改当前状态)
mTargetPowerState = mCurrentPowerState.copy();
// 2. 根据外部条件修改目标状态
// 2.1 检查唤醒锁:有唤醒锁则保持屏幕亮
boolean hasActiveWakeLock = checkWakeLocksLocked();
mTargetPowerState.hasWakeLock = hasActiveWakeLock;
if (hasActiveWakeLock) {
mTargetPowerState.screenOn = true;
mTargetPowerState.wakefulness = WAKEFULNESS_AWAKE;
}
// 2.2 检查充电状态:充电时调整亮度
boolean isCharging = mBatteryService.isCharging();
mTargetPowerState.isCharging = isCharging;
if (isCharging) {
mTargetPowerState.screenBrightness = Math.min(200, mTargetPowerState.screenBrightness);
}
// 2.3 检查低功耗模式:省电模式下降低亮度、关闭高亮
if (mTargetPowerState.lowPowerMode) {
mTargetPowerState.screenBright = false;
mTargetPowerState.screenBrightness = 50; // 低亮度值
}
// 3. 对比当前状态与目标状态,判断是否需要执行操作
if (!mCurrentPowerState.equals(mTargetPowerState)) {
applyPowerStateLocked(mTargetPowerState);
// 更新当前状态为目标状态
mCurrentPowerState = mTargetPowerState.copy();
}
}
3. 应用目标状态
applyPowerStateLocked() 方法会根据 PowerState 中的字段,执行实际的硬件操作(如亮灭屏、调整亮度):
java
// 应用 PowerState 到硬件
private void applyPowerStateLocked(PowerState targetState) {
// 1. 处理屏幕开关
if (targetState.screenOn != mCurrentPowerState.screenOn) {
setScreenStateLocked(targetState.screenOn);
}
// 2. 处理屏幕亮度
if (targetState.screenBrightness != mCurrentPowerState.screenBrightness) {
setScreenBrightnessLocked(targetState.screenBrightness);
}
// 3. 处理低功耗模式
if (targetState.lowPowerMode != mCurrentPowerState.lowPowerMode) {
setLowPowerModeLocked(targetState.lowPowerMode);
}
// 4. 处理休眠状态
if (targetState.wakefulness != mCurrentPowerState.wakefulness) {
setWakefulnessLocked(targetState.wakefulness);
}
}
设计特点
1. 不可变思想(准不可变)
PowerState 虽未声明为 final,但设计上遵循"不可变"原则:
- 没有提供字段的
setter方法,外部需通过copy()生成新对象后修改; - PMS 中始终通过"拷贝-修改-替换"的方式更新状态,避免多线程下的状态混乱。
2. 状态聚合
将分散的电源状态(屏幕、亮度、休眠、功耗、唤醒锁)聚合到一个类中,解决了以下问题:
- 避免 PMS 中出现大量零散的状态变量(如
mScreenOn、mBrightness、mLowPower等); - 简化状态对比逻辑(只需调用
equals()即可判断整体状态是否变化); - 便于调试:可直接打印整个
PowerState对象,查看所有电源状态信息。
3. 与 Native 层的衔接
PowerState 仅存在于 Java 层,其字段最终会被转换为 Native 层的参数,通过 JNI 传递到底层:
java
// 示例:将 PowerState 中的屏幕状态传递到 Native 层
private void setScreenStateLocked(boolean on) {
if (on) {
// 传递 wakefulness 状态到 Native 层
mPowerManager.wakeUp(SystemClock.uptimeMillis(), "screen_on", mCurrentPowerState.wakeLockReason);
} else {
mPowerManager.goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0);
}
}
PowerState 与其他电源类的关系
| 类名 | 与 PowerState 的关系 | 核心区别 |
|---|---|---|
PowerManagerService |
依赖 PowerState 存储/传递状态 | PMS 是逻辑类,负责状态计算;PowerState 是数据类,负责状态存储 |
WakeLock |
其状态会更新到 PowerState 的 hasWakeLock 字段 |
WakeLock 是"状态触发器",PowerState 是"状态结果" |
NativePowerManager |
接收 PowerState 中的字段作为参数 | NativePowerManager 是"执行层",PowerState 是"配置层" |
总结
- PowerState 是电源状态的"数据容器":聚合了屏幕、亮度、休眠、功耗等核心状态字段,是 PMS 中状态传递的核心载体;
- 核心设计是"拷贝-修改-对比-应用":PMS 不会直接修改当前 PowerState,而是通过拷贝生成目标状态,对比后再应用,保证状态变更的安全性;
- 仅存在于 Java 层 :PowerState 是 Framework 层的抽象状态,其字段最终会被转换为 Native 层的指令,驱动硬件状态变更。
