原文:https://source.android.com/devices/tech/health/implementation
healthd
的所有代码都已重构为health@2.0-impl
和libhealthservice
,然后修改HAL实现为health@2.0
。这两个库通过health@2.0-service
静态链接,使其能够完成之前healthd
的工作(如运行healthd_mainloop
和执行轮询)。在初始化时,health@2.0-service
将IHealth
的接口实现注册到hwservicemanager
。使用Android 8.x vendor镜像和Android 9 Framework升级设备时,vendor镜像可能不提供health@2.0
服务。这是由弃用计划强制执行的 。
要解决此问题:
-
healthd
注册IHealth
到hwservicemanager
(尽管是一个系统守护进程)。IHealth
添加到系统manifest
中,实例名为“backup”。 - Framework和
storaged
通过hwbinder
(而不是binder
)与healthd
进行通信。 - Framework代码和
storaged
更改为获取“default”实例(如果可用),然后“backup”。- C++端代码使用定义在
libhealthhalutils
中的逻辑。 - Java端代码使用定义在
HealthServiceWrapper
中的逻辑。
- C++端代码使用定义在
- 在
IHealth/default
广泛可用且Android 8.1 vendor镜像被弃用之后,IHealth/backup
和healthd
才被弃用。有关更多详细信息,请参阅弃用health@1.0。
healthd的特定板构建变量
BOARD_PERIODIC_CHORES_INTERVAL_*
是用于构建 healthd
的特定板的变量。作为system/vendor
构建拆分的一部分,无法为系统模块定义特定板的值 。在health@2.0
中,供应商可以覆盖healthd_mode_ops->init
中这两个值(通过删除依赖于health@2.0-service.<device>
的libhealthservice
并重新实现此功能)。
静态实现库
与其他HAL实现库不同,health@2.0-impl
实现库是一个静态库,其中包含health@2.0-service
, charger
, recovery
和遗留的healthd
链接。
如上所述health@2.0.impl
实现IHealth
,旨在包装libbatterymonitor
和libhealthd.BOARD
。这些health@2.0-impl
的用户不得直接使用BatteryMonitor
或libhealthd
中的功能 ; 相反,应该由实现IHealth
接口的Health
类调用。为进一步概括,healthd_common
代码也包含在health@2.0-impl
中。new 的healthd_common
包含health@2.0-service
, charger
和healthd
之间的其余的公共代码,并且取代BatteryMonitor
调用IHealth
方法。
Health2.0服务实现
为设备实现health@2.0
服务时,如果默认实现为:
- 设备充足,直接使用
android.hardware.health@2.0-service
。 - 对于设备来说还不够,创建
android.hardware.health@2.0-service.(device)
可执行文件并包含:
#include <health2/service.h>
int main() { return health_service_main(); }
然后:
- 如果
libhealthd
特定板:- 存在,链接到它。
- 不存在,提供
healthd_board_init
和healthd_board_battery_update
函数的空实现。
- 如果特定板的
BOARD_PERIODIC_CHORES_INTERVAL_*
变量:- 已定义,创建特定设备
HealthServiceCommon.cpp
(复制自hardware/interfaces/health/2.0/utils/libhealthservice
)并在healthd_mode_service_2_0_init
中客制化。 - 未定义,静态链接到
libhealthservice
。
- 已定义,创建特定设备
- 如果设备:
- 需要实现
getStorageInfo
和getDiskStats
API,则在get_storage_info
和get_disk_stats
函数中提供实现。 - 不用实现这些API,则静态链接到
libstoragehealthdefault
。
- 需要实现
- 更新必要的SELinux权限。
有关详细信息,请参阅 hardware/interfaces/health/2.0/README.md。
Health客户端
health@2.0
有以下客户端:
charger。
libbatterymonitor
和和healthd_common
代码的用法包含在health@2.0-impl
中。recovery。
libbatterymonitor
的链接包含在health@2.0-impl
中。所有BatteryMonitor
的调用都被Health
实现类的调用所取代 。-
BatteryManager。
BatteryManager.queryProperty(int id)
是唯一的一个IBatteryPropertiesRegistrar.getProperty
的客户端,其由healthd
提供并直接读/sys/class/power_supply
。出于安全考虑,应用不允许直接调用Health HAL。在Android 9中,
binder
服务IBatteryPropertiesRegistrar
是由BatteryService
提供而不是healthd
,并且BatteryService
委派通过Health的HAL调用来检索所请求的信息。 BatteryService。在Android 9中,
BatteryService
通过HealthServiceWrapper
来确定要使用的Health服务实例(来自vender
的“default”实例或来自healthd
的“backup”实例)。然后通过IHealth.registerCallback
监听取Health事件。Storaged。在Android 9中,
storaged
通过libhealthhalutils
来确定要使用的Health服务实例(来自vender
的“default”实例或来自healthd
的“backup”实例)。然后通过IHealth.registerCallback
来监听Health事件并检索存储信息。
SELinux变化
新的health@2.0 HAL
中SELinux的改动如下:
- 添加
health@2.0-service
至file_contexts
。 - 允许
system_server
和storaged
使用hal_health
。 - 允许
system_server
(BatteryService
)注册batteryproperties_service
(IBatteryPropertiesRegistrar
)。 - 允许
healthd
提供hal_health
。 - 移除允许
system_server/storaged
通过binder
调用healthd
的规则。 - 移除允许
healthd
注册batteryproperties_service(IBatteryPropertiesRegistrar)
的规则。
对于有自己实现的设备,某些供应商的SELinux改动可能是有必要的。例如:
# device/<manufacturer>/<device>/sepolicy/vendor/file_contexts
/vendor/bin/hw/android\.hardware\.health@2\.0-service.<device> u:object_r:hal_health_default_exec:s0
# 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.
Kernel接口
healthd
守护进程和 android.hardware.health@2.0-service
的默认实现访问以下Kernel接口来获取电池信息:
/sys/class/power_supply/*/capacity
/sys/class/power_supply/*/charge_counter
/sys/class/power_supply/*/charge_full
/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/*/type
/sys/class/power_supply/*/voltage_max
/sys/class/power_supply/*/voltage_now
否则任何特定设备的Health HAL实现都会默认使用libbatterymonitor
访问这些内核接口,除非在healthd_board_init(struct healthd_config*)
中被重写。
如果这些文件缺失,或者healthd
或默认服务从无法访问(如:文件是特定供应商文件夹的符号链接,由于SELinux的策略配置错误而拒绝访问),它们可能无法正常运行。因此,即使使用默认实现,也可能需要进行其他特定供应商的SELinux更改。
测试
Android 9包含专为health@2.0 HAL
编写的新VTS测试。如果设备声明在设备manifest
中提供health@2.0 HAL
,则必须通过相应的VTS测试。default
实例(确保设备正确实现HAL)和backup
实例(确保healthd
在删除之前继续正常运行)两者都要编写测试。