实施健康 2.1

在 Android 11 中,所有healthd代码都被重构为libhealthlooplibhealth2impl ,然后进行修改以实现 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 服务。弃用计划强制执行与旧供应商映像的向后兼容性。

为确保向后兼容性:

  1. healthdIHealth注册到hwservicemanager ,尽管它是一个系统守护进程。 IHealth被添加到系统清单中,实例名称为“backup”。
  2. 框架和storaged通过hwbinder而不是binderhealthd通信。
  3. framework 和storaged的​​代码已更改为获取实例“默认”(如果可用),然后是“备份”。
    • C++ 客户端代码使用libhealthhalutils中定义的逻辑。
    • Java 客户端代码使用HealthServiceWrapper中定义的逻辑。
  4. 在 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 有以下客户端:

  • 充电器libbatterymonitorhealthd_common代码的使用包含在health@2.0-impl中。
  • 恢复。与libbatterymonitor的链接包含在health@2.0-impl中。所有对BatteryMonitor的调用都被对Health实现类的调用所取代。
  • 电池管理器BatteryManager.queryProperty(int id)IBatteryPropertiesRegistrar.getProperty的唯一客户端。 IBatteryPropertiesRegistrar.getPropertyhealthd提供,直接读取/sys/class/power_supply

    出于安全考虑,不允许应用直接调用 Health HAL。在 Android 9 及更高版本中,绑定服务IBatteryPropertiesRegistrarBatteryService而不是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时不强制执行
  • 电池状态必须与是否连接电源正确。具体来说:
    • 当且仅当连接了电源时,电池状态必须是CHARGINGNOT_CHARGINGFULL之一;
    • 当且仅当电源断开时,电池状态必须为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 电源类