原文:https://source.android.com/devices/tech/health/implementation
healthd
的所有代碼都已重構(gòu)為health@2.0-impl
和libhealthservice
旋恼,然后修改HAL實現(xiàn)為health@2.0
棒仍。這兩個庫通過health@2.0-service
靜態(tài)鏈接,使其能夠完成之前healthd
的工作(如運行healthd_mainloop
和執(zhí)行輪詢)。在初始化時谆刨,health@2.0-service
將IHealth
的接口實現(xiàn)注冊到hwservicemanager
。使用Android 8.x vendor鏡像和Android 9 Framework升級設(shè)備時邑蒋,vendor鏡像可能不提供health@2.0
服務(wù)歇竟。這是由棄用計劃強(qiáng)制執(zhí)行的 。
要解決此問題:
-
healthd
注冊IHealth
到hwservicemanager
(盡管是一個系統(tǒng)守護(hù)進(jìn)程)。IHealth
添加到系統(tǒng)manifest
中纲菌,實例名為“backup”挠日。 - Framework和
storaged
通過hwbinder
(而不是binder
)與healthd
進(jìn)行通信。 - Framework代碼和
storaged
更改為獲取“default”實例(如果可用)翰舌,然后“backup”嚣潜。- C++端代碼使用定義在
libhealthhalutils
中的邏輯。 - Java端代碼使用定義在
HealthServiceWrapper
中的邏輯椅贱。
- C++端代碼使用定義在
- 在
IHealth/default
廣泛可用且Android 8.1 vendor鏡像被棄用之后郑原,IHealth/backup
和healthd
才被棄用。有關(guān)更多詳細(xì)信息夜涕,請參閱棄用health@1.0犯犁。
healthd的特定板構(gòu)建變量
BOARD_PERIODIC_CHORES_INTERVAL_*
是用于構(gòu)建 healthd
的特定板的變量。作為system/vendor
構(gòu)建拆分的一部分女器,無法為系統(tǒng)模塊定義特定板的值 酸役。在health@2.0
中,供應(yīng)商可以覆蓋healthd_mode_ops->init
中這兩個值(通過刪除依賴于health@2.0-service.<device>
的libhealthservice
并重新實現(xiàn)此功能)驾胆。
靜態(tài)實現(xiàn)庫
與其他HAL實現(xiàn)庫不同涣澡,health@2.0-impl
實現(xiàn)庫是一個靜態(tài)庫,其中包含health@2.0-service
, charger
, recovery
和遺留的healthd
鏈接丧诺。
如上所述health@2.0.impl
實現(xiàn)IHealth
入桂,旨在包裝libbatterymonitor
和libhealthd.BOARD
。這些health@2.0-impl
的用戶不得直接使用BatteryMonitor
或libhealthd
中的功能 ; 相反驳阎,應(yīng)該由實現(xiàn)IHealth
接口的Health
類調(diào)用抗愁。為進(jìn)一步概括,healthd_common
代碼也包含在health@2.0-impl
中呵晚。new 的healthd_common
包含health@2.0-service
, charger
和healthd
之間的其余的公共代碼蜘腌,并且取代BatteryMonitor
調(diào)用IHealth
方法。
Health2.0服務(wù)實現(xiàn)
為設(shè)備實現(xiàn)health@2.0
服務(wù)時饵隙,如果默認(rèn)實現(xiàn)為:
- 設(shè)備充足撮珠,直接使用
android.hardware.health@2.0-service
。 - 對于設(shè)備來說還不夠金矛,創(chuàng)建
android.hardware.health@2.0-service.(device)
可執(zhí)行文件并包含:
#include <health2/service.h>
int main() { return health_service_main(); }
然后:
- 如果
libhealthd
特定板:- 存在芯急,鏈接到它。
- 不存在驶俊,提供
healthd_board_init
和healthd_board_battery_update
函數(shù)的空實現(xiàn)娶耍。
- 如果特定板的
BOARD_PERIODIC_CHORES_INTERVAL_*
變量:- 已定義,創(chuàng)建特定設(shè)備
HealthServiceCommon.cpp
(復(fù)制自hardware/interfaces/health/2.0/utils/libhealthservice
)并在healthd_mode_service_2_0_init
中客制化废睦。 - 未定義伺绽,靜態(tài)鏈接到
libhealthservice
。
- 已定義,創(chuàng)建特定設(shè)備
- 如果設(shè)備:
- 需要實現(xiàn)
getStorageInfo
和getDiskStats
API,則在get_storage_info
和get_disk_stats
函數(shù)中提供實現(xiàn)奈应。 - 不用實現(xiàn)這些API澜掩,則靜態(tài)鏈接到
libstoragehealthdefault
。
- 需要實現(xiàn)
- 更新必要的SELinux權(quán)限杖挣。
有關(guān)詳細(xì)信息肩榕,請參閱 hardware/interfaces/health/2.0/README.md。
Health客戶端
health@2.0
有以下客戶端:
charger惩妇。
libbatterymonitor
和和healthd_common
代碼的用法包含在health@2.0-impl
中株汉。recovery。
libbatterymonitor
的鏈接包含在health@2.0-impl
中歌殃。所有BatteryMonitor
的調(diào)用都被Health
實現(xiàn)類的調(diào)用所取代 乔妈。-
BatteryManager。
BatteryManager.queryProperty(int id)
是唯一的一個IBatteryPropertiesRegistrar.getProperty
的客戶端氓皱,其由healthd
提供并直接讀/sys/class/power_supply
路召。出于安全考慮,應(yīng)用不允許直接調(diào)用Health HAL波材。在Android 9中股淡,
binder
服務(wù)IBatteryPropertiesRegistrar
是由BatteryService
提供而不是healthd
,并且BatteryService
委派通過Health的HAL調(diào)用來檢索所請求的信息廷区。 BatteryService唯灵。在Android 9中,
BatteryService
通過HealthServiceWrapper
來確定要使用的Health服務(wù)實例(來自vender
的“default”實例或來自healthd
的“backup”實例)隙轻。然后通過IHealth.registerCallback
監(jiān)聽取Health事件埠帕。Storaged。在Android 9中大脉,
storaged
通過libhealthhalutils
來確定要使用的Health服務(wù)實例(來自vender
的“default”實例或來自healthd
的“backup”實例)搞监。然后通過IHealth.registerCallback
來監(jiān)聽Health事件并檢索存儲信息。
SELinux變化
新的health@2.0 HAL
中SELinux的改動如下:
- 添加
health@2.0-service
至file_contexts
镰矿。 - 允許
system_server
和storaged
使用hal_health
。 - 允許
system_server
(BatteryService
)注冊batteryproperties_service
(IBatteryPropertiesRegistrar
)俘种。 - 允許
healthd
提供hal_health
秤标。 - 移除允許
system_server/storaged
通過binder
調(diào)用healthd
的規(guī)則。 - 移除允許
healthd
注冊batteryproperties_service(IBatteryPropertiesRegistrar)
的規(guī)則宙刘。
對于有自己實現(xiàn)的設(shè)備苍姜,某些供應(yīng)商的SELinux改動可能是有必要的。例如:
# device/<manufacturer>/<device>/sepolicy/vendor/file_contexts
/vendor/bin/hw/android\.hardware\.health@2\.0-service.<device> u:object_r:hal_health_default_exec:s0
# 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.
Kernel接口
healthd
守護(hù)進(jìn)程和 android.hardware.health@2.0-service
的默認(rèn)實現(xiàn)訪問以下Kernel接口來獲取電池信息:
/sys/class/power_supply/*/capacity
/sys/class/power_supply/*/charge_counter
/sys/class/power_supply/*/charge_full
/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/*/type
/sys/class/power_supply/*/voltage_max
/sys/class/power_supply/*/voltage_now
否則任何特定設(shè)備的Health HAL實現(xiàn)都會默認(rèn)使用libbatterymonitor
訪問這些內(nèi)核接口悬包,除非在healthd_board_init(struct healthd_config*)
中被重寫衙猪。
如果這些文件缺失,或者healthd
或默認(rèn)服務(wù)從無法訪問(如:文件是特定供應(yīng)商文件夾的符號鏈接,由于SELinux的策略配置錯誤而拒絕訪問)垫释,它們可能無法正常運行丝格。因此,即使使用默認(rèn)實現(xiàn)棵譬,也可能需要進(jìn)行其他特定供應(yīng)商的SELinux更改显蝌。
測試
Android 9包含專為health@2.0 HAL
編寫的新VTS測試。如果設(shè)備聲明在設(shè)備manifest
中提供health@2.0 HAL
订咸,則必須通過相應(yīng)的VTS測試曼尊。default
實例(確保設(shè)備正確實現(xiàn)HAL)和backup
實例(確保healthd
在刪除之前繼續(xù)正常運行)兩者都要編寫測試。