實現動態關閉涉及連接資料流並執行動態進程,如下列各節所述。
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
更改提供的基礎設施自動重新啟動。這可能涉及幾種不同的策略,包括:
- 如果有人呼叫 close 或類似的 API,HAL 可以選擇自行呼叫 exit。此行為必須在對應的 HAL 介面中指定。
- HAL 可以在任務完成後關閉(記錄在 HAL 檔案中)。
自動生命週期
Android 10 增加了對核心和hwservicemanager
更多支持,允許 HAL 在沒有客戶端時自動關閉。若要使用此功能,請執行HAL 定義變更中的所有步驟以及:
- 在 C++ 中使用
LazyServiceRegistrar
而非成員函式registerAsService
註冊服務,例如:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- 驗證 HAL 用戶端僅在使用時保留對頂級 HAL(使用
hwservicemanager
註冊的介面)的參考。為了避免在繼續執行的 hwbinder 執行緒上刪除此參考時出現延遲,用戶端也應該在刪除參考後呼叫IPCThreadState::self()->flushCommands()
,以確保向 Binder 驅動程式通知關聯的參考計數變更。