L'implémentation d'un arrêt dynamique implique de connecter les flux de données et d'exécuter des processus dynamiques, comme indiqué dans les sections suivantes.
Modifications apportées aux définitions HAL
L'arrêt dynamique nécessite des informations sur les processus qui servent les interfaces HAL (ces informations peuvent également être utiles plus tard dans d'autres contextes), ainsi que de ne pas démarrer les processus au démarrage et de ne pas les redémarrer (jusqu'à ce qu'ils soient à nouveau demandés) lorsqu'ils se terminent.
# 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
Modifications apportées à init et hwservicemanager
L'arrêt dynamique nécessite également que hwservicemanager
indique à init
de démarrer les services demandés. Dans Android 9, init
inclut trois messages de contrôle supplémentaires (par exemple, ctl.start
): ctl.interface_start
, ctl.interface_stop
et ctl.interface_restart
.
Ces messages peuvent être utilisés pour indiquer à init
d'activer et de désactiver des interfaces matérielles spécifiques. Lorsqu'un service est demandé et qu'il n'est pas enregistré, hwservicemanager
demande que le service soit démarré. Toutefois, les HAL dynamiques ne nécessitent aucune de ces méthodes.
Déterminer la sortie de la HAL
Sous Android 9, la sortie HAL doit être déterminée manuellement. Pour Android 10 et versions ultérieures, cela peut également être déterminé avec des cycles de vie automatiques.
L'arrêt dynamique nécessite plusieurs règles pour décider quand démarrer un HAL et quand l'arrêter. Si un HAL décide de se fermer pour une raison quelconque, il sera automatiquement redémarré lorsqu'il sera à nouveau nécessaire à l'aide des informations fournies dans la définition du HAL et de l'infrastructure fournie par les modifications apportées à init
et hwservicemanager
. Vous pouvez utiliser plusieurs stratégies différentes, y compris les suivantes:
- Un HAL peut choisir d'appeler la sortie sur lui-même si quelqu'un appelle une API de fermeture ou similaire. Ce comportement doit être spécifié dans l'interface HAL correspondante.
- Les HAL peuvent s'arrêter une fois leur tâche terminée (documentée dans le fichier HAL).
Cycles de vie automatiques
Android 10 ajoute une compatibilité accrue au kernel et à hwservicemanager
, ce qui permet aux HAL de s'arrêter automatiquement lorsqu'ils n'ont pas de clients. Pour utiliser cette fonctionnalité, suivez toutes les étapes de la section Modifications apportées aux définitions HAL, ainsi que les étapes suivantes:
- Enregistrez le service en C++ avec
LazyServiceRegistrar
au lieu de la fonction membreregisterAsService
, par exemple:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Vérifiez que le client HAL ne conserve une référence au HAL de niveau supérieur (l'interface enregistrée avec
hwservicemanager
) que lorsqu'il est utilisé. Pour éviter les retards si cette référence est supprimée sur un thread hwbinder qui continue de s'exécuter, le client doit également appelerIPCThreadState::self()->flushCommands()
après avoir supprimé la référence pour s'assurer que le pilote du liaisonneur est informé des modifications du nombre de références associées.