动态可用的 HAL
Android 9 支持在不使用或不需要 Android 硬件子系统时动态关停这些子系统。例如,如果用户未使用 WLAN,WLAN 子系统就不应占用内存、耗用电量或使用其他系统资源。早期版本的 Android 中,在 Android 手机启动的整个期间,Android 设备上的 HAL/驱动程序都会保持开启状态。
实现动态关停涉及连接数据流以及执行动态进程,下文对此进行了详细介绍。
对 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 oneshot 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 调用关闭命令或类似的 API,则 HAL 可能会选择自行调用退出命令。此行为必须在相应的 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()
,以确保 Binder 驱动程序在相关引用计数发生变化时收到通知。