La implementación del apagado dinámico implica conectar flujos de datos y ejecutar procesos dinámicos como se detalla en las siguientes secciones.
Cambios en las definiciones de HAL
El apagado dinámico requiere información sobre qué procesos sirven a qué interfaces HAL (esta información también puede ser útil más adelante en otros contextos), así como no iniciar procesos en el arranque y no reiniciarlos (hasta que se solicite nuevamente) cuando salen.
# 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
Cambios en init y hwservicemanager
El apagado dinámico también requiere que hwservicemanager
le indique init
que inicie los servicios solicitados. En Android 9, init
incluye tres mensajes de control adicionales (por ejemplo, ctl.start
): ctl.interface_start
, ctl.interface_stop
y ctl.interface_restart
. Estos mensajes se pueden utilizar para indicarle init
que active y desactive interfaces de hardware específicas. Cuando se solicita un servicio y no está registrado, hwservicemanager
solicita que se inicie el servicio. Sin embargo, los HAL dinámicos no requieren el uso de ninguno de estos.
Determinar la salida HAL
En Android 9, la salida de HAL debe determinarse manualmente. Para Android 10 y superiores, también se puede determinar con ciclos de vida automáticos .
El apagado dinámico requiere múltiples políticas para decidir cuándo iniciar una HAL y cuándo cerrarla. Si un HAL decide salir por cualquier motivo, se reiniciará automáticamente cuando sea necesario nuevamente utilizando la información proporcionada en la definición de HAL y la infraestructura proporcionada por los cambios en init
y hwservicemanager
. Esto podría implicar un par de estrategias diferentes, que incluyen:
- Un HAL podría optar por llamar a exit sobre sí mismo si alguien llama a una API cercana o similar. Este comportamiento debe especificarse en la interfaz HAL correspondiente.
- Los HAL pueden apagarse cuando se completa su tarea (documentado en el archivo HAL).
Ciclos de vida automáticos
Android 10 agrega más soporte al kernel y hwservicemanager
, lo que permite que los HAL se apaguen automáticamente cuando no tengan clientes. Para utilizar esta función, siga todos los pasos en Cambios en las definiciones de HAL , así como:
- Registre el servicio en C++ con
LazyServiceRegistrar
en lugar de la función miembro,registerAsService
, por ejemplo:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Verifique que el cliente HAL mantenga una referencia al HAL de nivel superior (la interfaz registrada con
hwservicemanager
) solo cuando esté en uso. Para evitar retrasos si esta referencia se elimina en un subproceso hwbinder que continúa ejecutándose, el cliente también debe llamar aIPCThreadState::self()->flushCommands()
después de eliminar la referencia para garantizar que se notifique al controlador de carpeta el recuento de referencias asociado. cambios.