所有healthd
代码都被重构为 health@2.0-impl 和libhealthservice
,然后修改为实现 health@2.0 HAL。这两个库由 health@2.0-service 静态链接,使其能够完成之前由healthd
完成的工作(即运行healthd_mainloop
并进行轮询)。在 init 中, health@2.0-service 将接口IHealth
的实现注册到hwservicemanager
。使用 Android 8.x 供应商映像和 Android 9 框架升级设备时,供应商映像可能不提供 health@2.0 服务。这是由弃用计划强制执行的。
要解决此问题:
-
healthd
将IHealth
注册到hwservicemanager
(尽管是系统守护进程)。IHealth
被添加到系统清单中,实例名称为“backup”。 - 框架和
storaged
通过hwbinder
而不是binder
与healthd
通信。 - 框架和
storaged
的代码被更改为获取实例“默认”(如果可用),然后是“备份”。- C++ 客户端代码使用
libhealthhalutils
中定义的逻辑。 - Java 客户端代码使用
HealthServiceWrapper
中定义的逻辑。
- C++ 客户端代码使用
- 在 IHealth/default 广泛可用且 Android 8.1 供应商映像被弃用后,可以弃用 IHealth/backup 和
healthd
。有关更多详细信息,请参阅弃用 health@1.0 。
healthd 的特定于板的构建变量
BOARD_PERIODIC_CHORES_INTERVAL_*
是用于构建healthd
的特定于板的变量。作为系统/供应商构建拆分的一部分,无法为系统模块定义特定于板的值。在 health@2.0 中,供应商可以在healthd_mode_ops->init
中覆盖这两个值(通过在health@2.0-service.<device>
中删除libhealthservice
依赖并重新实现此功能)。
静态实现库
与其他 HAL 实现库不同,实现库 health@2.0-impl 是一个静态库,health@2.0-service、charger、recovery 和 legacy healthd 链接到该库。
health@2.0.impl 实现了如上所述的IHealth
,旨在包裹libbatterymonitor
和libhealthd. BOARD
。这些 health@2.0-impl 的用户不得直接使用BatteryMonitor
或libhealthd
中的功能;相反,这些调用应替换为对Health
类的调用,即IHealth
接口的实现。为了进一步概括, healthd_common
代码也包含在 health@2.0-impl 中。新的healthd_common
包含 health@2.0-service、charger 和healthd
之间的其余公共代码,并调用 IHealth 方法而不是 BatteryMonitor。
实施健康 2.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 权限。
通过将直通实现安装到恢复映像,在恢复中实现 HAL。例子:
// Android.bp cc_library_shared { name: "android.hardware.health@2.0-impl-<device>", recovery_available: true, relative_install_path: "hw", static_libs: [ "android.hardware.health@2.0-impl", "libhealthd.<device>" // Include the following or implement device-specific storage APIs "libhealthstoragedefault", ], srcs: [ "HealthImpl.cpp", ], overrides: [ "android.hardware.health@2.0-impl-default", ], }
// HealthImpl.cpp #include <health2/Health.h> #include <healthd/healthd.h> using android::hardware::health::V2_0::IHealth; using android::hardware::health::V2_0::implementation::Health; extern "C" IHealth* HIDL_FETCH_IHealth(const char* name) { const static std::string providedInstance{"default"}; if (providedInstance != name) return nullptr; return Health::initInstance(&gHealthdConfig).get(); }
# device.mk PRODUCT_PACKAGES += android.hardware.health@2.0-impl-<device>
有关详细信息,请参阅hardware/interfaces/health/2.0/README.md 。
健康客户
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.
内核接口
测试
Android 9 包含专门为 health@2.0 HAL 编写的新VTS 测试。如果设备在设备清单中声明提供 health@2.0 HAL,则它必须通过相应的 VTS 测试。为默认实例(以确保设备正确实现 HAL)和备份实例(以确保healthd
在被删除之前继续正常运行)编写测试。
电池信息要求
请参阅电池信息要求。