在 Android 11 中,所有 healthd
程式碼都會重構為 libhealthloop
和 libhealth2impl
,然後修改為實作 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
會向 hwservicemanager
註冊介面 IHealth
的實作項目。使用 Android 8.x 或 9 供應商映像檔和 Android 11 架構升級裝置時,供應商映像檔可能不會提供 health@2.1 服務。淘汰時間表會強制執行舊版供應商圖片的回溯相容性。
如要確保回溯相容性,請採取下列做法:
healthd
會向hwservicemanager
註冊IHealth
,即使是系統精靈也一樣。系統資訊清單會新增IHealth
,執行個體名稱為「backup」。- 架構和
storaged
會透過hwbinder
與healthd
通訊,而不是binder
。 - 架構和
storaged
的程式碼會變更為擷取「default」例項 (如有),然後擷取「backup」。- C++ 用戶端程式碼會使用
libhealthhalutils
中定義的邏輯。 - Java 用戶端程式碼會使用
HealthServiceWrapper
中定義的邏輯。
- C++ 用戶端程式碼會使用
- IHealth/default 廣泛推出後,Android 8.1 供應商映像檔就會遭到淘汰,屆時 IHealth/backup 和
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。
BatteryManager.queryProperty(int id)
是IBatteryPropertiesRegistrar.getProperty
的唯一用戶端。IBatteryPropertiesRegistrar.getProperty
是由healthd
提供,並直接讀取/sys/class/power_supply
。基於安全考量,應用程式不得直接呼叫健康 HAL。在 Android 9 以上版本中,繫結器服務
IBatteryPropertiesRegistrar
由BatteryService
提供,而非healthd
。BatteryService
會將呼叫委派給健康 HAL,以擷取所要求的資訊。BatteryService. 在 Android 9 以上版本中,
BatteryService
會使用HealthServiceWrapper
判斷要使用vendor
中的預設健康狀態服務執行個體,還是healthd
中的備份健康狀態服務執行個體。BatteryService
接著會透過IHealth.registerCallback
監聽健康狀態事件。Storaged。在 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 變更。
健康 2.1 中使用的部分核心介面 (例如 /sys/class/power_supply/*/capacity_level
和 /sys/class/power_supply/*/time_to_full_now
) 可能為選用介面。不過,為避免因缺少核心介面而導致架構行為不正確,建議您先挑選 CL 1398913,再建構 Health HAL 2.1 服務。
測試
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)。
- 即時和平均電池電流的正負號必須正確。
具體來說:
- 電池狀態為
UNKNOWN
時,current == 0 - 電池狀態為
CHARGING
時,current > 0 - 電池狀態為
NOT_CHARGING
時,電流 <= 0 - 電池狀態為
DISCHARGING
時,current < 0 - 電池狀態為
FULL
時不會強制執行
- 電池狀態為
- 電池狀態必須與電源是否已連接相符。具體來說:
- 如果已接上電源,電池狀態必須是
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 電源供應器類別」。