實施動態關閉涉及連接數據流和執行動態過程,如以下部分所述。
HAL 定義的更改
動態關閉需要有關哪些進程服務於哪些 HAL 接口的信息(此信息稍後在其他上下文中也可能有用)以及在啟動時不啟動進程並且在它們退出時不重新啟動它們(直到再次請求)。
# some init.rc script associated with the HAL
service vendor.some-service-name /vendor/bin/hw/some-binary-service
# init language extension, provides information of what service is served
# if multiple interfaces are served, they can be specified one on each line
interface android.hardware.light@2.0::ILight default
# restarted if hwservicemanager dies
# would also cause the hal to start early during boot if disabled wasn't set
class hal
# will not be restarted if it exits until it is requested to be restarted
oneshot
# will only be started when requested
disabled
# ... other properties對 init 和 hwservicemanager 的更改
動態關閉還需要hwservicemanager告訴init啟動請求的服務。在 Android 9 中, init包含三個額外的控制消息(例如ctl.start ): ctl.interface_start 、 ctl.interface_stop和ctl.interface_restart 。這些消息可用於向init發出信號以啟動和關閉特定的硬件接口。當請求服務但未註冊時, hwservicemanager請求啟動該服務。但是,動態 HAL 不需要使用任何這些。
確定 HAL 退出
在 Android 9 中,必須手動確定 HAL 退出。對於 Android 10 及更高版本,也可以通過自動生命週期來確定。
動態關閉需要多個策略來決定何時啟動 HAL 以及何時關閉 HAL。如果 HAL 出於任何原因決定退出,它將在再次需要時使用 HAL 定義中提供的信息以及對init和hwservicemanager的更改提供的基礎架構自動重新啟動。這可能涉及幾種不同的策略,包括:
- 如果有人在 HAL 上調用 close 或類似 API,則 HAL 可以選擇在其自身上調用 exit。此行為必須在相應的 HAL 接口中指定。
- HAL 可以在其任務完成時關閉(記錄在 HAL 文件中)。
自動生命週期
Android 10 為內核和hwservicemanager添加了更多支持,這允許 HAL 在沒有客戶端時自動關閉。要使用此功能,請執行更改 HAL 定義中的所有步驟以及:
- 使用
LazyServiceRegistrar而不是成員函數registerAsService在 C++ 中註冊服務,例如:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- 驗證 HAL 客戶端是否僅在使用時保留對頂級 HAL(使用
hwservicemanager註冊的接口)的引用。為避免在繼續執行的 hwbinder 線程上刪除此引用時出現延遲,客戶端還應在刪除引用後調用IPCThreadState::self()->flushCommands()以確保通知綁定器驅動程序相關的引用計數變化。