Starting in Android 11, native AIDL services running in the system partition can be started and stopped dynamically as they are needed. Dynamic services start when they are first requested and automatically stop when they are no longer in use.
Services that can run dynamically
This feature is available only for native services whose lifecycles can be
servicemanager. Services within app packages are not
supported and should use bound services
Dynamic shutdown works by shutting down the process in which the service runs. If multiple services exist in the same process, all of them must be registered as dynamic to be compatible with this feature. That process will then shut down when all of the services are unused.
Configuring a service’s init .rc file
To run a service dynamically, add the following options to the service’s init
.rc file after the leading
service <name> <cmd> line.
interface aidl serviceName disabled oneshot
These options do the following:
interface aidl serviceName: Allows
servicemanagerto find the service. If the service uses multiple interfaces, declare each interface on its own line. These names must be exactly what
servicemanagerexpects and may differ from the process name.
disabled: Prevents the service from automatically starting at boot.
oneshot: Prevents the service from automatically restarting each time it is stopped.
For more information, see the Android Init Language Readme in AOSP.
Registering a service
Each service is created and registered with
servicemanager. Registration often
occurs in a file named
main.cpp, but the implementation can vary. The
registration usually looks something like this:
using android::defaultServiceManager; defaultServiceManager()->addService(serviceName, service);
Registration is sometimes abstracted by
BinderService::instantiate, which call the above code.
To register a service as dynamic, replace its registration code with the following:
#include <binder/LazyServiceRegistrar.h> using android::binder::LazyServiceRegistrar; auto lazyRegistrar = LazyServiceRegistrar::getInstance(); lazyRegistrar.registerService(service, serviceName);
servicemanager communicates with
LazyServiceRegistrar to shut down services
based on their reference counts.
Configuring AIDL service clients
Getting the service
To enable a client to retrieve a lazy service that may or may not be running,
replace calls to
checkService with calls to
waitForService blocks and waits indefinitely, so only call it on services that
actually exist. There is no VINTF manifest equivalent to verify whether an AIDL
service exists on a device.
In C++ this will look something like:
sp<IServiceManager> sm = android::defaultServiceManager(); // sp<IBinder> binder = sm->getService(String16("serviceName")); sp<IBinder> binder = sm->waitForService(String16("serviceName"));
In Java, this will look something like:
// IService.Stub.asInterface(ServiceManager.getService("serviceName")); IService.Stub.asInterface(ServiceManager.waitForService("serviceName"));
Releasing the service
Dynamic shutdown is based on reference counting, so clients must not hold onto the service when it is not in use.
Temporarily disabling shutdown
If you want a service to run independently until certain tasks are complete and
then switch to dynamic behavior, you can use
LazyServiceRegistrar::forcePersist to toggle dynamic shutdown on and off. If
this is called from the server side, it should be called before