实现 Health 2.0

所有 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 服务。这项服务是按照弃用时间表强制执行的。

为了解决此问题:

  1. healthd 会将 IHealth 注册到 hwservicemanager(尽管它是系统守护进程)。将 IHealth 添加到系统清单中(实例名称为“backup”)。
  2. 框架和 storaged 通过 hwbinder(而不是 binder)与 healthd 通信。
  3. 框架和 storaged 的代码会更改为获取实例“default”(如果有),然后获取“backup”实例。
    • C++ 客户端代码会使用 libhealthhalutils 中定义的逻辑。
    • Java 客户端代码使用 HealthServiceWrapper 中定义的逻辑。
  4. 在广泛推出 IHealth/default 实例且弃用 Android 8.1 供应商映像后,就可以弃用 IHealth/backup 实例和 healthd。如需了解详情,请参阅弃用 health@1.0

针对 healthd 的板级编译变量

BOARD_PERIODIC_CHORES_INTERVAL_* 是用于构建 healthd 的板级变量。在系统/供应商 build 拆分过程中,无法为系统模块定义板级值。在 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(如上所述),并旨在封装 libbatterymonitorlibhealthd.BOARD。health@2.0-impl 的用户不得使用 BatteryMonitorlibhealthd 中的函数;相反,这些调用应替换为对 Health 类(IHealth 接口的实现)的调用。为了进一步泛化,healthd_common 代码也会包含在 health@2.0-impl 中。新的 healthd_common 包含 health@2.0-service、Charger 和 healthd 之间的常用代码,并调用 IHealth 方法(而不是 BatteryMonitor)。

实现 Health 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_inithealthd_board_battery_update 函数提供空实现。
  • 如果板级 BOARD_PERIODIC_CHORES_INTERVAL_* 变量:

    • 已定义,请创建一个设备专用的 HealthServiceCommon.cpp(从 hardware/interfaces/health/2.0/utils/libhealthservice 复制)并在 healthd_mode_service_2_0_init 中进行自定义。
    • 未定义,则静态关联到 libhealthservice
  • 如果设备:

    • 应该实现 getStorageInfogetDiskStats API,并在 get_storage_infoget_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

Health 客户端

请参阅 Health 2.1 HAL 的运行状况客户端

SELinux 更改

新的 health@2.0 HAL 包括以下 SELinux 变更:

  • 将 health@2.0-service 添加到 file_contexts
  • 允许 system_serverstoraged 使用 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.

内核接口

请参阅 health 2.1 HAL 的内核接口

测试

Android 9 包括专门为 health@2.0 HAL 编写的新 VTS 测试。如果设备声明在设备清单中提供 health@2.0 HAL,则该设备必须通过相应的 VTS 测试。这些测试是为“default”实例(确保设备正确实现 HAL)和“backup”实例(确保 healthd 在移除之前继续正常发挥作用)编写的。

电池信息要求

请参阅电池信息要求