💡 基础概念:Wakefulness 状态
PowerManagerService 使用内部变量 mWakefulness
来标识系统当前的“唤醒状态”,主要包括以下几种:
-
WAKEFULNESS_AWAKE (1):完全唤醒,屏幕亮,设备可交互
-
WAKEFULNESS_DREAMING (2):梦境模式,屏幕可能亮但不可交互(如屏保)
-
WAKEFULNESS_DOZING (3):打瞌睡(Doze),设备进入轻度休眠,屏幕可能是熄灭状态或仅显示 AoD(Always on Display)
-
WAKEFULNESS_ASLEEP (0):深度休眠,CPU 允许完全挂起,设备无法交互
Doze 模式就是通过 WAKEFULNESS_DOZING
表示的浅层休眠状态,系统仍可进行部分后台任务或显示 AoD 内容。
🔁 状态切换流程(从深度睡眠 → 浅睡眠)
一般由以下两种情况触发浅睡眠:
场景一:屏幕关闭,进入 Doze 浅睡眠(不是立刻深睡)
流程梳理:
-
用户按电源键或屏幕超时
→PhoneWindowManager
调用PowerManager.goToSleep()
→ 进入PowerManagerService.goToSleepInternal()
-
进入 doze 状态
→ 调用goToSleepNoUpdateLocked()
方法时,如果没有传入GO_TO_SLEEP_FLAG_NO_DOZE
→ 设置:mWakefulness = WAKEFULNESS_DOZING
→ 即从 AWAKE → DOZING(浅睡)mSandmanSummoned = true; setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
-
通知系统其他模块
setWakefulnessLocked()
会通知 Notifier 和其他模块状态变更,广播SCREEN_OFF
等事件。 -
唤起 Sandman(打瞌睡精灵)
→scheduleSandmanLocked()
发送消息MSG_SANDMAN
→ 异步线程中执行handleSandman()
→ 判断是否可进入 dream / doze
→ 如果进入 doze 模式,会调用 DreamManager 启动 doze UI(如 AoD)mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
-
等待 Doze 结束或条件变化
-
如果条件允许,会一直处于 DOZING
-
否则将调用
reallyGoToSleepNoUpdateLocked()
→ 转入WAKEFULNESS_ASLEEP
reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);
-
场景二:从深度睡眠被唤醒,进入轻度 Doze
某些情况,例如系统定时任务、通知到达、传感器(比如抬手唤醒、双击唤醒)也会让设备从完全挂起状态(Deep Sleep)唤醒 CPU,但不点亮屏幕、不进入 AWAKE 状态:
-
系统保持
mWakefulness = WAKEFULNESS_DOZING
-
这属于“浅唤醒”,主要用于:
-
Doze 的 maintenance window
-
Ambient Display 显示通知
-
执行某些后台任务(Google Play 服务、同步)
-
这类唤醒由 AlarmManager、DeviceIdleController、传感器等触发。
🔍 判断与标志位
关键常量/标志:
-
GO_TO_SLEEP_FLAG_NO_DOZE
:调用goToSleep()
时如果设置了该标志,会跳过 DOZING,直接进入 ASLEEP -
WAKEFULNESS_DOZING
:表示当前是打瞌睡状态,设备可能运行 AoD,但不允许全功能交互 -
mSandmanSummoned
:一个布尔标志,表示已经请求进入 dream/doze -
mDreamManager.startDream(true)
:如果为 true,代表启动的是 doze UI,而非普通 dream(屏保)
与其他服务的协作:
-
DreamManagerService:负责管理 dream/doze UI,例如 AoD 显示
-
SuspendControlService:通过 AIDL 接口,负责控制内核 suspend 动作,只有在 WAKEFULNESS_ASLEEP 并且没有 wakelock 时才允许真正挂起 CPU
-
BatteryStatsService:记录唤醒/睡眠原因、屏幕状态、耗电时间段等
-
DeviceIdleController:负责深度 Doze 的逻辑控制,例如 idle、maintenance window 等
✅ 总结
在 Android 14 中,PowerManagerService 通过 wakefulness 状态 管理休眠与唤醒流程。系统不会一关闭屏幕就立即进入深度休眠,而是先进入 WAKEFULNESS_DOZING
:
-
可以显示 AoD(由 DreamManager 启动 doze dream)
-
允许短暂的后台任务执行(如 Doze maintenance)
-
条件满足后才转为
WAKEFULNESS_ASLEEP
,进入真正的 Deep Sleep(Suspend)