在 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 电源类。