La mise en œuvre d'un arrêt dynamique implique le câblage des flux de données et l'exécution de processus dynamiques, comme détaillé dans les sections suivantes.
Modifications des définitions HAL
L'arrêt dynamique nécessite des informations sur les processus qui servent quelles interfaces HAL (ces informations peuvent également être utiles ultérieurement dans d'autres contextes), ainsi que le fait 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) à leur sortie.
# 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 signaler init
d'activer et de désactiver des interfaces matérielles spécifiques. Lorsqu'un service est demandé et n'est pas enregistré, hwservicemanager
demande que le service soit démarré. Cependant, les HAL dynamiques ne nécessitent l’utilisation d’aucun de ces éléments.
Déterminer la sortie de 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 politiques pour décider quand démarrer et arrêter une HAL. Si un HAL décide de se fermer pour une raison quelconque, il sera automatiquement redémarré lorsqu'il sera à nouveau nécessaire en utilisant les informations fournies dans la définition de HAL et l'infrastructure fournie par les modifications apportées à init
et hwservicemanager
. Cela pourrait impliquer plusieurs stratégies différentes, notamment :
- Un HAL peut choisir d'appeler exit sur lui-même si quelqu'un y appelle une API proche ou similaire. Ce comportement doit être spécifié dans l'interface HAL correspondante.
- Les HAL peuvent s'arrêter lorsque leur tâche est terminée (documentée dans le fichier HAL).
Cycles de vie automatiques
Android 10 ajoute davantage de prise en charge au noyau et hwservicemanager
, ce qui permet aux HAL de s'arrêter automatiquement lorsqu'ils n'ont aucun client. Pour utiliser cette fonctionnalité, effectuez toutes les étapes décrites dans Modifications des définitions HAL ainsi que :
- Enregistrez le service en C++ avec
LazyServiceRegistrar
au lieu de la fonction membre,registerAsService
, par exemple :// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Vérifiez que le client HAL conserve une référence au HAL de niveau supérieur (l'interface enregistrée avec
hwservicemanager
) uniquement 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 garantir que le pilote du classeur est informé du nombre de références associé. changements.