Health 2.0 の実装

すべての healthd コードが health@2.0-impl と libhealthservice にリファクタリングされ、health@2.0 HAL を実装するように変更されました。これらの 2 つのライブラリは、health@2.0-service によって静的にリンクされ、以前は healthd が実行していた作業を行えるようになります(つまり、healthd_mainloop を実行してポーリングを行います)。init では、health@2.0-service がインターフェース IHealthhwservicemanager への実装を登録します。Android 8.x ベンダー イメージと Android 9 フレームワークを使用してデバイスをアップグレードする場合は、ベンダー イメージで health@2.0 サービスが提供されない可能性があります。これは、サポート終了予定によって決まります。

この問題を解決するには:

  1. healthdIHealthhwservicemanager に登録します(システム デーモンであるにもかかわらず)。IHealth が、インスタンス名 "backup" でシステム マニフェストに追加されます。
  2. フレームワークと storaged は、binder の代わりに hwbinder を介して 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 のビルドに使用されるボード固有の変数です。システムとベンダーのビルド分割の一環として、ボード固有の値はシステム モジュールに定義できません。health@2.0 では、ベンダーが healthd_mode_ops->init でこの 2 つの値をオーバーライドできます(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 のこれらのユーザーは、BatteryMonitor または libhealthd の関数を直接使用できません。代わりに、これらの呼び出しを Health クラスへの呼び出し(IHealth インターフェースの実装)に置き換える必要があります。さらに一般化するために、healthd_common コードも health@2.0-impl に含まれています。新しい healthd_common は、health@2.0-service、charger、healthd の残りの共通コードを含み、BatteryMonitor の代わりに IHealth メソッドを呼び出します。

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 の Health クライアントをご覧ください。

SELinux の変更

新しい health@2.0 HAL には、SELinux に関する次の変更が含まれています。

  • file_contexts に health@2.0-service が追加されています。
  • system_serverstoragedhal_health を使用できます。
  • system_serverBatteryService)で batteryproperties_serviceIBatteryPropertiesRegistrar)を登録できます。
  • healthdhal_health を提供できます。
  • バインダーを通じた healthd の呼び出しを system_server および storaged に許可するルールが削除されています。
  • healthdbatteryproperties_serviceIBatteryPropertiesRegistrar)の登録を許可するルールが削除されています。

独自の実装を含むデバイスでは、ベンダー 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 テストに合格する必要があります。テストは、デバイスで HAL を正しく実装するためのデフォルト インスタンスと、削除されるまで healthd を正しく機能させるためのバックアップ インスタンスの両方を対象に作成されています。

電池情報の要件

電池情報の要件をご覧ください。