Implementing dynamic shutdown involves wiring up data flows and executing dynamic processes as detailed in the following sections.
Changes to HAL definitions
Dynamic shutdown requires information on which processes serve what HAL interfaces (this information may also be useful later in other contexts) as well as not starting processes on boot and not restarting them (until requested again) when they exit.
# 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 firstname.lastname@example.org::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
Changes to init and hwservicemanager
Dynamic shutdown also requires the
hwservicemanager to tell
init to start requested services. In Android 9,
init includes three additional control messages (e.g.
These messages can be used to signal
init to bring up and down
specific hardware interfaces. When a service is requested and isn't
hwservicemanager requests that the service be
started. However, dynamic HALs don't require using any of these.
Determining HAL exit
In Android 9, HAL exit has to be manually determined. For Android 10 and higher, it can also be determined with automatic lifecycles.
Dynamic shutdown requires multiple policies for deciding when to start a
HAL and when to shutdown a HAL. If a HAL decides to exit for any reason, it
will automatically be restarted when it is needed again using the information
provided in the HAL definition and the infrastructure provided by changes to
hwservicemanager. This could involve a
couple of different strategies, including:
- 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.
- HALs can shut down when their task is completed (documented in the HAL file).
Android 10 adds more support to the kernel and
hwservicemanager, which allows HALs to shut down automatically
whenever they have no clients. To use this feature, do all of the steps in
Changes to HAL definitions as well
- Register the service in C++ with
LazyServiceRegistrarinstead of the member function,
registerAsService, for example:
// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- 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()->flushCommands()after dropping the reference to ensure that the binder driver is notified of the associated reference count changes.