在 Android 11 中,所有healthd代碼都被重構為libhealthloop和libhealth2impl ,然後進行修改以實現 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 服務。棄用計劃強制執行與舊供應商映像的向後兼容性。
為確保向後兼容性:
-
healthd將IHealth註冊到hwservicemanager,儘管它是一個系統守護進程。IHealth被添加到系統清單中,實例名稱為“backup”。 - 框架和
storaged通過hwbinder而不是binder與healthd通信。 - framework 和
storaged的代碼已更改為獲取實例“默認”(如果可用),然後是“備份”。- C++ 客戶端代碼使用
libhealthhalutils中定義的邏輯。 - Java 客戶端代碼使用
HealthServiceWrapper中定義的邏輯。
- C++ 客戶端代碼使用
- 在 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 有以下客戶端:
- 充電器。
libbatterymonitor和healthd_common代碼的使用包含在health@2.0-impl中。 - 恢復。與
libbatterymonitor的鏈接包含在health@2.0-impl中。所有對BatteryMonitor的調用都被對Health實現類的調用所取代。 電池管理器。
BatteryManager.queryProperty(int id)是IBatteryPropertiesRegistrar.getProperty的唯一客戶端。IBatteryPropertiesRegistrar.getProperty由healthd提供,直接讀取/sys/class/power_supply。出於安全考慮,不允許應用直接調用 Health HAL。在 Android 9 及更高版本中,綁定服務
IBatteryPropertiesRegistrar由BatteryService而不是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時不強制執行
- current == 0 當電池狀態為
- 電池狀態必須與是否連接電源正確。具體來說:
- 當且僅當連接了電源時,電池狀態必須是
CHARGING、NOT_CHARGING或FULL之一; - 當且僅當電源斷開時,電池狀態必須為
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 電源類。