动态可用的 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 更改提供的基础架构自动重启。这可能涉及几种不同的策略,包括

  • 如果有人在其上调用 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 驱动程序收到关联的引用计数更改的通知。