为了支持特定于车辆的电源管理,Android 提供了 CarPowerManagementService 服务和 CarPowerManager 接口。
状态转换由车辆主控制单元 (VMCU) 触发。为了与 VMCU 通信,集成商必须实现多个组件。集成商负责与车辆硬件抽象层 (VHAL) 和内核实现集成。集成商还负责停用唤醒源,并确保不会无限期地推迟关机。
术语
本文档通篇使用以下术语
suspend() 和 shutdown() 的最终调用。系统设计
本节介绍 AAOS 如何表示应用处理器的电源状态,以及哪些模块实现了电源管理系统。本材料还介绍了这些模块如何协同工作以及状态转换通常如何发生。
汽车电源状态机
AAOS 使用状态机来表示 AP 的电源状态。状态机提供下图所示的状态

图 1. 汽车电源状态机。
最常见的转换以蓝色突出显示。以下是状态和常见转换
- 挂起到 RAM。车辆和 SoC 都已关闭。没有代码正在执行。SoC RAM 保持供电。
- 等待 VHAL。当驾驶员与车辆互动时(例如,打开车门),VMCU 向 SoC 供电。AAOS 从挂起到 RAM 恢复,并进入等待 VHAL 状态,在该状态下,它等待与 VHAL 协调。
- 开启。VHAL 告知 AAOS 进入开启状态。在此状态下,AAOS 完全运行并与驾驶员互动。
- 准备关机。当驾驶员完成驾驶时,VHAL 告知 AAOS 进入准备关机状态。在此状态下,显示屏和音频关闭,AAOS 不与驾驶员互动。Android 系统仍在运行,可以自由更新应用和 Android 系统。如果完成更新,Android 系统将进入等待 VHAL 完成状态。
- 等待 VHAL 完成。此时,AAOS 通知 VHAL 它已准备好关机。VMCU 预计将 SoC 置于深度睡眠状态,并断开应用处理器的电源。然后,AAOS 处于挂起到 RAM 状态,尽管没有代码正在执行。
电源管理模块
电源管理系统由以下模块组成
| 模块名称 | 说明 |
|---|---|
| CarPowerManager | Java 或 C++ API。 |
| CarPowerManagementService | 协调电源状态转换。 |
| CarPowerPolicyDaemon | 与原生电源政策客户端通信。 |
| 车辆 HAL | 与 VMCU 的接口。 |
| 内核 | 挂起到 RAM 或磁盘实现。 |
深度睡眠/休眠功能(将 Android 挂起到 RAM/磁盘)在内核中实现。此功能作为位于 /sys/power/state 的特殊文件公开给用户空间。通过将 mem 或 disk 写入此文件来挂起 AAOS。
CPMS 与其他服务和 HAL 协调电源状态。CPMS 实现上述状态机,并在发生电源状态转换时向每个观察者发送通知。此服务还使用 VHAL 向硬件发送消息。
CPPD 在 CPMS 接管控制之前管理电源政策。它还会向原生监听器发送电源政策更改通知。
某些属性在 VHAL 中定义。为了与 VMCU 通信,CPMS 读取和写入这些属性。应用可以使用 CPM 中定义的接口来监控电源状态更改。此接口还使应用能够注册电源政策监听器。此 API 可以从 Java 调用,并使用 @hide / @System API 注释,这意味着它仅适用于特权应用。下图说明了这些模块、应用和服务之间的关系

图 2. 电源组件参考图。
消息序列
上一节介绍了构成电源管理系统的模块。本节使用进入深度睡眠和退出深度睡眠示例来解释模块和应用如何通信
进入深度睡眠
只有 VMCU 可以启动深度睡眠。启动深度睡眠后,VMCU 通过 VHAL 向 CPMS 发送通知。CPMS 将状态更改为准备关机,并通过调用 onStateChanged() 方法,使用 CPM 提供的新的状态 ID 向所有观察者(监控 CPMS 的应用和服务)广播此状态转换。
CPM 在应用/服务和 CPMS 之间进行协调。应用/服务的 onStateChanged() 方法在 CPM 的 onStateChanged() 方法中同步调用。大多数应用和服务都需要在从此调用返回之前完成其准备工作。特权服务允许在 PRE_SHUTDOWN_PREPARE、SUSPEND_ENTER、POST_SUSPEND_ENTER 返回后继续异步准备。在这种情况下,特权服务应在其完成准备工作时,对提供的 CompletablePowerStateChangeFuture 对象调用 complete()。请注意,SHUTDOWN_PREPARE 不允许异步准备。在向 VHAL 发送 DEEP_SLEEP_ENTRY 之前,CPMS 会定期向 VHAL 发送关机推迟请求。
当所有 CPM 对象都完成关机准备后,CPMS 会向 VHAL 发送 AP_POWER_STATE_REPORT,然后 VHAL 通知 VMCU AP 已准备好挂起。CPMS 还会调用其挂起方法,该方法会挂起内核。
下图说明了上述序列

图 3. 进入深度睡眠。
CPM 提供的编程接口
本节介绍 CPM 为系统应用和服务提供的 Java API。此 API 使系统软件能够
- 监控 AP 中的电源状态更改。
- 应用电源政策。
使用以下步骤调用 CPM 提供的 API
- 要获取 CPM 实例,请调用 Car API。
- 对步骤 1 中创建的对象调用相应的方法。
创建 CarPowerManager 对象
要创建 CPM 对象,请调用 Car 对象的 getCarManager() 方法。此方法是用于创建 CPM 对象的外观模式。指定 android.car.Car.POWER_SERVICE 作为参数以创建 CPM 对象。
Car car = Car.createCar(this); CarPowerManager powerManager = (CarPowerManager) car.getCarManager(android.car.Car.POWER_SERVICE);
CarPowerStateListener 和注册
系统应用和服务可以通过实现 CarPowerManager.CarPowerStateListener 来接收电源状态更改通知。此接口定义了一个方法 onStateChanged(),当 CPMS 的电源状态更改时,会调用该回调函数。以下示例定义了一个新的匿名类,该类实现了该接口
private final CarPowerManager.CarPowerStateListener powerListener = new CarPowerManager.CarPowerStateListener () { @Override public void onStateChanged(int state) { Log.i(TAG, "onStateChanged() state = " + state); } };
要指示此监听器对象监控电源状态转换,请创建一个新的执行线程,并将监听器和此线程注册到 CPM 对象
executor = new ThreadPerTaskExecutor(); powerManager.setListener(powerListener, executor);
当电源状态更改时,将使用表示新电源状态的值调用监听器对象的 onStateChanged() 方法。实际值和电源状态之间的关联在 CarPowerManager 中定义,并在下表中显示
| 名称 | 说明 |
|---|---|
| STATE_ON | 进入开启状态。系统完全运行。 |
| STATE_SHUTDOWN_CANCELLED | 关机已取消,电源状态返回正常状态。 |
| STATE_SHUTDOWN_ENTER | 应用应清理并准备好关机。 |
| STATE_POST_SHUTDOWN_ENTER | 关机准备已完成,VMCU 已准备好关机。进入关机状态。 |
| STATE_PRE_SHUTDOWN_PREPARE | 已请求关机过程,但 CPMS 尚未启动该过程。显示屏和音频仍然开启 |
| STATE_SHUTDOWN_PREPARE | 车库模式可能在此期间运行。 |
| STATE_SUSPEND_ENTER | 应用应清理并准备好挂起到 RAM。 |
| STATE_POST_SUSPEND_ENTER | 挂起到 RAM 的准备已完成,VMCU 已准备好挂起到 RAM。进入挂起状态。 |
| STATE_SUSPEND_EXIT | 从挂起状态唤醒或从已取消的挂起状态恢复。 |
| STATE_HIBERNATION_ENTER | 应用应清理并准备好休眠。 |
| STATE_POST_HIBERNATION_ENTER | 休眠准备已完成,VMCU 已准备好休眠。进入休眠状态。 |
| STATE_HIBERNATION_EXIT | 从休眠状态唤醒或从已取消的休眠状态恢复。 |
| STATE_WAIT_FOR_VHAL | 系统正在启动,但在进入开启状态之前,正在等待与 VHAL 建立通信。 |
CarPowerStateListener 取消注册
要取消注册所有注册到 CPM 的监听器对象,请调用 clearListener 方法
powerManager.clearListener();
Android 实现的系统集成
集成商负责以下事项
- 实现内核接口以挂起 Android。
- 实现 VHAL 功能以
- 将挂起或关机的启动从汽车传播到 Android。
- 从 Android 向汽车发送关机就绪消息。
- 通过 Linux 内核接口启动 Android 的关机或挂起。
- 确保当设备处于挂起状态时,所有唤醒源都被禁用。
- 确保应用快速关机,以免无限期地推迟关机过程。
- 确保 BSP 根据电源政策开启(或关闭)设备组件,以免阻止挂起或休眠
内核接口:/sys/power/state
当应用或服务将 mem(用于挂起到 RAM)或 disk(用于挂起到磁盘)写入位于 /sys/power/state 的文件时,AAOS 会将设备置于挂起模式。集成商必须提供一个函数来监控此文件,并将 Linux 置于挂起电源状态。此函数可以向 VMCU 发送 GPIO,以通知 VMCU 设备已完全关机。集成商还负责消除 VHAL 向 VMCU 发送最终消息与系统进入挂起或关机模式之间的任何竞争条件。
VHAL 职责
VHAL 在车辆网络和 Android 之间提供接口。VHAL
- 将挂起或关机的启动从汽车传播到 Android。
- 从 Android 向汽车发送关机就绪消息。
- 通过 Linux 内核接口启动 Android 的关机或挂起。
当 CPMS 通知 VHAL 它已准备好关机时,VHAL 会向 VMCU 发送关机就绪消息。通常,片上外围设备(如 UART、SPI 和 USB)会传输消息。发送消息后,CPMS 会调用内核命令以挂起或关闭设备。在此之前,VHAL 或 BSP 可能会切换 GPIO,以指示 VMCU 可以安全地断开设备电源。
VHAL 必须支持以下属性,这些属性通过 VHAL 控制电源管理
| 名称 | 说明 |
|---|---|
| AP_POWER_STATE_REPORT | Android 使用此属性,使用 VehicleApPowerStateReport 枚举值向 VMCU 报告状态转换。 |
| AP_POWER_STATE_REQ | VMCU 使用此属性来指示 Android 转换为不同的电源状态,使用 VehicleApPowerStateReq 枚举值。 |
AP_POWER_STATE_REPORT
使用此属性报告 Android 当前的电源管理状态。此属性包含两个整数
int32Values[0]:当前状态的 VehicleApPowerStateReport 枚举。int32Values[1]:推迟或睡眠或关机的时间(以毫秒为单位)。此值的含义取决于第一个值。
第一个值可以采用以下值之一。VehicleApPowerStateReport.aidl 包含更具体的描述,这些描述存储在 hardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle 中。
| 值名称 | 说明 | 第二个值 |
|---|---|---|
| WAIT_FOR_VHAL | AP 正在启动,需要与 VHAL 建立通信。 | |
| DEEP_SLEEP_ENTRY | AP 正在进入深度睡眠状态。VMCU 应在第二个值指定的时间后重新打开 AP。 | 必须设置 |
| DEEP_SLEEP_EXIT | AP 正在退出深度睡眠状态。 | |
| HIBERNATION_ENTRY | AP 正在进入休眠状态。VMCU 应在第二个值指定的时间后重新打开 AP。 | 必须设置 |
| HIBERNATION_EXIT | AP 正在退出休眠状态。 | |
| SHUTDOWN_POSTPONE | Android 尚未准备好关机。VMCU 应在第二个值指定的时间后等待,然后再关闭 AP。Android 可能会通过发布额外的 SHUTDOWN_POSTPONE 报告来请求额外的推迟。 | 必须设置 |
| SHUTDOWN_PREPARE | Android 正在准备关机。 | 必须设置 |
| SHUTDOWN_START | AP 已准备好关机。VMCU 应在第二个值指定的时间后重新打开 AP。(VMCU 不需要支持定时开启功能。) | 必须设置 |
| SHUTDOWN_CANCELLED | Android 正在停止准备关机,并将继续进入 WAIT_FOR_VHAL 状态。 | |
| ON | Android 正常运行。 |
状态可以自主设置,也可以响应 VMCU 的请求进行设置。
AP_POWER_STATE_REQ
此属性由 VMCU 发送,用于将 Android 转换为不同的电源状态,并包含两个整数
int32Values[0]:VehicleApPowerStateReq枚举值,表示要转换到的新状态。int32Values[1]:VehicleApPowerStateShutdownParam枚举值。此值仅针对SHUTDOWN_PREPARE消息发送,并传输到 Android 它包含的选项。
第一个整数值表示 Android 要转换到的新状态。语义在 VehicleApPowerStateReq.aidl 中定义,并在下面提供
| 值名称 | 说明 |
|---|---|
| ON | AP 应开始全面运行。 |
| SHUTDOWN_PREPARE | AP 应准备关机。第二个值指示是否允许 AP 推迟关机,以及 AP 应预期断电还是进入深度睡眠。 |
| CANCEL_SHUTDOWN | AP 应停止准备关机,并准备进入开启状态。 |
| FINISHED | AP 现在将关机或挂起。 |
VehicleApPowerStateShutdownParam 在 VehicleApPowerStateShutdownParam.aidl 中定义。此枚举具有以下元素
| 值名称 | 说明 |
|---|---|
| CAN_SLEEP | AP 可以进入深度睡眠而不是完全关机。允许推迟。 |
| CAN_HIBERNATE | AP 可以进入休眠而不是完全关机。允许推迟。 |
| SHUTDOWN_ONLY | AP 应关机。允许推迟。不允许深度睡眠。 |
| SLEEP_IMMEDIATELY | AP 可以进入深度睡眠,但必须立即睡眠或关机。不允许推迟。 |
| HIBERNATE_IMMEDIATELY | AP 可以进入挂起到磁盘状态,但必须立即休眠或关机。不允许推迟。 |
| SHUTDOWN_IMMEDIATELY | AP 必须立即关机。不允许推迟。不允许深度睡眠。 |
唤醒源
集成商必须在设备处于暂停模式时禁用适当的唤醒源。常见的唤醒源包括心跳信号、调制解调器、Wi-Fi 和蓝牙。唯一有效的唤醒源必须是来自 VMCU 的中断,以唤醒 SoC。这假设 VMCU 可以监听调制解调器以获取远程唤醒事件(例如远程引擎启动)。如果此功能被推送到 AP,则必须添加另一个唤醒源来服务调制解调器。
应用
OEM 必须小心编写应用,使其可以快速关闭,而不会无限期地推迟该过程。
附录
源代码树中的目录
| 内容 | 目录 |
|---|---|
| 与 CarPowerManager 相关的代码。 | packages/services/Car/car-lib/src/android/car/hardware/power |
| CarPowerManagementService 等。 | packages/services/Car/service/src/com/android/car/power |
处理 VHAL 的服务,例如 VehicleHal 和 HAlClient。 |
packages/services/Car/service/src/com/android/car/hal |
| VHAL 接口和属性定义。 | hardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ |
提供有关 CarPowerManager 的一些想法的示例应用 |
packages/services/Car/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink |
类图
此类图显示了电源管理系统中的 Java 类和接口

图 4. 电源类图。
对象关系
图 5 说明了哪些对象引用了其他对象。边表示源对象持有对目标对象的引用。例如,VehicleHAL 引用了 PropertyHalService 对象。

图 5. 对象引用图。