在 Android 11 中,所有healthd代码都被重构为libhealthloop和libhealth2impl ,然后进行修改以实现 health@2.1 HAL。这两个库由health@2.0-impl-2.1静态链接,health@2.0-impl-2.1 是 health 2.1 的直通实现。静态链接库使health@2.0-impl-2.1能够执行与healthd相同的工作,例如运行healthd_mainloop和轮询。在 init 中, health@2.1-service将接口IHealth的实现注册到hwservicemanager 。升级具有 Android 8.x 或 9 供应商映像和 Android 11 框架的设备时,供应商映像可能不提供 health@2.1 服务。弃用计划强制执行与旧供应商映像的向后兼容性。
为确保向后兼容性:
-
healthd将IHealth注册到hwservicemanager,尽管它是一个系统守护进程。IHealth被添加到系统清单中,实例名称为“backup”。 - 框架和
storaged通过hwbinder而不是binder与healthd通信。 - framework 和
storaged的代码已更改为获取实例“默认”(如果可用),然后是“备份”。- C++ 客户端代码使用
libhealthhalutils中定义的逻辑。 - Java 客户端代码使用
HealthServiceWrapper中定义的逻辑。
- C++ 客户端代码使用
- 在 IHealth/default 广泛可用且 Android 8.1 供应商映像被弃用后,可以弃用 IHealth/backup 和
healthd。有关更多详细信息,请参阅弃用 health@1.0 。
healthd 的特定于板的构建变量
BOARD_PERIODIC_CHORES_INTERVAL_*是用于构建healthd的特定于板的变量。作为系统/供应商构建拆分的一部分,无法为系统模块定义特定于板的值。这些值曾经在已弃用的函数healthd_board_init中被覆盖。
在 health@2.1 中,供应商可以在传递给健康实现类构造函数之前覆盖healthd_config结构中的这两个周期性杂项间隔值。健康实现类应该继承自android::hardware::health::V2_1::implementation::Health 。
实施 Health 2.1 服务
有关实施 Health 2.1 服务的信息,请参阅hardware/interfaces/health/2.1/README.md 。
健康客户
health@2.x 有以下客户端:
- 充电器。
libbatterymonitor和healthd_common代码的使用包含在health@2.0-impl中。 - 恢复。与
libbatterymonitor的链接包含在health@2.0-impl中。所有对BatteryMonitor的调用都被对Health实现类的调用所取代。 电池管理器。
BatteryManager.queryProperty(int id)是IBatteryPropertiesRegistrar.getProperty的唯一客户端。IBatteryPropertiesRegistrar.getProperty由healthd提供,直接读取/sys/class/power_supply。出于安全考虑,不允许应用直接调用 Health HAL。在 Android 9 及更高版本中,绑定服务
IBatteryPropertiesRegistrar由BatteryService而不是healthd提供。BatteryService将调用委托给运行状况 HAL 以检索请求的信息。电池服务。在 Android 9 及更高版本中,
BatteryService使用HealthServiceWrapper来确定是使用来自vendor的默认健康服务实例还是使用来自healthd的备份健康服务实例。BatteryService然后通过IHealth.registerCallback监听健康事件。存储。在 Android 9 及更高版本中,
storaged使用libhealthhalutils来确定是使用来自vendor的默认健康服务实例还是使用来自healthd的备份健康服务实例。storaged然后通过IHealth.registerCallback监听健康事件并检索存储信息。
SELinux 变化
health@2.1 HAL 包括平台中的以下 SELinux 更改:
- 将
android.hardware.health@2.1-service添加到file_contexts。
对于具有自己实现的设备,可能需要对供应商的 SELinux 进行一些更改。例子:
# device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te
# Add device specific permissions to hal_health_default domain, especially
# if it links to board-specific libhealthd or implements storage APIs.
内核接口
healthd守护进程和默认实现android.hardware.health@2.0-impl-2.1访问以下内核接口以检索电池信息:
-
/sys/class/power_supply/*/capacity_level(在健康 2.1 中添加) -
/sys/class/power_supply/*/capacity -
/sys/class/power_supply/*/charge_counter -
/sys/class/power_supply/*/charge_full -
/sys/class/power_supply/*/charge_full_design(在健康 2.1 中添加) -
/sys/class/power_supply/*/current_avg -
/sys/class/power_supply/*/current_max -
/sys/class/power_supply/*/current_now -
/sys/class/power_supply/*/cycle_count -
/sys/class/power_supply/*/health -
/sys/class/power_supply/*/online -
/sys/class/power_supply/*/present -
/sys/class/power_supply/*/status -
/sys/class/power_supply/*/technology -
/sys/class/power_supply/*/temp -
/sys/class/power_supply/*/time_to_full_now(在健康 2.1 中添加) -
/sys/class/power_supply/*/type -
/sys/class/power_supply/*/voltage_max -
/sys/class/power_supply/*/voltage_now
默认情况下,使用libbatterymonitor的任何特定于设备的运行状况 HAL 实现都会访问这些内核接口,除非在运行状况实现类构造函数中被覆盖。
如果这些文件丢失或无法从healthd或默认服务访问(例如,该文件是指向供应商特定文件夹的符号链接,由于 SELinux 策略配置错误而拒绝访问),它们可能无法正常运行。因此,即使使用了默认实现,也可能需要额外的特定于供应商的 SELinux 更改。
Health 2.1 中使用的一些内核接口,例如/sys/class/power_supply/*/capacity_level和/sys/class/power_supply/*/time_to_full_now ,可能是可选的。但是,为了防止由于缺少内核接口而导致框架行为不正确,建议在构建健康 HAL 2.1 服务之前选择CL 1398913 。
测试
Android 11 包含专门为 health@2.1 HAL 编写的新VTS 测试。如果设备在设备清单中声明了 health@2.1 HAL,则它必须通过相应的 VTS 测试。为默认实例(以确保设备正确实现 HAL)和备份实例(以确保healthd在被删除之前继续正常运行)编写测试。
电池信息要求
健康 2.0 HAL 对 HAL 接口提出了一组要求,但相应的 VTS 测试在执行方面相对宽松。在 Android 11 中,添加了新的 VTS 测试以对搭载 Android 11 及更高版本的设备强制执行以下要求:
- 无电流和平均电池电流的单位必须是微安 (μA)。
- 瞬时和平均电池电流的符号必须正确。具体来说:
- current == 0 当电池状态为
UNKNOWN时 - 当电池状态为
CHARGING时,电流 > 0 - 当电池状态为
NOT_CHARGING时,电流 <= 0 - 当电池状态为
DISCHARGING时,电流 < 0 - 电池状态为
FULL时不强制执行
- current == 0 当电池状态为
- 电池状态必须与是否连接电源正确。具体来说:
- 当且仅当连接了电源时,电池状态必须是
CHARGING、NOT_CHARGING或FULL之一; - 当且仅当电源断开时,电池状态必须为
DISCHARGING。
- 当且仅当连接了电源时,电池状态必须是
如果您在实现中使用libbatterymonitor并传递来自内核接口的值,请确保 sysfs 节点报告正确的值:
- 确保使用正确的符号和单位报告电池电流。这包括以下 sysfs 节点:
-
/sys/class/power_supply/*/current_avg -
/sys/class/power_supply/*/current_max -
/sys/class/power_supply/*/current_now - 正值表示进入电池的电流。
- 值应以微安 (μA) 为单位。
-
- 确保以微伏 (μV) 为单位报告电池电压。这包括以下 sysfs 节点:
-
/sys/class/power_supply/*/voltage_max -
/sys/class/power_supply/*/voltage_now - 请注意,默认 HAL 实现将
voltage_now除以 1000 并以毫伏 (mV) 为单位报告值。请参阅@1.0::HealthInfo 。
-
详见Linux 电源类。