すべての healthd
コードが health@2.0-impl と libhealthservice
にリファクタリングされ、health2.0 HAL を実装するように変更されました。これらの 2 つのライブラリは、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
は、binder
の代わりにhwbinder
を介してhealthd
と通信します。 - フレームワークと
storaged
のコードが、インスタンス「default」と、可能であれば「backup」を取得するように変更されます。- 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
でこの 2 つの値をオーバーライドできます(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
の関数を直接使用できません。代わりに、これらの呼び出しを 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_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 をご覧ください。
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)
は、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_server
とstoraged
でhal_health
を使用できます。system_server
(BatteryService
)でbatteryproperties_service
(IBatteryPropertiesRegistrar
)を登録できます。healthd
でhal_health
を提供できます。- バインダーを介した
healthd
の呼び出しをsystem_server
またはstoraged
に許可するルールが削除されています。 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.
カーネル インターフェース
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
を正しく機能させるためのバックアップ インスタンスの両方を対象に作成されています。