實施健康 2.1

在 Android 11 中,所有healthd程式碼都被重構為libhealthlooplibhealth2impl ,然後進行修改以實作 health@2.1 HAL。這兩個函式庫透過health@2.0-impl-2.1 (health 2.1 的直通實作)靜態連結。靜態連結函式庫使health@2.0-impl-2.1能夠執行與healthd相同的工作,例如執行healthd_mainloop和輪詢。在 init 中, health@2.1-service將介面IHealth的實作註冊到hwservicemanager 。當使用 Android 8.x 或 9 供應商映像和 Android 11 框架升級裝置時,供應商映像可能不提供 health@2.1 服務。與舊供應商映像的向後相容性是透過棄用計劃強制執行的。

為了確保向後相容性:

  1. 儘管是系統守護進程, healthd仍將IHealth註冊到hwservicemanagerIHealth已新增至系統清單中,實例名稱為「backup」。
  2. 框架和storaged透過hwbinder而不是binderhealthd通訊。
  3. Framework 和storaged的程式碼已變更為取得實例「預設」(如果可用),然後取得「備份」。
    • C++ 用戶端程式碼使用libhealthhalutils中定義的邏輯。
    • Java 用戶端程式碼使用HealthServiceWrapper中定義的邏輯。
  4. 在 IHealth/default 廣泛可用並且棄用 Android 8.1 供應商映像後,可以棄用 IHealth/backup 和healthd 。有關更多詳細信息,請參閱棄用 health@1.0

healthd 的特定於主機板的建構變數

BOARD_PERIODIC_CHORES_INTERVAL_*是用於建構healthd主機板特定變數。作為系統/供應商建置拆分的一部分,無法為系統模組定義特定於板的值。這些值過去在已棄用的函數healthd_board_init中被覆寫。

在 health@2.1 中,供應商可以在傳遞給 health 實作類別建構函數之前覆寫healthd_config結構中的這兩個週期性雜務間隔值。 health 實作類別應該繼承自android::hardware::health::V2_1::implementation::Health

實施健康2.1服務

有關實施 Health 2.1 服務的信息,請參閱hardware/interfaces/health/2.1/README.md

健康客戶

health@2.x 有以下客戶:

  • 充電器libbatterymonitorhealthd_common程式碼的使用包含在health@2.0-impl中。
  • 恢復。與libbatterymonitor的連結包含在health@2.0-impl中。所有對BatteryMonitor的呼叫都被對Health實作類別的呼叫所取代。
  • 電池管理器BatteryManager.queryProperty(int id)IBatteryPropertiesRegistrar.getProperty的唯一客戶端。 IBatteryPropertiesRegistrar.getPropertyhealthd提供,直接讀取/sys/class/power_supply

    出於安全考慮,應用程式不允許直接調用健康 HAL。在 Android 9 及更高版本中,綁定器服務IBatteryPropertiesRegistrarBatteryService而不是healthd提供。 BatteryService將呼叫委託給運行狀況 HAL 以擷取請求的資訊。

  • 電池服務。在 Android 9 及更高版本中, BatteryService使用HealthServiceWrapper來確定是使用vendor預設運行狀況服務實例還是使用healthd備份運行狀況服務實例。然後, BatteryService透過IHealth.registerCallback監聽運行狀況事件。

  • 儲存 d .在 Android 9 及更高版本中, storaged使用libhealthhalutils來確定是使用vendor預設運行狀況服務實例還是使用healthd備份運行狀況服務實例。 storaged接著透過IHealth.registerCallback監聽運行狀況事件並檢索儲存資訊。

SELinux 的變化

health@2.1 HAL 包括平台中的以下 SELinux 變更:

  • android.hardware.health@2.1-service新增至file_contexts

對於擁有自己實現的設備,可能需要對供應商 SELinux 進行一些更改。例子:

# 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-impl-2.1存取以下核心介面來檢索電池資訊:

  • /sys/class/power_supply/*/capacity_level (在 health 2.1 中新增)
  • /sys/class/power_supply/*/capacity
  • /sys/class/power_supply/*/charge_counter
  • /sys/class/power_supply/*/charge_full
  • /sys/class/power_supply/*/charge_full_design (在 health 2.1 中新增)
  • /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/*/time_to_full_now (在 health 2.1 中新增)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

預設情況下,任何使用libbatterymonitor的特定於裝置的運行狀況 HAL 實作都會存取這些核心接口,除非在運行狀況實作類別建構函式中被覆寫。

如果這些檔案遺失或無法從healthd或預設服務存取(例如,該檔案是指向特定於供應商的資料夾的符號鏈接,由於 SELinux 策略配置錯誤而拒絕存取),它們可能無法正常運作。因此,即使使用預設實現,也可能需要進行額外的特定於供應商的 SELinux 變更。

Health 2.1 中使用的某些核心介面(例如/sys/class/power_supply/*/capacity_level/sys/class/power_supply/*/time_to_full_now )可能是可選的。但是,為了防止因缺少核心介面而導致不正確的框架行為,建議在建立 health HAL 2.1 服務之前優先選擇CL 1398913

測試

Android 11 包含專為 health@2.1 HAL 編寫的新VTS 測試。如果設備在設備清單中聲明 health@2.1 HAL,則它必須通過相應的 VTS 測試。為預設實例(以確保設備正確實現 HAL)和備份實例(以確保healthd在被刪除之前繼續正常運行)編寫了測試。

電池資訊要求

health 2.0 HAL 對 HAL 介面提出了一系列要求,但相應的 VTS 測試在執行這些要求方面相對寬鬆。在 Android 11 中,新增了新的 VTS 測試,以對搭載 Android 11 及更高版本的裝置強制執行以下要求:

  • 電池瞬時電流和平均電流的單位必須為微安培 (μA)。
  • 電池瞬時電流和平均電流的符號必須正確。具體來說:
    • 電池狀態UNKNOWN時電流 == 0
    • 當電池狀態為CHARGING時電流 > 0
    • 當電池狀態為NOT_CHARGING時電流 <= 0
    • 當電池狀態為DISCHARGING時電流 < 0
    • 當電池狀態為FULL時不強制執行
  • 無論是否連接電源,電池狀態都必須正確。具體來說:
    • 當且僅連接電源時,電池狀態必須為CHARGINGNOT_CHARGINGFULL之一;
    • 當且僅當電源斷開時,電池狀態必須為DISCHARGING

如果您在實作中使用libbatterymonitor並傳遞來自核心介面的值,請確保 sysfs 節點報告正確的值:

  • 確保使用正確的符號和單位報告電池電流。這包括以下 sysfs 節點:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • 正值表示進入電池的電流。
    • 值應以微安培 (μA) 為單位。
  • 確保電池電壓以微伏特 (μV) 為單位報告。這包括以下 sysfs 節點:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • 請注意,預設的 HAL 實作將voltage_now除以 1000 並以毫伏特 (mV) 為單位報告值。請參閱@1.0::HealthInfo

詳細資訊請參閱Linux電源類別