Ejecutar servicios AIDL dinámicamente

A partir de Android 11, los servicios AIDL nativos que se ejecutan en la partición del sistema se pueden iniciar y detener dinámicamente según sea necesario. Los servicios dinámicos comienzan cuando se solicitan por primera vez y se detienen automáticamente cuando ya no están en uso.

Servicios que pueden ejecutarse dinámicamente

Esta característica está disponible solo para servicios nativos cuyos ciclos de vida pueden controlarse mediante init y servicemanager . Los servicios dentro de los paquetes de aplicaciones no son compatibles y en su lugar deben utilizar servicios vinculados .

El apagado dinámico funciona cerrando el proceso en el que se ejecuta el servicio. Si existen varios servicios en el mismo proceso, todos ellos deben estar registrados como dinámicos para que sean compatibles con esta característica. Ese proceso se cerrará cuando todos los servicios no se utilicen.

Configurar el archivo init .rc de un servicio

Para ejecutar un servicio dinámicamente, agregue las siguientes opciones al archivo init .rc del servicio después de la línea principal service <name> <cmd> .

interface aidl serviceName
disabled
oneshot

Estas opciones hacen lo siguiente:

  • interface aidl serviceName : permite servicemanager encontrar el servicio. Si el servicio utiliza varias interfaces, declare cada interfaz en su propia línea. Estos nombres deben ser exactamente los que espera servicemanager y pueden diferir del nombre del proceso.
  • disabled : evita que el servicio se inicie automáticamente en el inicio.
  • oneshot : evita que el servicio se reinicie automáticamente cada vez que se detiene.

Para obtener más información, consulte el archivo Léame del idioma de inicio de Android en AOSP.

Ejemplos:

Registrar un servicio

Cada servicio se crea y registra con servicemanager . El registro suele realizarse en un archivo denominado main.cpp , pero la implementación puede variar. El registro suele verse así:

using android::defaultServiceManager;

defaultServiceManager()->addService(serviceName, service);

A veces, BinderService::publish o BinderService::instantiate abstraen el registro, que llama al código anterior.

Para registrar un servicio como dinámico, reemplace su código de registro con lo siguiente:

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);

servicemanager se comunica con LazyServiceRegistrar para cerrar servicios según sus recuentos de referencias.

Ejemplos:

Configurar clientes del servicio AIDL

Obteniendo el servicio

Para recuperar un servicio diferido, se debe iniciar el servicio y luego recuperarlo. Llamar a getService en el administrador de servicios iniciará el servicio, pero generalmente desea obtener el servicio tan pronto como esté disponible y se deben usar las variantes waitForService . Consulte la documentación específica del backend sobre cómo utilizarlos.

Liberando el servicio

El cierre dinámico se basa en el recuento de referencias, por lo que los clientes no deben conservar el servicio cuando no esté en uso.

Ejemplos:

Desactivar temporalmente el apagado

Si desea que un servicio se ejecute de forma independiente hasta que se completen ciertas tareas y luego cambie al comportamiento dinámico, puede usar LazyServiceRegistrar::forcePersist para activar y desactivar el apagado dinámico. Si esto se llama desde el lado del servidor, se debe llamar antes registerService .

Ejemplo: servicio apex