实现动态关机涉及连接数据流和执行动态过程,如下几节所述。
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 驱动程序收到关联的引用计数更改的通知。