Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

Health の実装

すべての healthd コードが health@2.0-impl と libhealthservice にリファクタリングされ、health2.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.0 には次のクライアントがあります。

  • chargerlibbatterymonitorhealthd_common コードの使用は health@2.0-impl にラップされています。
  • recoverylibbatterymonitor へのリンクは health@2.0-impl にラップされています。BatteryMonitor へのすべての呼び出しは、Health 実装クラスへの呼び出しに置き換えられます。
  • BatteryManagerBatteryManager.queryProperty(int id) は、healthd によって提供されて /sys/class/power_supply を直接読み込む IBatteryPropertiesRegistrar.getProperty の唯一のクライアントでした。

    セキュリティ上の考慮事項として、アプリは Health HAL を直接呼び出すことができません。Android 9 では、healthd ではなく BatteryService によってバインダー サービス IBatteryPropertiesRegistrar が提供され、BatteryService は Health HAL への呼び出しを委任して、必要な情報を取得します。

  • BatteryService。Android 9 では、BatteryService は使用するヘルスサービス インスタンス(ベンダーの「default」インスタンスまたは healthd の「backup」インスタンス)を HealthServiceWrapper を使用して特定します。その後、IHealth.registerCallback を介してヘルスイベントをリッスンします。

  • Storaged。Android 9 では、storaged は使用するヘルスサービス インスタンス(ベンダーの「default」インスタンスまたは healthd の「backup」インスタンス)を libhealthhalutils を使用して特定します。その後、IHealth.registerCallback を介してヘルスイベントをリッスンしてストレージ情報を取得します。

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.
    

カーネル インターフェース

healthd デーモンとデフォルト実装 android.hardware.health@2.0-service は、次のカーネル インターフェースにアクセスして電池情報を取得します。

  • /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

libbatterymonitor を使用するデバイス固有の Health HAL 実装は、healthd_board_init(struct healthd_config*) でオーバーライドされない限り、デフォルトでこれらのカーネル インターフェースにアクセスします。

これらのファイルが見つからないか、healthd またはデフォルト サービスからアクセス不能な場合(このファイルが、SELinux ポリシーの誤った設定が原因でアクセスを拒否するベンダー固有のフォルダへのシンボリック リンクである場合など)は、実装が正常に機能しない可能性があります。したがって、デフォルトの実装が使用されていても、ベンダー固有の SELinux の変更が追加で必要になることがあります。

テスト

Android 9 には、health@2.0 HAL 専用の新しい VTS テストが含まれています。デバイス マニフェストで health@2.0 HAL の提供が宣言されているデバイスは、対応する VTS テストに合格する必要があります。テストは、デバイスで HAL を正しく実装するためのデフォルト インスタンスと、削除されるまで healthd を正しく機能させるためのバックアップ インスタンスの両方を対象に作成されています。