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 流程的主要步骤是什么?

答案
  1. 写入 /sys/power/state
  2. 冻结用户空间进程
  3. 同步文件系统
  4. 调用所有驱动的 suspend() 回调
  5. 关闭外设、保存设备状态
  6. 关闭非启动 CPU
  7. 禁用中断
  8. 进入 CPU 休眠(WFI)
  9. 中断唤醒
  10. 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?

答案
  1. 录像需要 CPU 持续运行(编码、存储)
  2. 屏幕可以灭但 CPU 不能休眠
  3. 使用 PARTIAL_WAKE_LOCK 保持 CPU 运行
  4. 录像结束后释放 WakeLock 节能
  5. 避免录像中断导致数据丢失

问题 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 支持
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐