自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
动态可用的 HAL
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Android 9 支持动态关停未使用或不需要的 Android 硬件子系统。例如,如果用户未使用 Wi-Fi,Wi-Fi 子系统就不应占用内存、耗用电量或使用其他系统资源。早期版本的 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 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
提供的基础架构。这可能会涉及多个不同的策略,包括:
- 如果有人对 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 驱动程序在相关引用计数发生变化时收到通知。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-26。
[null,null,["最后更新时间 (UTC):2025-07-26。"],[],[],null,["# Dynamically available HALs\n\nAndroid 9 supports the dynamic shutdown of Android hardware subsystems when they are not in use or not needed. For example, when a user is not using Wi-Fi, the Wi-Fi subsystems should not be taking up memory, power, or other system resources. In earlier versions of Android, HALs/drivers were kept open on Android devices for the entire duration an Android phone was booted.\n\nImplementing dynamic shutdown involves wiring up data flows and executing\ndynamic processes as detailed in the following sections.\n\nChanges to HAL definitions\n--------------------------\n\nDynamic shutdown requires information on which processes serve what HAL\ninterfaces (this information may also be useful later in other contexts) as\nwell as not starting processes on boot and not restarting them (until\nrequested again) when they exit. \n\n```objective-c\n# some init.rc script associated with the HAL\nservice vendor.some-service-name /vendor/bin/hw/some-binary-service\n # init language extension, provides information of what service is served\n # if multiple interfaces are served, they can be specified one on each line\n interface android.hardware.light@2.0::ILight default\n # restarted if hwservicemanager dies\n # would also cause the hal to start early during boot if disabled wasn't set\n class hal\n # will not be restarted if it exits until it is requested to be restarted\n oneshot\n # will only be started when requested\n disabled\n # ... other properties\n```\n\nChanges to init and hwservicemanager\n------------------------------------\n\nDynamic shutdown also requires the `hwservicemanager` to tell\n`init` to start requested services. In Android 9,\n`init` includes three additional control messages (e.g.\n`ctl.start`): `ctl.interface_start`,\n`ctl.interface_stop`, and `ctl.interface_restart`.\nThese messages can be used to signal `init` to bring up and down\nspecific hardware interfaces. When a service is requested and isn't\nregistered, `hwservicemanager` requests that the service be\nstarted. However, dynamic HALs don't require using any of these.\n\nDetermine HAL exit\n------------------\n\nIn Android 9, HAL exit has to be manually\ndetermined. For Android 10 and higher, it can also\nbe determined with\n[automatic lifecycles](#automatic-lifecycles).\n\nDynamic shutdown requires multiple policies for deciding when to start a\nHAL and when to shutdown a HAL. If a HAL decides to exit for any reason, it\nwill automatically be restarted when it is needed again using the information\nprovided in the HAL definition and the infrastructure provided by changes to\n`init` and `hwservicemanager`. This could involve a\ncouple of different strategies, including:\n\n- A HAL could choose to call exit on itself if someone calls a close or similar API on it. This behavior must be specified in the corresponding HAL interface.\n- HALs can shut down when their task is completed (documented in the HAL file).\n\nAutomatic lifecycles\n--------------------\n\nAndroid 10 adds more support to the kernel and\n`hwservicemanager`, which allows HALs to shut down automatically\nwhenever they have no clients. To use this feature, do all of the steps in\n[Changes to HAL definitions](#changes-HAL-definitions) as well\nas:\n\n- Register the service in C++ with `LazyServiceRegistrar` instead of the member function, `registerAsService`, for example: \n\n ```scilab\n // only one instance of LazyServiceRegistrar per process\n LazyServiceRegistrar registrar;\n registrar.registerAsService(myHidlService /* , \"default\" */);\n ```\n- Verify that the HAL client keeps a reference to the top-level HAL (the interface registered with `hwservicemanager`) only when it's in use. To avoid delays if this reference is dropped on a hwbinder thread that continues to execute, the client should also call `IPCThreadState::self()-\u003eflushCommands()` after dropping the reference to ensure that the binder driver is notified of the associated reference count changes."]]