實施動態關閉涉及連接數據流和執行動態過程,如以下部分所述。
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()
以確保通知綁定器驅動程序相關的引用計數變化。