电源管理架构全景图)
系列目录第一篇电源管理架构全景图 | 第二篇开机全链路—BootROM到Launcher | 第三篇关机/重启全链路—ShutdownThread到kernel_power_off | 第四篇休眠唤醒与开关机—核心差异深度对比 | 第五篇休眠全链路—PMS到Kernel Suspend | 第六篇唤醒全链路—Kernel Resume到屏幕点亮 | 第七篇内核层—wakelock与autosleep机制 | 第八篇内核层—Alarm定时唤醒与硬件唤醒源 | 第九篇Native层—libsuspend与Power HAL | 第十篇实战调试与问题排查一、为什么要理解休眠唤醒移动设备与 PC 在电源管理上有本质区别。PC 可以随时插电使用而手机依赖电池供电必须在性能和续航之间做精细平衡。Android 为此设计了一套从应用到内核、跨越四层软件栈的电源管理体系。当你遇到以下问题时答案都在这套体系之中“为什么 App 申请了 WakeLock设备还是会休眠”——WakeLock 的 level 可能不够高或者 PMS 的mWakeLockSummary汇总时被覆盖了“为什么设备休眠后无法通过 Alarm 唤醒”——Alarm 的 type 可能不是RTC_WAKEUP或ELAPSED_REALTIME_WAKEUP“为什么功耗测试显示设备从未进入 deep sleep”——内核 wakelock 可能被某个驱动持锁/sys/power/wake_lock可以排查这套体系的核心思想当用户不使用设备时让它尽可能深地睡眠当用户需要使用设备时让它在一秒之内恢复。二、三种状态转移模型Android 系统的电源状态可以抽象为三种粒度的转移2.1 宏观级别关机 ↔ 开机最彻底的状态切换。关机将操作系统完整卸载、硬件完全掉电开机则从 BootROM 开始经历 BootLoader → Kernel → init → Zygote → SystemServer → Launcher 的完整启动链。维度说明耗时开机 30-60 秒关机 5-15 秒状态保留无。所有内存数据、进程状态、寄存器上下文全部丢失功耗关机后几乎为零仅 RTC 时钟供电2.2 中观级别休眠 ↔ 唤醒这是本系列的核心。休眠时 CPU 进入深度睡眠状态deep idle / suspend仅保留 RAM 自刷新供电和外设唤醒源。唤醒时从中断触发到屏幕点亮通常在 1 秒以内完成。维度说明耗时休眠 1 秒唤醒 1 秒状态保留完整。进程页表、ART 虚拟机堆、Activity 栈全部保留在 RAM 中功耗仅 RAM 自刷新 RTC 唤醒源监听功耗极低2.3 微观级别亮屏 ↔ 暗屏最轻量级的切换仅涉及DisplayPowerController控制屏幕背光和显示层不涉及 CPU 挂起。通常由用户操作触摸屏幕、按下按键或接近传感器触发。三、Android 电源管理四层架构Android 电源管理跨越四层软件栈每层有明确的职责边界┌──────────────────────────────────────────────────────┐ │ 应用层 (Application Layer) │ │ PowerManager API / WakeLock 申请与释放 │ │ frameworks/base/core/java/android/os/PowerManager │ ├──────────────────────────────────────────────────────┤ │ 框架层 (Framework Layer) │ │ PowerManagerService / DisplayPowerController │ │ Notifier / ShutdownThread │ │ frameworks/base/services/core/java/com/android/ │ │ server/power/ │ ├──────────────────────────────────────────────────────┤ │ Native 层 (Native Layer) │ │ libsuspend / suspend_blocker / Power HAL │ │ system/core/libsuspend/ │ │ hardware/libhardware/include/hardware/power.h │ ├──────────────────────────────────────────────────────┤ │ 内核层 (Kernel Layer) │ │ wakelock / autosleep / alarmtimer │ │ kernel/power/ │ │ drivers/rtc/alarm-dev.c │ └──────────────────────────────────────────────────────┘3.1 应用层PowerManager API应用程序通过PowerManager.WakeLock通知系统我正在做重要的事不要休眠。源码路径frameworks/base/core/java/android/os/PowerManager.javapublicfinalclassPowerManager{// WakeLock 级别从低到高publicstaticfinalintPARTIAL_WAKE_LOCK0x00000001;// 仅保持 CPU 运行publicstaticfinalintSCREEN_DIM_WAKE_LOCK0x00000006;// 保持 CPU 暗屏publicstaticfinalintSCREEN_BRIGHT_WAKE_LOCK0x0000000a;// 保持 CPU 亮屏publicstaticfinalintFULL_WAKE_LOCK0x0000001a;// 保持 CPU 亮屏 键盘publicWakeLocknewWakeLock(intlevelAndFlags,Stringtag){returnnewWakeLock(levelAndFlags,tag,mContext.getOpPackageName());}publicfinalclassWakeLock{publicvoidacquire(){...}// 获取锁阻止休眠publicvoidacquire(longtimeout){...}// 带超时的获取publicvoidrelease(){...}// 释放锁}}关键设计WakeLock默认非引用计数setReferenceCounted(false)多次acquire()只需一次release()即可释放。如果设为引用计数模式则必须acquire()和release()次数匹配。3.2 框架层PowerManagerServicePowerManagerServicePMS是休眠唤醒的中枢大脑运行在 SystemServer 进程中。源码路径frameworks/base/services/core/java/com/android/server/power/PowerManagerService.javapublicfinalclassPowerManagerServiceextendsSystemService{// 唤醒状态机四种状态privateintmWakefulness;// AWAKE → DREAMING → DOZING → ASLEEPprivatebooleanmWakefulnessChanging;// 状态迁移中标志// WakeLock 聚合状态所有活跃 WakeLock 的位掩码汇总privateintmWakeLockSummary;// 每个 bit 代表一种 WakeLock 类型// 脏标记指示哪部分电源状态需要更新protectedintmDirty;// 位掩码驱动 updatePowerStateLocked() 的增量更新}关键设计PMS 用mDirty位掩码驱动增量更新——当某个条件变化时如 WakeLock 变化、亮度变化只设置对应的 dirty bitupdatePowerStateLocked()根据 dirty bits 分阶段处理避免全量重算。Wakefulness 状态机沿固定方向迁移AWAKE ──→ DREAMING ──→ DOZING ──→ ASLEEP ↑ ↑ ↑ │ │ │ │ │ └─────────┴───────────┴───────────┘ (用户交互 / 唤醒事件)AWAKE屏幕亮设备完全可用DREAMING屏幕变暗可能进入屏保DaydreamDOZINGDoze 模式限制网络和后台任务ASLEEPCPU 挂起仅 RAM 自刷新关键设计状态迁移是单向的AWAKE → ASLEEP唤醒时直接跳回 AWAKE。mWakefulnessChanging标志在状态迁移过程中置位防止并发状态变更。3.3 Native 层libsuspend 与 Power HALlibsuspend是用户空间与内核休眠机制的桥梁。两种实现方式源码路径system/core/libsuspend/autosuspend_wakeup_count.cwakeup_count 方式读取/sys/power/wakeup_count获取当前值写入/sys/power/state为 “mem” 触发休眠。如果在读取和写入之间产生了新的唤醒事件wakeup_count 不匹配内核拒绝休眠并返回错误。源码路径system/core/libsuspend/autosuspend_autosleep.cautosleep 方式写入/sys/power/autosleep为 “mem”内核在 autosleep 工作线程中自动尝试休眠无需用户空间持续轮询。Power HAL 定义硬件抽象层接口源码路径hardware/libhardware/include/hardware/power.h关键接口powerHint()— 向底层cpufreq governor传递电源提示setInteractive()— 通知 HAL 交互模式变化。3.4 内核层wakelock 与 autosleepAndroid 内核在 Linux 标准 suspend/resume 基础上增加了 wakelock 和 autosleep 机制确保在有活跃 wakelock 时不会错误休眠。关键内核源码路径kernel/power/wakelock.c— wakelock 核心实现kernel/power/autosleep.c— autosleep 工作线程kernel/power/main.c— sysfs 节点注册/sys/power/wake_lock、/sys/power/wake_unlockkernel/power/suspend.c— suspend 主路径pm_suspendkernel/power/process.c— 进程 freeze/thaw四、休眠唤醒与开关机核心区分理解这四种流程的关键在于状态保持 vs 状态重建关机→开机状态完全重建 BootROM → BootLoader → Kernel → init → Zygote → SystemServer → Launcher 内核重载、进程全部冷启动、ART 堆清零重分配 休眠→唤醒状态完全保持 内核仍在运行仅 CPU 暂停 进程被 freeze冻结而非 kill ART 虚拟机堆内存完整保留 Activity 栈原样保存 恢复时只需 thaw解冻→ 恢复外设 → 点亮屏幕关键休眠唤醒的核心优势是状态保持——不需要重新加载内核、不需要重启进程、不需要重新初始化服务。这解释了为什么唤醒只需不到 1 秒而开机需要 30-60 秒。五、关键源码文件索引层级文件本文涉及内容Frameworkframeworks/base/services/core/java/com/android/server/power/PowerManagerService.javaPMS 核心Wakefulness 状态机、mDirty 增量更新Frameworkframeworks/base/services/core/java/com/android/server/power/Notifier.java电源状态广播SCREEN_ON/OFFFrameworkframeworks/base/services/core/java/com/android/server/power/ShutdownThread.java关机/重启调度Frameworkframeworks/base/core/java/android/os/PowerManager.java应用层 WakeLock APINativesystem/core/libsuspend/autosuspend.c自动休眠核心实现Nativesystem/core/libsuspend/autosuspend_wakeup_count.cwakeup_count 方式休眠Nativesystem/core/libsuspend/autosuspend_autosleep.cautosleep 方式休眠HALhardware/libhardware/include/hardware/power.hPower HAL 接口定义Kernelkernel/power/wakelock.c内核 wakelock 实现Kernelkernel/power/autosleep.c内核 autosleep 线程Kernelkernel/power/suspend.cSuspend 主路径Kernelkernel/power/process.c进程 freeze/thaw六、系列阅读路线第 1 篇本篇全景图 │ ├─→ 第 2 篇开机全链路建立全量启动的基准认知 │ │ │ └─→ 第 3 篇关机/重启全链路理解全量销毁的代价 │ │ │ └─→ 第 4 篇休眠唤醒 vs 开关机 对比核心交汇点 │ │ │ ┌───────────┼───────────┐ │ │ │ │ 第 5 篇休眠全链路 第 6 篇唤醒全链路 │ (Framework → Kernel) (Kernel → Framework) │ │ │ │ └───────────┬───────────┘ │ │ │ 第 7 篇内核wakelock 第 8 篇Alarm唤醒源 │ │ │ 第 9 篇Native 层 Power HAL │ │ └─────────── 第 10 篇实战调试与问题排查App 开发者重点读第 1、4、5、6、10 篇理解 WakeLock 的申请释放与功耗影响Framework 开发者通读全系列核心是第 2-6 篇驱动/Kernel 开发者重点关注第 4-8 篇特别是第 5、6、7、8 篇七、小结本篇建立了 Android 电源管理的顶层认知概念说明三种状态转移关机↔开机全量重建、休眠↔唤醒状态保持、亮屏↔暗屏仅背光四层架构应用层WakeLock API→ 框架层PMS 状态机→ Native 层libsuspend→ 内核层wakelock/autosleep核心区分状态保持休眠唤醒vs 状态重建开关机后续篇章将逐层深入——下一篇从开机开始走完从 BootROM 到 Launcher 的完整启动链路为理解休眠唤醒跳过了什么打下基础。