所有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"
。 - Framework 和
storaged
透過hwbinder
而不是binder
與healthd
通訊。 - Framework 和
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
中覆寫這兩個值(透過刪除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、充電器和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
在被刪除之前繼續正常運行)編寫了測試。
電池資訊要求
請參閱電池資訊要求。