實作 Health 2.0

所有 healthd 程式碼都已重構為 health@2.0-impl 和 libhealthservice,然後修改為實作 health@2.0 HAL。這兩個程式庫會由 health@2.0-service 靜態連結,讓它執行先前由 healthd 執行的工作 (也就是執行 healthd_mainloop 並進行輪詢)。在初始化時,health@2.0-service 會將介面 IHealth 的實作項目註冊至 hwservicemanager。升級搭載 Android 8.x 供應商映像檔和 Android 9 架構的裝置時,供應商映像檔可能不會提供 health@2.0 服務。這項規定是由淘汰時間表強制執行。

解決此問題的方法如下:

  1. healthd 會將 IHealth 註冊至 hwservicemanager (儘管是系統 Daemon)。IHealth 已新增至系統資訊清單,並附上執行個體名稱 "backup"
  2. 架構和 storaged 會透過 hwbinderhealthd 通訊,而非 binder
  3. 系統會變更架構和 storaged 的程式碼,以擷取執行個體 "default" (如有),然後變更 "backup"
    • C++ 用戶端程式碼會使用 libhealthhalutils 中定義的邏輯。
    • Java 用戶端程式碼會使用 HealthServiceWrapper 中定義的邏輯。
  4. 在 IHealth/預設廣泛提供,且 Android 8.1 供應商映像檔已淘汰後,IHealth/備份和 healthd 也將淘汰。詳情請參閱 Deprecating 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、充電器、復原和舊版 healthd。

health@2.0.impl 會實作上述的 IHealth,並且用於包裝 libbatterymonitorlibhealthd.BOARD。Health@2.0-impl 的使用者不得直接使用 BatteryMonitorlibhealthd 中的函式;而是應將這些呼叫替換為 Health 類別 (為 IHealth 介面的實作) 的呼叫。為了進一步一般化,Health@2.0-impl 也提供 healthd_common 程式碼。新的 healthd_common 包含 health@2.0-service、充電器和 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 用戶端 for 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_serverstoraged 透過繫結器呼叫 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 測試。我們會為預設例項 (確保裝置正確實作 HAL) 和備份例項 (確保 healthd 在移除前繼續正常運作) 撰寫測試。

電池資訊規定

請參閱「電池資訊規定」。