實施健康 2.1

在 Android 11 中,所有healthd代碼都被重構為libhealthlooplibhealth2impl ,然後進行修改以實現 health@2.1 HAL。這兩個庫由health@2.0-impl-2.1靜態鏈接,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. healthdIHealth註冊到hwservicemanager ,儘管它是一個系統守護進程。 IHealth被添加到系統清單中,實例名稱為“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 中,供應商可以在傳遞給健康實現類構造函數之前覆蓋healthd_config結構中的這兩個週期性雜項間隔值。健康實現類應該繼承自android::hardware::health::V2_1::implementation::Health

實施 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

    出於安全考慮,不允許應用直接調用 Health HAL。在 Android 9 及更高版本中,綁定服務IBatteryPropertiesRegistrarBatteryService而不是healthd提供。 BatteryService將調用委託給運行狀況 HAL 以檢索請求的信息。

  • 電池服務。在 Android 9 及更高版本中, BatteryService使用HealthServiceWrapper來確定是使用來自vendor默認健康服務實例還是使用來自healthd備份健康服務實例。 BatteryService然後通過IHealth.registerCallback監聽健康事件。

  • 存儲。在 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 (在健康 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 (在健康 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 (在健康 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 ,可能是可選的。但是,為了防止由於缺少內核接口而導致框架行為不正確,建議在構建健康 HAL 2.1 服務之前選擇CL 1398913

測試

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

電池信息要求

健康 2.0 HAL 對 HAL 接口提出了一組要求,但相應的 VTS 測試在執行方面相對寬鬆。在 Android 11 中,添加了新的 VTS 測試以對搭載 Android 11 及更高版本的設備強制執行以下要求:

  • 無電流和平均電池電流的單位必須是微安 (μA)。
  • 瞬時和平均電池電流的符號必須正確。具體來說:
    • current == 0 當電池狀態為UNKNOWN
    • 當電池狀態為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 電源類