動態可用的 HAL

Android 9 支持在 Android 硬件子系統不使用或不需要時動態關閉它們。例如,當用戶不使用 Wi-Fi 時,Wi-Fi 子系統不應佔用內存、電源或其他系統資源。在早期版本的 Android 中,HAL/驅動程序在 Android 手機啟動的整個期間都在 Android 設備上保持打開狀態。

實施動態關閉涉及連接數據流和執行動態過程,如以下部分所述。

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_startctl.interface_stopctl.interface_restart 。這些消息可用於向init發出信號以啟動和關閉特定的硬件接口。當請求服務但未註冊時, hwservicemanager請求啟動該服務。但是,動態 HAL 不需要使用任何這些。

確定 HAL 退出

在 Android 9 中,必須手動確定 HAL 退出。對於 Android 10 及更高版本,也可以通過自動生命週期來確定。

動態關閉需要多個策略來決定何時啟動 HAL 以及何時關閉 HAL。如果 HAL 出於任何原因決定退出,它將在再次需要時使用 HAL 定義中提供的信息以及對inithwservicemanager的更改提供的基礎架構自動重新啟動。這可能涉及幾種不同的策略,包括:

  • 如果有人在 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()以確保通知綁定器驅動程序相關的引用計數變化。