04-05-09 深入理解Android内核设计思想 第9章:Android电源管理
04-05-09 深入理解Android内核设计思想 第9章:Android电源管理
核心知识点速查
1. Android电源管理架构(Android 16 / API 36)
┌─────────────────────────────────────────────┐
│ Application (Java) │ ← PowerManager, WakeLock, BatteryManager
│ │ ← Adaptive Battery / Charging APIs
│ │ ← BatteryHealthManager (API 36+)
├─────────────────────────────────────────────┤
│ PowerManagerService (Java) │ ← 电源管理服务核心
│ ├── DeviceIdleController │ ← Doze / App Standby Buckets
│ ├── AdaptiveBatteryController │ ← ML 驱动的电池优化
│ ├── AdaptiveChargingController │ ← 自适应充电控制
│ ├── ThermalStatusListener │ ← 热状态监听
│ └── frameworks/base/services/core/ │
│ java/com/android/server/power/ │
├─────────────────────────────────────────────┤
│ Native PowerManager (C++) │ ← Native 层电源管理
│ └── frameworks/native/services/ │
│ powermanager/ │
├─────────────────────────────────────────────┤
│ HAL 层(AIDL 接口) │
│ ├── IPower.aidl (Power HAL AIDL) │ ← 替代 HIDL,标准化电源控制
│ ├── IThermal.aidl (Thermal HAL AIDL) │ ← 热管理硬件抽象
│ └── IBattery.aidl (Battery HAL AIDL) │ ← 电池状态抽象
├─────────────────────────────────────────────┤
│ Linux Power Management (内核层) │ ← 内核电源管理
│ ├── /sys/power/state │
│ ├── /sys/power/wake_lock │
│ ├── /sys/power/wake_unlock │
│ ├── /proc/pressure/ (PSI) │ ← 压力 stall 信息
│ └── drivers/thermal/ │ ← 内核热管理
├─────────────────────────────────────────────┤
│ Hardware (CPU, GPU, Display, Battery, etc.) │
└─────────────────────────────────────────────┘
2. Android 电源状态(Android 16)
Android 电源状态
├── Screen On(屏幕亮)
│ ├── Interactive(交互状态)
│ ├── 所有服务正常运行
│ ├── CPU/GPU 按需调度(EAS 调度器)
│ └── Thermal 监控激活
├── Screen Off(屏幕灭)
│ ├── Doze Mode(打盹模式)
│ │ ├── App Standby Buckets 限制后台应用
│ │ ├── 延迟 Job / Alarm / 网络
│ │ └── 周期性维护窗口(自适应间隔)
│ └── Light Doze(浅度打盹,短时间息屏后进入)
├── Deep Sleep(深度睡眠)
│ ├── CPU 挂起(Suspend)
│ ├── 只保留基本硬件(RTC、Modem、唤醒源)
│ └── 功耗最低(<10mA)
├── Adaptive Charging(自适应充电中)
│ ├── 充电速率智能调节
│ ├── 延缓满充减少电池老化
│ └── 基于用户习惯预测起床时间
└── Shutdown(关机)
└── 完全断电
3. WakeLock 机制
WakeLock(唤醒锁)
├── 防止系统休眠
├── 类型(Android 16):
│ ├── PARTIAL_WAKE_LOCK(CPU 保持运行,屏幕可灭)⭐ 最常用
│ ├── DOZE_WAKE_LOCK(允许进入 Doze,但不完全休眠)
│ ├── DRAW_WAKE_LOCK(屏幕绘制时保持唤醒)
│ ├── SCREEN_BRIGHT_WAKE_LOCK(已废弃,仅兼容性保留)
│ └── FULL_WAKE_LOCK(已废弃,完全无效)
├── 使用场景:
│ ├── 音乐播放
│ ├── 下载任务
│ ├── 后台录像(T8000)
│ └── 推送消息处理
└── 最佳实践:
├── 设置超时 acquire(timeoutMs)
├── 使用 try-finally 确保释放
└── 使用 WorkManager 替代长时间 WakeLock
WakeLock 详解(与之前笔记关联)
1. WakeLock 使用示例
// Java 层使用 WakeLock
public class RecordingService extends Service {
private PowerManager.WakeLock wakeLock;
@Override
public void onCreate() {
super.onCreate();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
// 创建 WakeLock(PARTIAL_WAKE_LOCK:CPU 运行,屏幕可灭)
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"RecordingService::WakeLock");
// 设置超时自动释放(可选,防止泄漏)
wakeLock.acquire(10 * 60 * 1000L); // 10 分钟
}
public void startRecording() {
// 获取 WakeLock
if (!wakeLock.isHeld()) {
wakeLock.acquire();
}
// 开始录像...
}
public void stopRecording() {
// 释放 WakeLock
if (wakeLock.isHeld()) {
wakeLock.release();
}
// 停止录像...
}
@Override
public void onDestroy() {
if (wakeLock.isHeld()) {
wakeLock.release();
}
super.onDestroy();
}
}
Android 16 注意:Google 推荐优先使用
WorkManager而非直接持有 WakeLock。WorkManager 内部自动管理 WakeLock 的生命周期,更加安全可靠。
详细内容参考之前的笔记:WakeLock 机制
2. WakeLock 内核实现
// kernel/power/wakelock.c
struct wakelock {
struct list_head link;
char name[64];
unsigned long expires; // 超时时间
bool active;
};
static LIST_HEAD(active_wakelocks);
static DEFINE_SPINLOCK(wakelock_lock);
// 申请 WakeLock
void wake_lock(struct wakelock* lock)
{
unsigned long flags;
spin_lock_irqsave(&wakelock_lock, flags);
if (!lock->active) {
lock->active = true;
list_add(&lock->link, &active_wakelocks);
// 阻止系统休眠
__pm_stay_awake(&lock->ws);
}
spin_unlock_irqrestore(&wakelock_lock, flags);
}
// 释放 WakeLock
void wake_unlock(struct wakelock* lock)
{
unsigned long flags;
spin_lock_irqsave(&wakelock_lock, flags);
if (lock->active) {
lock->active = false;
list_del(&lock->link);
// 允许系统休眠(如果没有其他 WakeLock)
__pm_relax(&lock->ws);
}
spin_unlock_irqrestore(&wakelock_lock, flags);
}
// sysfs 接口
// echo "my_wakelock" > /sys/power/wake_lock
// echo "my_wakelock" > /sys/power/wake_unlock
PowerManagerService 详解(Android 16 更新)
PowerManagerService 核心功能
// frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public final class PowerManagerService extends SystemService {
// 电源状态(Android 16)
private static final int POWER_STATE_AWAKE = 0;
private static final int POWER_STATE_DOZING = 1;
private static final int POWER_STATE_ASLEEP = 2;
private int mWakefulness; // 当前唤醒状态
// Android 16 新增:自适应电池控制器
private AdaptiveBatteryController mAdaptiveBattery;
// Android 16 新增:自适应充电控制器
private AdaptiveChargingController mAdaptiveCharging;
// Android 16 新增:热状态监听
private ThermalStatusListener mThermalListener;
// WakeLock 列表
private final ArrayList<WakeLock> mWakeLocks = new ArrayList<>();
// 获取 WakeLock
public void acquireWakeLock(IBinder lock, int flags, String tag,
String packageName, WorkSource ws) {
synchronized (mLock) {
WakeLock wakeLock = findWakeLockLocked(lock);
if (wakeLock == null) {
wakeLock = new WakeLock(lock, flags, tag, packageName, ws);
mWakeLocks.add(wakeLock);
}
applyWakeLockLocked(wakeLock);
}
}
// 释放 WakeLock
public void releaseWakeLock(IBinder lock, int flags) {
synchronized (mLock) {
WakeLock wakeLock = findWakeLockLocked(lock);
if (wakeLock != null) {
mWakeLocks.remove(wakeLock);
updateWakeLockSummaryLocked();
}
}
}
// 更新电源状态(Android 16 增强版)
private void updatePowerStateLocked() {
// 检查是否有 WakeLock
boolean hasPartialWakeLock = false;
boolean hasFullWakeLock = false;
for (WakeLock wl : mWakeLocks) {
if ((wl.mFlags & PowerManager.PARTIAL_WAKE_LOCK) != 0) {
hasPartialWakeLock = true;
}
if ((wl.mFlags & PowerManager.FULL_WAKE_LOCK) != 0) {
hasFullWakeLock = true;
}
}
// Android 16 新增:检查热状态
// 如果 Thermal HAL 报告温度过高,即使有 WakeLock 也限制性能
if (mThermalListener.isThermalThrottling()) {
// 通知 Power HAL 降频
nativeSetPowerMode(POWER_MODE_THERMAL_THROTTLE);
}
// 决定是否允许休眠
if (hasPartialWakeLock || hasFullWakeLock) {
// 阻止休眠
nativeAcquireSuspendBlocker("PowerManagerService");
} else {
// 允许休眠
nativeReleaseSuspendBlocker("PowerManagerService");
}
}
// 休眠
public void goToSleep(long eventTime, int reason, int flags) {
synchronized (mLock) {
mWakefulness = POWER_STATE_ASLEEP;
// 关闭屏幕
mDisplayPowerController.requestPowerState(...);
// 通知其他服务
mNotifier.onGoToSleep();
// Android 16:通知 DeviceIdleController 进入 Doze
mDeviceIdleController.startMonitoring();
// 触发 Suspend
if (!hasWakeLockLocked()) {
nativeSuspend();
}
}
}
// 唤醒
public void wakeUp(long eventTime, int reason, String opPackageName) {
synchronized (mLock) {
mWakefulness = POWER_STATE_AWAKE;
// 唤醒屏幕
mDisplayPowerController.requestPowerState(...);
// 通知其他服务
mNotifier.onWakeUp();
// Android 16:退出 Doze,恢复后台任务
mDeviceIdleController.exitIdle();
}
}
// Android 16 新增:自适应充电状态查询
public AdaptiveChargingState getAdaptiveChargingState() {
return mAdaptiveCharging.getState();
}
// Native 方法
private static native void nativeAcquireSuspendBlocker(String name);
private static native void nativeReleaseSuspendBlocker(String name);
private static native void nativeSuspend();
private static native void nativeSetPowerMode(int mode);
}
Suspend/Resume 机制
1. Linux Suspend 流程
用户空间触发休眠
↓
PowerManagerService.goToSleep()
↓
写入 /sys/power/state
↓
内核 suspend_prepare()
├── 冻结用户空间进程
├── 同步文件系统
└── 准备设备休眠
↓
suspend_devices_and_enter()
├── 调用所有驱动的 .suspend()
├── 关闭外设
└── 保存设备状态
↓
suspend_enter()
├── 关闭非启动 CPU
├── 禁用中断
└── 进入 CPU 休眠状态(WFI)
↓
[深度睡眠] (功耗<10mA)
↓
中断唤醒(如 RTC、按键、Modem、网络 WoL)
↓
resume_enter()
├── 启用中断
├── 启动非启动 CPU
└── 恢复 CPU 状态
↓
resume_devices()
├── 调用所有驱动的 .resume()
├── 恢复设备状态
└── 重新初始化外设
↓
恢复用户空间进程
↓
系统恢复运行
2. 驱动中实现 Suspend/Resume
// drivers/video/fbdev/T8000_fb.c
static int T8000_fb_suspend(struct device* dev)
{
struct fb_info* info = dev_get_drvdata(dev);
struct T8000_fb_data* data = info->par;
pr_info("Framebuffer suspending\n");
// 保存寄存器状态
data->saved_regs.ctrl = readl(data->regs + LCD_CTRL_REG);
data->saved_regs.timing = readl(data->regs + LCD_TIMING_REG);
// 关闭 LCD
writel(0, data->regs + LCD_CTRL_REG);
// 关闭时钟
clk_disable_unprepare(data->clk);
return 0;
}
static int T8000_fb_resume(struct device* dev)
{
struct fb_info* info = dev_get_drvdata(dev);
struct T8000_fb_data* data = info->par;
pr_info("Framebuffer resuming\n");
// 启动时钟
clk_prepare_enable(data->clk);
// 恢复寄存器
writel(data->saved_regs.ctrl, data->regs + LCD_CTRL_REG);
writel(data->saved_regs.timing, data->regs + LCD_TIMING_REG);
// 重新启动 LCD
writel(LCD_ENABLE, data->regs + LCD_CTRL_REG);
return 0;
}
static SIMPLE_DEV_PM_OPS(T8000_fb_pm_ops, T8000_fb_suspend, T8000_fb_resume);
static struct platform_driver T8000_fb_driver = {
.driver = {
.name = "T8000-fb",
.pm = &T8000_fb_pm_ops,
},
};
3. 唤醒源配置
// drivers/input/keyboard/T8000_keys.c
static int T8000_keys_probe(struct platform_device* pdev)
{
// ...
// 配置为唤醒源(按键可唤醒系统)
device_init_wakeup(&pdev->dev, true);
// 使能中断唤醒
enable_irq_wake(key->irq);
return 0;
}
static int T8000_keys_suspend(struct device* dev)
{
// Suspend 时保持中断使能(用于唤醒)
return 0;
}
static int T8000_keys_resume(struct device* dev)
{
// Resume 时处理按键事件
return 0;
}
Power HAL(Android 16 AIDL 版本)
1. Power HAL 从 HIDL 迁移到 AIDL
Android 16 中,Power HAL 已从 HIDL 完全迁移到 AIDL 接口。AIDL 提供了更好的类型安全、跨版本兼容性和更简洁的 API。
// hardware/interfaces/power/aidl/IPower.aidl
/**
* Power HAL AIDL 接口(Android 16)
* 替代了旧的 HIDL IPower@1.x 接口
*/
interface IPower {
/**
* 设置电源模式
* @param type 电源模式类型
* @param enabled 是否启用
*/
void setMode(Mode type, boolean enabled);
/**
* 检查是否支持某个电源模式
*/
bool isModeSupported(Mode type);
/**
* 发送电源提示(性能需求)
* @param hint 提示类型
* @param data 附加数据
*/
void sendPowerHint(Hint hint, int data);
/**
* 设置交互状态(屏幕亮/灭)
*/
void setInteractive(boolean interactive);
/**
* 注册充电回调(用于 Adaptive Charging)
*/
void setChargingState(boolean charging, int chargeLevel);
}
/**
* 电源模式类型(Android 16 扩展)
*/
enum Mode {
LOW_POWER, // 低功耗模式
SUSTAINED_PERFORMANCE, // 持续性能模式
FIXED_PERFORMANCE, // 固定性能
VR_MODE, // VR 模式
INTERACTIVE, // 交互模式
DEVICE_IDLE, // 设备空闲(Doze)
DISPLAY_INACTIVE, // 显示不活跃
THERMAL_THROTTLE, // Android 16 新增:热节流
ADAPTIVE_CHARGING, // Android 16 新增:自适应充电
BOOST_DISPLAY, // Android 16 新增:显示提升
}
/**
* 电源提示类型(Android 16 扩展)
*/
enum Hint {
INTERACTION, // 用户交互
VSYNC, // VSync 信号
VIDEO_ENCODE, // 视频编码
VIDEO_DECODE, // 视频解码
LOW_POWER, // 低功耗
LAUNCH, // 应用启动
AUDIO_STREAMING, // 音频流
CAMERA_LAUNCH, // 相机启动
CAMERA_SHOT, // 相机拍摄
ML_INFERENCE, // Android 16 新增:ML 推理
}
2. Power HAL AIDL 实现示例
// hardware/device/power/aidl/Power.cpp
// Android 16 AIDL 实现
#include <aidl/android/hardware/power/BnPower.h>
#include <aidl/android/hardware/power/Mode.h>
#include <aidl/android/hardware/power/Hint.h>
#include <fstream>
using ::aidl::android::hardware::power::BnPower;
using ::aidl::android::hardware::power::Mode;
using ::aidl::android::hardware::power::Hint;
class Power : public BnPower {
public:
// CPU 频率控制
ndk::ScopedAStatus setMode(Mode type, bool enabled) override {
switch (type) {
case Mode::LOW_POWER:
set_cpu_governor(enabled ? "powersave" : "interactive");
set_cpu_max_freq(enabled ? 800000 : 1800000);
ALOGD("Power: LOW_POWER mode %s", enabled ? "ON" : "OFF");
break;
case Mode::SUSTAINED_PERFORMANCE:
set_cpu_governor(enabled ? "schedutil" : "interactive");
set_cpu_max_freq(enabled ? 1500000 : 1800000);
ALOGD("Power: SUSTAINED_PERFORMANCE %s", enabled ? "ON" : "OFF");
break;
case Mode::THERMAL_THROTTLE:
if (enabled) {
// 热节流:强制降频
set_cpu_max_freq(600000); // 限制到 600MHz
set_gpu_max_freq(300000000);
ALOGW("Power: Thermal throttling activated!");
} else {
// 恢复正常频率
set_cpu_max_freq(1800000);
set_gpu_max_freq(800000000);
ALOGD("Power: Thermal throttling released");
}
break;
case Mode::ADAPTIVE_CHARGING:
// 自适应充电模式下的性能调节
set_cpu_max_freq(enabled ? 1200000 : 1800000);
ALOGD("Power: Adaptive charging %s", enabled ? "ON" : "OFF");
break;
case Mode::INTERACTIVE:
set_cpu_governor(enabled ? "interactive" : "schedutil");
ALOGD("Power: Interactive mode %s", enabled ? "ON" : "OFF");
break;
default:
break;
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override {
// 厂商自定义支持的模式
* _aidl_return = (type != Mode::VR_MODE); // T8000 不支持 VR
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus sendPowerHint(Hint hint, int32_t data) override {
switch (hint) {
case Hint::INTERACTION:
set_cpu_governor("interactive");
set_cpu_max_freq(1800000);
ALOGD("Power: Interaction hint");
break;
case Hint::VIDEO_ENCODE:
// T8000 主要场景:视频编码
set_cpu_governor("performance");
set_cpu_max_freq(1800000);
set_gpu_max_freq(800000000);
ALOGD("Power: Video encode hint");
break;
case Hint::LAUNCH:
// 应用启动:短暂提升
set_cpu_boost(data); // data 为 boost 时长 (ms)
ALOGD("Power: Launch hint, boost %dms", data);
break;
case Hint::ML_INFERENCE:
// Android 16 新增:ML 推理性能提升
enable_npu_boost(data > 0);
ALOGD("Power: ML inference hint");
break;
default:
break;
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus setInteractive(bool interactive) override {
if (interactive) {
set_cpu_governor("interactive");
set_cpu_max_freq(1800000);
set_gpu_max_freq(800000000);
ALOGD("Power: Interactive");
} else {
set_cpu_governor("schedutil");
set_cpu_max_freq(1200000);
set_gpu_max_freq(400000000);
ALOGD("Power: Non-interactive");
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus setChargingState(bool charging, int32_t chargeLevel) override {
if (charging) {
ALOGD("Power: Charging at %d%%", chargeLevel);
// 充电时允许更高性能
set_cpu_max_freq(1800000);
}
return ndk::ScopedAStatus::ok();
}
private:
void set_cpu_governor(const char* gov) {
std::ofstream("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor") << gov;
}
void set_cpu_max_freq(int khz) {
std::ofstream("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq") << khz;
}
void set_gpu_max_freq(int hz) {
std::ofstream("/sys/class/kgsl/kgsl-3d0/max_gpuclk") << hz;
}
void set_cpu_boost(int durationMs) {
// 临时 boost,durationMs 后自动恢复
// ...
}
void enable_npu_boost(bool enable) {
// NPU 性能模式控制
// ...
}
};
3. 与旧版 HIDL 的对比
旧版 HIDL(已废弃)
├── hardware/interfaces/power/1.3/IPower.hal
├── C 风格结构体 (power_module)
├── 手动内存管理
└── 版本兼容复杂
新版 AIDL(Android 16)
├── hardware/interfaces/power/aidl/IPower.aidl
├── C++ 原生类型 + ndk::ScopedAStatus
├── 自动内存管理 + 强类型
├── 向后兼容(AIDL 接口自动版本协商)
└── 支持新增 Mode/Hint 无需大版本升级
电源驱动
1. CPU 频率调节(CPUFreq)
内核层的 CPUFreq 机制在 Android 16 中变化不大,但调度器从 interactive 演进到 schedutil(基于 EAS 能效感知调度)。
// drivers/cpufreq/cpufreq_T8000.c
#include <linux/cpufreq.h>
#include <linux/clk.h>
struct T8000_cpufreq_data {
struct clk* cpu_clk;
struct cpufreq_frequency_table* freq_table;
};
// 频率表
static struct cpufreq_frequency_table T8000_freq_table[] = {
{ .frequency = 600000 }, // 600MHz
{ .frequency = 800000 }, // 800MHz
{ .frequency = 1200000 }, // 1.2GHz
{ .frequency = 1500000 }, // 1.5GHz
{ .frequency = 1800000 }, // 1.8GHz
{ .frequency = CPUFREQ_TABLE_END },
};
// 设置频率
static int T8000_cpufreq_target(struct cpufreq_policy* policy,
unsigned int index)
{
struct T8000_cpufreq_data* data = policy->driver_data;
unsigned long freq = T8000_freq_table[index].frequency * 1000;
// 调整时钟频率
return clk_set_rate(data->cpu_clk, freq);
}
// 初始化
static int T8000_cpufreq_init(struct cpufreq_policy* policy)
{
struct T8000_cpufreq_data* data;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
// 获取 CPU 时钟
data->cpu_clk = clk_get(NULL, "cpu_clk");
if (IS_ERR(data->cpu_clk)) {
kfree(data);
return PTR_ERR(data->cpu_clk);
}
data->freq_table = T8000_freq_table;
policy->driver_data = data;
// 设置频率表
cpufreq_table_validate_and_show(policy, T8000_freq_table);
policy->cur = clk_get_rate(data->cpu_clk) / 1000;
return 0;
}
static struct cpufreq_driver T8000_cpufreq_driver = {
.name = "T8000-cpufreq",
.flags = CPUFREQ_STICKY,
.init = T8000_cpufreq_init,
.verify = cpufreq_generic_frequency_table_verify,
.target_index = T8000_cpufreq_target,
.get = cpufreq_generic_get,
.attr = cpufreq_generic_attr,
};
static int __init T8000_cpufreq_init_module(void)
{
return cpufreq_register_driver(&T8000_cpufreq_driver);
}
module_init(T8000_cpufreq_init_module);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("T8000 CPUFreq Driver");
CPUFreq 调速器(Governor)对比
| 调速器 | 特点 | Android 16 状态 |
|---|---|---|
performance |
始终最高频 | 可用(调试用) |
powersave |
始终最低频 | 可用(低功率模式) |
interactive |
按需快速升频 | 向后兼容,不推荐 |
ondemand |
按需调节 | 向后兼容 |
schedutil |
基于调度器信号,EAS 感知 | Android 16 默认推荐 |
schedutil 利用内核调度器的负载信息直接驱动频率调节,消除了传统 governor 的延迟,配合 EAS(Energy Aware Scheduling)实现功耗和性能的最优平衡。
2. 电池驱动
// drivers/power/supply/T8000_battery.c
// 如果 T8000 有 UPS 或备用电池
#include <linux/power_supply.h>
struct T8000_battery_data {
struct power_supply* battery;
int voltage_mv;
int capacity_percent;
int health; // Android 16 新增:电池健康度
int cycle_count; // Android 16 新增:充放电循环计数
};
// 获取电池属性
static int T8000_battery_get_property(struct power_supply* psy,
enum power_supply_property psp,
union power_supply_propval* val)
{
struct T8000_battery_data* data = power_supply_get_drvdata(psy);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = POWER_SUPPLY_STATUS_CHARGING;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = data->voltage_mv * 1000; // 转换为 uV
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = data->capacity_percent;
break;
// Android 16 新增电池健康属性
case POWER_SUPPLY_PROP_HEALTH:
val->intval = data->health; // GOOD / OVERHEAT / DEAD / UNKNOWN
break;
case POWER_SUPPLY_PROP_CYCLE_COUNT:
val->intval = data->cycle_count;
break;
default:
return -EINVAL;
}
return 0;
}
static enum power_supply_property T8000_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CAPACITY,
// Android 16 新增
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_CYCLE_COUNT,
};
static const struct power_supply_desc T8000_battery_desc = {
.name = "T8000-battery",
.type = POWER_SUPPLY_TYPE_BATTERY,
.properties = T8000_battery_props,
.num_properties = ARRAY_SIZE(T8000_battery_props),
.get_property = T8000_battery_get_property,
};
// probe 函数省略...
与 Framework 层的关联
Doze 模式与 App Standby Buckets(Android 16 增强版)
Doze 模式状态机
// frameworks/base/services/core/java/com/android/server/DeviceIdleController.java
// Doze 模式状态机(Android 16 增强)
public class DeviceIdleController extends SystemService {
// Doze 状态
static final int STATE_ACTIVE = 0; // 活跃
static final int STATE_INACTIVE = 1; // 不活跃
static final int STATE_IDLE_PENDING = 2; // 即将 Idle
static final int STATE_SENSING = 3; // 检测运动
static final int STATE_LOCATING = 4; // 定位
static final int STATE_IDLE = 5; // Idle 状态
static final int STATE_IDLE_MAINTENANCE = 6; // 维护窗口
// Android 16 新增
static final int STATE_OVERRIDE_IDLE = 7; // 被用户交互打断
// 进入 Doze 模式的条件:
// 1. 屏幕关闭
// 2. 未充电(或充电时强制 Doze - Android 16 支持充电时也进入 Doze)
// 3. 静止不动(加速度计)
// 4. 一段时间无用户交互
// 5. Android 16:ML 模型判断用户不太可能近期使用设备
// Doze 模式下的限制:
// 1. 延迟任务(JobScheduler)
// 2. 限制网络访问
// 3. 限制 Alarm(setAndAllowWhileIdle 除外)
// 4. 禁止 GPS 扫描
// 5. 禁止 WiFi 扫描
// 6. Android 16:按 App Standby Bucket 差异化限制
}
App Standby Buckets 详解
Android 16 进一步增强了基于机器学习的 App Standby Buckets 分类机制:
// frameworks/base/services/core/java/com/android/server/usage/
// AppStandbyController.java
// App Standby Buckets(Android 16,5 个桶)
public class AppStandbyController {
// 分桶级别(数值越小,限制越松)
static final int BUCKET_ACTIVE = 0; // 活跃应用(当前前台)
static final int BUCKET_WORKING_SET = 10; // 工作集(经常使用)
static final int BUCKET_FREQUENT = 20; // 频繁使用
static final int BUCKET_RARE = 30; // 很少使用
static final int BUCKET_RESTRICTED = 40; // 受限(Android 16 新增)
static final int BUCKET_NEVER = 50; // 从未使用
// Android 16 新增:基于 ML 的分桶决策
private AppUsagePredictor mUsagePredictor;
// 各桶的限制
void applyBucketRestrictions(String packageName, int bucket) {
switch (bucket) {
case BUCKET_ACTIVE:
// 无限制
break;
case BUCKET_WORKING_SET:
// 允许 Job 和 Alarm,但限制网络
allowJobs(packageName);
restrictNetwork(packageName);
break;
case BUCKET_FREQUENT:
// 每天 1 次维护窗口
allowDailyJob(packageName, 1);
restrictAlarm(packageName);
break;
case BUCKET_RARE:
// 每周 1 次维护窗口
allowWeeklyJob(packageName, 1);
restrictAll(packageName);
break;
case BUCKET_RESTRICTED:
// Android 16 新增:几乎禁止所有后台活动
// 只有高优先级 FCM 消息可唤醒
restrictToFCMOnly(packageName);
break;
case BUCKET_NEVER:
// 完全冻结(仅在存储清理时解冻)
freezeApp(packageName);
break;
}
}
// Android 16:ML 驱动的分桶
int determineBucket(String packageName) {
// 综合以下因素:
// 1. 最近使用时间和频率
// 2. 用户交互模式(使用时间段偏好)
// 3. 通知响应率
// 4. 同类应用使用模式
// 5. 充电状态下的使用习惯
return mUsagePredictor.predictBucket(packageName);
}
}
维护窗口(Maintenance Window)策略
Android 16 维护窗口策略
├── Light Doze(息屏 30 分钟内)
│ ├── 每 15 分钟一次窗口
│ └── 允许 Job / Alarm / 网络
├── Deep Doze(息屏 30 分钟后)
│ ├── 每 2 小时一次窗口(自适应递增)
│ └── 允许 Job / Alarm,限制网络
├── Long Doze(息屏 6 小时后)
│ ├── 每 6 小时一次窗口
│ └── 仅允许高优先级 Job
└── Android 16 自适应策略
├── ML 预测用户下次使用时间
├── 如果预测即将使用,提前 30 分钟解冻常用 App
└── 充电时缩短维护窗口间隔
Adaptive Battery(自适应电池)
Android 16 中的 Adaptive Battery 基于机器学习模型,学习用户的使用习惯,智能限制不常用应用的后台活动。
// frameworks/base/services/core/java/com/android/server/
// power/AdaptiveBatteryController.java
// Adaptive Battery 控制器(Android 16)
public class AdaptiveBatteryController {
// ML 模型:预测应用使用概率
private AppUsagePredictor mPredictor;
// 电池阈值配置
private static final float LOW_PRIORITY_THRESHOLD = 0.1f;
private static final float RESTRICT_THRESHOLD = 0.02f;
// 每日评估
void onDailyEvaluate() {
List<AppUsageStats> stats = getRecentUsageStats();
for (AppUsageStats app : stats) {
// 计算使用概率
float probability = mPredictor.predictUsageProbability(app.packageName);
if (probability < RESTRICT_THRESHOLD) {
// 标记为 Restricted Bucket
setAppBucket(app.packageName, BUCKET_RESTRICTED);
} else if (probability < LOW_PRIORITY_THRESHOLD) {
// 标记为 Rare Bucket
setAppBucket(app.packageName, BUCKET_RARE);
}
}
}
// 电池 saver 模式下的额外限制
void applyBatterySaverRestrictions() {
// 1. 所有非白名单应用进入 BUCKET_FREQUENT
// 2. 禁止后台 GPS
// 3. 限制动画和视觉效果
// 4. Android 16:ML 模型进一步压缩维护窗口
}
}
Adaptive Charging(自适应充电)
Android 16 的 Adaptive Charging 通过预测用户的起床/拔电时间,智能延缓充电速度,减少电池长时间处于 100% 状态的老化。
// frameworks/base/services/core/java/com/android/server/
// power/AdaptiveChargingController.java
// Adaptive Charging 控制器(Android 16)
public class AdaptiveChargingController {
// 用户习惯学习
private UserSchedulePredictor mSchedulePredictor;
// 充电状态
private boolean mAdaptiveChargingEnabled = true;
private int mTargetFullTime; // 预计充满时间
// 开始充电时
void onChargingStarted() {
if (!mAdaptiveChargingEnabled) return;
// 预测用户下次拔掉充电器的时间
mTargetFullTime = mSchedulePredictor.predictUnplugTime();
if (shouldEnableAdaptiveCharging(mTargetFullTime)) {
// 通知充电 IC 降低充电速率
enableSlowCharging(mTargetFullTime);
// 通知 Power HAL 进入 Adaptive Charging 模式
mPowerManager.setMode(MODE_ADAPTIVE_CHARGING, true);
}
}
// 判断是否启用自适应充电
boolean shouldEnableAdaptiveCharging(int targetTime) {
long now = System.currentTimeMillis();
long hoursUntilUnplug = (targetTime - now) / (1000 * 60 * 60);
// 如果距离下次拔电 > 4 小时,启用慢充
return hoursUntilUnplug > 4;
}
// 充电完成前动态调整
void onBatteryLevelChanged(int level) {
if (level >= 80) {
// 80% 以上大幅降低充电速率
setChargingRate(ChargingRate.SLOW);
}
if (level >= 95) {
// 95% 以上极慢充,恰好在预测时间到达 100%
setChargingRate(ChargingRate.TRICKLE);
}
}
}
Battery Health API(电池健康 API,Android 16 新增)
Android 16 新增了 BatteryHealthManager API,应用和系统可以查询电池的健康状态。
// frameworks/base/core/java/android/os/battery/BatteryHealthManager.java
// Battery Health API(Android 16 新增)
public class BatteryHealthManager {
/**
* 电池健康状态
*/
public enum BatteryHealth {
GOOD, // 健康
DEGRADED, // 轻微老化(容量 < 80%)
CRITICAL, // 严重老化(需要更换)
OVERHEAT, // 过热
UNKNOWN // 未知
}
private final Context mContext;
public BatteryHealthManager(Context context) {
mContext = context;
}
/**
* 获取当前电池健康状态
*/
public BatteryHealth getBatteryHealth() {
// 综合以下因素:
// 1. 充放电循环次数
// 2. 当前最大容量 vs 设计容量
// 3. 内阻增加
// 4. 温度历史
// 5. 厂商自定义算法
return readBatteryHealthFromHAL();
}
/**
* 获取电池循环次数
*/
public int getCycleCount() {
// 从 Battery HAL 读取
return readCycleCount();
}
/**
* 获取当前最大容量百分比(相对于设计容量)
*/
public float getCapacityPercent() {
// 例:返回 85.0f 表示当前最大容量为设计容量的 85%
return readCapacity();
}
/**
* 注册电池健康变化监听
*/
public void setBatteryHealthListener(BatteryHealthListener listener) {
// ...
}
}
Thermal HAL(热管理硬件抽象层,AIDL 接口)
Android 16 的 Thermal HAL 使用 AIDL 接口,标准化了热管理流程。
// hardware/interfaces/thermal/aidl/IThermal.aidl
/**
* Thermal HAL AIDL 接口(Android 16)
*/
interface IThermal {
/**
* 获取所有温度传感器信息
*/
ThermalInfo[] getThermalInfo();
/**
* 获取指定传感器的当前温度
*/
float getTemperature(ThermalType type, ThermalName name);
/**
* 获取热节流状态
*/
ThrottlingSeverity getThrottlingSeverity();
/**
* 注册温度变化回调
*/
void registerThermalChangedCallback(IThermalChangedCallback callback);
/**
* 设置热配置(Android 16 新增)
*/
void setThermalConfig(ThermalConfig config);
}
/**
* 温度传感器类型
*/
enum ThermalType {
CPU,
GPU,
BATTERY,
SKIN, // 设备表面温度
NPU, // Android 16 新增
CHARGER, // Android 16 新增
DISPLAY, // Android 16 新增
}
/**
* 节流严重程度(由轻到重)
*/
enum ThrottlingSeverity {
NONE, // 正常
LIGHT, // 轻微节流
MODERATE, // 中度节流
SEVERE, // 严重节流
CRITICAL, // 临界(立即降频)
EMERGENCY, // 紧急(强制降频 + 通知用户)
SHUTDOWN, // 即将关机保护
}
// frameworks/base/services/core/java/com/android/server/
// power/ThermalStatusListener.java
// 热状态监听器(Android 16)
public class ThermalStatusListener extends IThermalChangedCallback.Stub {
private ThrottlingSeverity mCurrentSeverity = ThrottlingSeverity.NONE;
@Override
public void onThermalChanged(ThermalInfo info) {
ThrottlingSeverity newSeverity = info.throttlingSeverity;
if (newSeverity != mCurrentSeverity) {
mCurrentSeverity = newSeverity;
// 通知 PowerManagerService
if (newSeverity.ordinal() >= ThrottlingSeverity.SEVERE.ordinal()) {
mPowerManager.onThermalThrottling(true);
// 发送系统广播
sendThermalWarningBroadcast();
} else {
mPowerManager.onThermalThrottling(false);
}
}
}
public boolean isThermalThrottling() {
return mCurrentSeverity.ordinal() >= ThrottlingSeverity.SEVERE.ordinal();
}
}
PSI(Pressure Stall Information,压力 Stall 信息)
Android 16 利用内核的 PSI 机制替代了部分 Low Memory Killer 的功能,更精准地管理内存压力和后台进程。
PSI 机制概述
├── 来源:Linux 内核 4.20+
├── 路径:/proc/pressure/
│ ├── /proc/pressure/cpu ← CPU 压力
│ ├── /proc/pressure/memory ← 内存压力
│ └── /proc/pressure/io ← I/O 压力
├── Android 16 中的使用
│ ├── LMKD(Low Memory Killer Daemon)结合 PSI 触发杀进程
│ ├── PowerManagerService 监听内存压力
│ └── Adaptive Battery 利用 PSI 优化后台限制
└── 优势:
├── 比单纯看内存占用更准确
├── 能反映资源争用程度
└── 避免"内存多但实际在等 I/O"的误杀
PSI 输出示例
├── some avg10=5.20 avg60=3.10 avg300=1.50 total=3428192
│ └── "some":至少有一个任务 stall 的时间百分比
├── full avg10=1.80 avg60=0.90 avg300=0.30 total=812456
│ └── "full":所有非 idle 任务都 stall 的时间百分比
└── 解读:
├── avg10:过去 10 秒平均
├── avg60:过去 60 秒平均
├── avg300:过去 300 秒平均
└── total:累计 stall 时间(微秒)
# PSI 调试命令
# 查看内存压力
adb shell cat /proc/pressure/memory
# 查看 CPU 压力
adb shell cat /proc/pressure/cpu
# 查看 I/O 压力
adb shell cat /proc/pressure/io
# LMKD 结合 PSI 的配置
adb shell getprop ro.lmk.use_psi # 确认 PSI 已启用
adb shell getprop ro.lmk.critical_upgrade # PSI 触发杀进程的阈值
调试命令和工具
1. 查看 WakeLock
# 查看所有 WakeLock
adb shell cat /sys/power/wake_lock
adb shell cat /sys/kernel/debug/wakeup_sources
# 查看 WakeLock 使用时间
adb shell dumpsys power | grep "Wake Locks"
# 查看阻止休眠的原因
adb shell dumpsys power | grep "mWakeLockSummary"
# Android 16:查看 Adaptive Battery 对各应用的限制
adb shell dumpsys deviceidle step
2. 电源状态查看
# 查看电源状态
adb shell dumpsys power
# 查看屏幕状态
adb shell dumpsys power | grep "Display Power"
# 查看 Doze 模式状态
adb shell dumpsys deviceidle
# 强制进入 Doze 模式(测试)
adb shell dumpsys deviceidle force-idle
# Android 16:查看 App Standby Buckets
adb shell dumpsys usagestats
# Android 16:查看 Adaptive Charging 状态
adb shell dumpsys power | grep "AdaptiveCharging"
# Android 16:查看电池健康状态
adb shell dumpsys battery | grep -i health
# Android 16:查看热状态
adb shell dumpsys thermalservice
3. CPU 频率查看
# 查看当前频率
adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
# 查看支持的频率
adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
# 查看调速器(governor)
adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 设置调速器
adb shell "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
# Android 16:查看所有 CPU 的频率(big.LITTLE)
adb shell "for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq; do echo \$cpu: \$(cat \$cpu); done"
# 查看 EAS 能量模型
adb shell cat /sys/kernel/debug/sched/energy_model
4. 电池信息
# 查看电池状态
adb shell dumpsys battery
# 查看电池统计
adb shell dumpsys batterystats
# 重置电池统计
adb shell dumpsys batterystats --reset
# Android 16:查看电池健康
adb shell dumpsys battery | grep -E "health|cycle|capacity"
# Android 16:导出 batterystats(用于 Battery Historian 分析)
adb shell bugreport > bugreport.zip
5. 休眠调试
# 手动触发 Suspend
adb shell "echo mem > /sys/power/state"
# 查看唤醒原因
adb shell cat /sys/kernel/debug/wakeup_sources
# 查看 Suspend 统计
adb shell cat /sys/kernel/debug/suspend_stats
6. 热管理调试(Android 16)
# 查看 Thermal HAL 状态
adb shell dumpsys thermalservice
# 查看各传感器温度
adb shell cat /sys/class/thermal/thermal_zone*/temp
# 查看当前节流状态
adb shell dumpsys thermalservice | grep "Throttling"
# 查看 Power HAL 的节流模式
adb shell dumpsys power | grep "Thermal"
7. PSI 压力调试(Android 16)
# 查看内存压力
adb shell cat /proc/pressure/memory
# 查看 CPU 压力
adb shell cat /proc/pressure/cpu
# 查看 I/O 压力
adb shell cat /proc/pressure/io
与 T8000 项目的关联
T8000 电源管理策略
T8000 电源管理(NVR 设备)
├── 特殊性
│ ├── 7x24 小时运行
│ ├── 不需要频繁休眠
│ ├── 但需要节能(降低温度)
│ └── 夜间可降低性能
├── 策略
│ ├── 屏幕休眠(无人操作时)
│ ├── CPU 降频(夜间或无录像时)
│ ├── 关闭不必要的外设
│ ├── 保持网络和录像功能
│ └── Android 16:利用 Thermal HAL 主动控温
├── 唤醒源
│ ├── 网络唤醒(远程访问)
│ ├── PIR 传感器(检测到移动)
│ ├── 定时任务(录像计划)
│ └── 按键(本地操作)
└── Android 16 优化
├── Adaptive Battery 标记录像 App 为 Working Set
├── 利用 PSI 在内存压力下优雅降级
└── Thermal HAL 监控编码器温度
T8000 电源管理实现(Android 16 更新版)
// 自定义电源管理服务(Android 16 更新)
public class NvrPowerManager {
private PowerManager pm;
private PowerManager.WakeLock recordingWakeLock;
private BatteryHealthManager batteryHealth; // Android 16 新增
public NvrPowerManager(Context context) {
pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
batteryHealth = new BatteryHealthManager(context); // Android 16
// 录像 WakeLock(PARTIAL_WAKE_LOCK)
recordingWakeLock = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"NVR::RecordingWakeLock"
);
}
public void startRecording() {
// 开始录像时持有 WakeLock
recordingWakeLock.acquire();
// Android 16:通知 Power HAL 需要视频编码性能
pm.sendPowerHint(PowerManager.POWER_HINT_VIDEO_ENCODE, 0);
}
public void stopRecording() {
// 停止录像时释放 WakeLock
if (recordingWakeLock.isHeld()) {
recordingWakeLock.release();
}
// Android 16:恢复正常功耗
pm.sendPowerHint(PowerManager.POWER_HINT_LOW_POWER, 0);
}
public void enterNightMode() {
// 夜间模式(降低 CPU 频率,节能)
pm.sendPowerHint(PowerManager.POWER_HINT_LOW_POWER, 0);
// Android 16:检查电池健康,如果老化严重进一步降频
if (batteryHealth.getBatteryHealth() == BatteryHealthManager.BatteryHealth.DEGRADED) {
pm.setPowerMode(PowerManager.POWER_MODE_LOW_POWER, true);
}
// 关闭屏幕
pm.goToSleep(SystemClock.uptimeMillis());
}
public void exitNightMode() {
// 退出夜间模式
pm.sendPowerHint(PowerManager.POWER_HINT_INTERACTION, 0);
// 唤醒屏幕
pm.wakeUp(SystemClock.uptimeMillis());
}
}
T8000 设备树配置
// arch/arm64/boot/dts/device/T8000.dts
/ {
// 电源管理
power {
compatible = "device,T8000-power";
// 唤醒源
wakeup-sources {
network {
compatible = "wakeup-source";
wakeup-source;
};
pir-sensor {
compatible = "wakeup-source";
wakeup-source;
};
power-key {
compatible = "wakeup-source";
wakeup-source;
};
};
// CPU 频率表(OPP 表)
cpu-freq {
opp-600mhz {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <900000>;
opp-supported-hw = <0x1>; // 所有 CPU 都支持
};
opp-1200mhz {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1000000>;
opp-supported-hw = <0x1>;
};
opp-1800mhz {
opp-hz = /bits/ 64 <1800000000>;
opp-microvolt = <1200000>;
opp-supported-hw = <0x1>;
};
};
// Android 16:Thermal 区域配置
thermal-zones {
cpu-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
trips {
cpu-warm {
temperature = <70000>; // 70°C
hysteresis = <2000>;
type = "passive"; // 触发降频
};
cpu-hot {
temperature = <85000>; // 85°C
hysteresis = <2000>;
type = "critical"; // 触发强制节流
};
};
};
};
};
};
T8000 功耗优化
# 优化 CPU 调度器(推荐 Android 16 默认 schedutil)
echo "schedutil" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 设置唤醒源
echo enabled > /sys/devices/platform/soc/12c00000.serial/tty/ttyS0/power/wakeup
echo enabled > /sys/devices/platform/soc/gpio-keys/power/wakeup
# 禁用不必要的唤醒源(如蓝牙)
echo disabled > /sys/devices/platform/soc/bluetooth/power/wakeup
# 配置网卡 WoL(Wake on LAN)
ethtool -s eth0 wol g
# Android 16:监控 PSI 内存压力
cat /proc/pressure/memory
# Android 16:查看 Thermal 状态
dumpsys thermalservice
快速回忆检查点
问题 1:WakeLock 的类型有哪些?主要区别是什么?
答案- PARTIAL_WAKE_LOCK:保持 CPU 运行,屏幕可灭(最常用,唯一推荐)
- DOZE_WAKE_LOCK:允许进入 Doze,但不完全休眠(Android 6.0+)
- DRAW_WAKE_LOCK:屏幕绘制时保持唤醒(Android 7.0+)
- SCREEN_BRIGHT_WAKE_LOCK:已废弃(仅兼容性保留)
- FULL_WAKE_LOCK:已废弃(完全无效)
Android 16 推荐使用 WorkManager 替代手动持有 WakeLock。
问题 2:Android Suspend 流程的主要步骤是什么?
答案- 写入
/sys/power/state - 冻结用户空间进程
- 同步文件系统
- 调用所有驱动的
suspend()回调 - 关闭外设、保存设备状态
- 关闭非启动 CPU
- 禁用中断
- 进入 CPU 休眠(WFI)
- 中断唤醒
- Resume 流程(反向)
问题 3:如何让设备成为唤醒源?
答案// 驱动中配置
device_init_wakeup(&pdev->dev, true);
enable_irq_wake(irq);
// sysfs 配置
echo enabled > /sys/devices/.../power/wakeup
问题 4:Power HAL 的作用是什么?Android 16 有什么变化?
答案- 硬件抽象层,封装电源相关操作
- 接收 PowerManagerService 的电源提示
- 根据提示调整 CPU/GPU 频率
- 实现 setMode、sendPowerHint、setInteractive 接口
- Android 16 变化:从 HIDL 迁移到 AIDL 接口,新增 THERMAL_THROTTLE、ADAPTIVE_CHARGING 等模式,支持 ML_INFERENCE 提示
- 允许厂商定制电源管理策略
问题 5:如何查看阻止系统休眠的 WakeLock?
答案# 方法 1:查看 active WakeLock
adb shell cat /sys/kernel/debug/wakeup_sources
# 方法 2:dumpsys
adb shell dumpsys power | grep "Wake Locks"
# 方法 3:查看持有时间
adb shell cat /sys/power/wake_lock
问题 6:T8000 录像时为什么需要 WakeLock?
答案- 录像需要 CPU 持续运行(编码、存储)
- 屏幕可以灭但 CPU 不能休眠
- 使用 PARTIAL_WAKE_LOCK 保持 CPU 运行
- 录像结束后释放 WakeLock 节能
- 避免录像中断导致数据丢失
问题 7:App Standby Buckets 是什么?有什么作用?
答案- 将应用分为 5 个桶:Active / WorkingSet / Frequent / Rare / Restricted
- 每个桶有不同的后台活动限制(Job、Alarm、网络)
- Android 16 使用 ML 模型预测应用使用概率,自动分桶
- 目的:限制不常用应用的后台活动,减少电池消耗
- 维护窗口按桶分配,越不活跃的应用窗口越短
问题 8:Thermal HAL 的作用是什么?
答案- Android 标准化的热管理硬件抽象层(AIDL 接口)
- 监控多区域温度(CPU / GPU / Battery / Skin / NPU / Charger)
- 定义节流严重程度:NONE / LIGHT / MODERATE / SEVERE / CRITICAL / EMERGENCY / SHUTDOWN
- 温度过高时自动通知 PowerManagerService 限制性能
- Power HAL 接收 THERMAL_THROTTLE 模式自动降频
问题 9:PSI(Pressure Stall Information)在 Android 中如何应用?
答案- 来自 Linux 内核 4.20+,通过 /proc/pressure/{cpu,memory,io} 暴露
- 反映资源争用程度,比单纯看内存占用更准确
- Android 16 中 LMKD 结合 PSI 触发杀进程
- 避免"内存多但实际在等 I/O"的误杀
- 替代了部分 Low Memory Killer 的功能
关键概念图谱
Android 电源管理(Android 16 / API 36)
├── 应用层
│ ├── PowerManager(电源管理器)
│ ├── WakeLock(唤醒锁,推荐使用 WorkManager 替代)
│ ├── BatteryManager(电池管理)
│ ├── BatteryHealthManager(电池健康 API)⭐ Android 16 新增
│ └── AdaptiveCharging API(自适应充电状态)⭐ Android 16 新增
├── Framework 层
│ ├── PowerManagerService(电源服务核心)
│ ├── DeviceIdleController(Doze / Light Doze)
│ ├── AppStandbyController(App Standby Buckets)⭐ ML 驱动
│ ├── AdaptiveBatteryController(自适应电池)⭐ ML 驱动
│ ├── AdaptiveChargingController(自适应充电)⭐ 预测用户习惯
│ ├── ThermalStatusListener(热状态监听)⭐ AIDL HAL
│ └── BatteryService(电池服务 + Health API)
├── HAL 层(全部 AIDL 接口,Android 16)
│ ├── IPower.aidl(Power HAL,从 HIDL 迁移)
│ ├── IThermal.aidl(Thermal HAL)⭐ 多区域温度监控
│ └── IBattery.aidl(Battery HAL + Health)
├── 内核层
│ ├── WakeLock 机制(保持不变)
│ ├── Suspend / Resume(保持不变)
│ ├── CPUFreq(schedutil 为默认 governor)
│ ├── CPUIdle(空闲管理)
│ ├── PSI(Pressure Stall Information)⭐ 替代 LMK
│ └── Thermal(内核热管理 + 设备树配置)
└── 关键机制
├── WakeLock(防止休眠,推荐使用 WorkManager)
├── 唤醒源(中断唤醒)
├── Doze / Light Doze(深度节能)
├── App Standby Buckets(ML 分桶限制)
├── Adaptive Battery(ML 驱动后台优化)
├── Adaptive Charging(智能充电延长寿命)
├── Battery Health(电池健康度 API)
├── Thermal Throttle(温度过高自动降频)
├── Power Hint(性能提示,新增 ML_INFERENCE)
└── PSI(压力 stall 信息,精准杀进程)
版本历史
| Android 版本 | 电源管理重要变化 |
|---|---|
| Android 6.0 | Doze Mode、App Standby 引入 |
| Android 7.0 | Project Svelte 后台优化 |
| Android 8.0 | 后台位置限制、Implicit Broadcast 限制 |
| Android 9 | Adaptive Battery、App Standby Buckets 首次引入 |
| Android 10 | Scoped Storage 间接影响功耗 |
| Android 11 | 5 桶分类完善、一次性权限 |
| Android 12 | Light Doze、充电保护 |
| Android 13 | 更精准的 Bucket 分类 |
| Android 14 | Foreground Service 类型限制 |
| Android 15 | Thermal HAL AIDL 迁移完成 |
| Android 16 | Power HAL AIDL、Battery Health API、Adaptive Charging 完善、PSI 替代 LMK、ML_INFERENCE 提示、NPU/Charger/Display Thermal 支持 |
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)