在 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
和輪詢。在初始化中,health@2.1-service
會將介面 IHealth
的實作項目註冊至 hwservicemanager
。升級搭載 Android 8.x 或 9 供應商映像檔和 Android 11 架構的裝置時,供應商映像檔可能不會提供 health@2.1 服務。淘汰時間表會強制執行與舊版供應商映像檔的回溯相容性。
為確保回溯相容性:
healthd
雖然是系統守護程式,但會將IHealth
註冊至hwservicemanager
。IHealth
會加入系統資訊清單,並使用「backup」做為例項名稱。- 架構和
storaged
會透過hwbinder
與healthd
通訊,而非binder
。 - 架構和
storaged
的程式碼會變更為擷取「預設」例項 (如果可用),然後擷取「備用」例項。- C++ 用戶端程式碼會使用
libhealthhalutils
中定義的邏輯。 - Java 用戶端程式碼會使用
HealthServiceWrapper
中定義的邏輯。
- C++ 用戶端程式碼會使用
- 在 IHealth/預設廣泛提供,且 Android 8.1 供應商映像檔已淘汰後,IHealth/備份和
healthd
也將淘汰。詳情請參閱 Deprecating 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
中包裝。 - recovery。
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
監聽運作狀態事件。已保存。在 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
」時未強制執行
- 目前電量為
- 電池狀態必須正確,才能判斷是否已連上電源。具體情況如下:
- 電池狀態必須為
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 電源供應類別」。