HAL disponibles dynamiquement

Android 9 est compatible avec l'arrêt dynamique du matériel Android. des sous-systèmes lorsqu’ils ne sont pas utilisés ou qu’ils ne sont pas nécessaires. Par exemple, lorsqu'un utilisateur n'utilise pas le Wi-Fi, les sous-systèmes Wi-Fi ne doivent pas utiliser de mémoire, une alimentation ou d'autres ressources système. Dans les versions antérieures d'Android, les HAL/pilotes ont été laissés ouverts sur les appareils Android pendant toute la durée d'exécution a démarré.

L'implémentation d'un arrêt dynamique implique de connecter les flux de données et d'exécuter les processus dynamiques, comme expliqué dans les sections suivantes.

Modifications apportées aux définitions des HAL

L'arrêt dynamique nécessite des informations sur les processus qui diffusent ce HAL (ces informations peuvent également s'avérer utiles par la suite dans d'autres contextes), car de ne pas démarrer les processus au démarrage et de ne pas les redémarrer (tant que à la fermeture de l'application).

# 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 pour démarrer les services demandés. Sous 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'afficher ou de masquer des interfaces matérielles spécifiques. Lorsqu'un service est demandé et n'est pas enregistré, hwservicemanager demande que le service soit pour commencer. Cependant, les HAL dynamiques ne nécessitent aucune de ces méthodes.

Déterminer la sortie HAL

Sous Android 9, la sortie HAL doit être manuellement déterminé. Pour Android 10 ou version ultérieure, il peut également être déterminé avec cycles de vie automatiques.

L'arrêt dynamique nécessite l'application de plusieurs règles et quand arrêter un HAL. Si, pour une raison quelconque, une HAL se ferme, redémarre automatiquement lorsque vous en avez besoin à nouveau à l'aide des informations fournies dans la définition HAL et l'infrastructure fournie par les modifications init et hwservicemanager. Cela peut impliquer un deux stratégies différentes, y compris:

  • Un HAL peut choisir d'appeler la sortie automatiquement si quelqu'un appelle une fermeture ou avec une API similaire. Ce comportement doit être spécifié dans le HAL correspondant de commande.
  • Les HAL peuvent s'arrêter une fois leur tâche terminée (documentée dans le HAL). ).

Cycles de vie automatiques

Android 10 prend en charge le noyau et hwservicemanager, qui permet aux HAL de s'arrêter automatiquement chaque fois qu'ils n'ont aucun client. Pour utiliser cette fonctionnalité, suivez toutes les étapes de la Modifications apportées aux définitions des HAL en tant que:

  • Enregistrer le service en C++ avec LazyServiceRegistrar au lieu de la fonction membre, registerAsService, pour 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 premier niveau (le enregistrée auprès de hwservicemanager) uniquement lorsqu'elle est en cours d'utilisation. Pour éviter les retards si cette référence est supprimée sur un thread dehwbinder qui continue de s'exécuter, le client doit également appeler IPCThreadState::self()->flushCommands() après la suppression de la pour s'assurer que le conducteur de liaison est informé des du nombre de références.