Exécution dynamique des services AIDL

À partir d'Android 11, les services AIDL natifs exécutés dans la partition système peuvent être démarrés et arrêtés dynamiquement selon leurs besoins. Les services dynamiques démarrent lorsqu'ils sont demandés pour la première fois et s'arrêtent automatiquement lorsqu'ils ne sont plus utilisés.

Services pouvant s'exécuter de manière dynamique

Cette fonctionnalité est disponible uniquement pour les services natifs dont les cycles de vie peuvent être contrôlés par init et servicemanager . Les services contenus dans les packages d'application ne sont pas pris en charge et doivent plutôt utiliser des services liés .

L'arrêt dynamique fonctionne en arrêtant le processus dans lequel le service s'exécute. Si plusieurs services existent dans le même processus, ils doivent tous être enregistrés comme dynamiques pour être compatibles avec cette fonctionnalité. Ce processus s'arrêtera ensuite lorsque tous les services seront inutilisés.

Configuration du fichier init .rc d'un service

Pour exécuter un service de manière dynamique, ajoutez les options suivantes au fichier init .rc du service après la première ligne service <name> <cmd> .

interface aidl serviceName
disabled
oneshot

Ces options effectuent les opérations suivantes :

  • interface aidl serviceName : Permet à servicemanager de trouver le service. Si le service utilise plusieurs interfaces, déclarez chaque interface sur sa propre ligne. Ces noms doivent correspondre exactement à ce que servicemanager attend et peuvent différer du nom du processus.
  • disabled : empêche le service de démarrer automatiquement au démarrage.
  • oneshot : Empêche le service de redémarrer automatiquement à chaque arrêt.

Pour plus d’informations, consultez le fichier Readme du langage d’initialisation Android dans AOSP.

Exemples:

Enregistrer un service

Chaque service est créé et enregistré auprès de servicemanager . L'enregistrement s'effectue souvent dans un fichier nommé main.cpp , mais l'implémentation peut varier. L'enregistrement ressemble généralement à ceci :

using android::defaultServiceManager;

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

L'enregistrement est parfois résumé par BinderService::publish ou BinderService::instantiate , qui appellent le code ci-dessus.

Pour enregistrer un service comme dynamique, remplacez son code d'enregistrement par ce qui suit :

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

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

servicemanager communique avec LazyServiceRegistrar pour arrêter les services en fonction de leur nombre de références.

Exemples:

Configuration des clients du service AIDL

Obtenir le service

Pour récupérer un service paresseux, le service doit être démarré puis récupéré. L'appel de getService sur le gestionnaire de services démarrera le service, mais généralement, vous souhaitez obtenir le service dès qu'il est disponible, et les variantes waitForService doivent être utilisées. Consultez la documentation spécifique au backend pour savoir comment les utiliser.

Libération du service

L'arrêt dynamique est basé sur le comptage de références, les clients ne doivent donc pas conserver le service lorsqu'il n'est pas utilisé.

Exemples:

Désactiver temporairement l'arrêt

Si vous souhaitez qu'un service s'exécute indépendamment jusqu'à ce que certaines tâches soient terminées, puis passe à un comportement dynamique, vous pouvez utiliser LazyServiceRegistrar::forcePersist pour activer et désactiver l'arrêt dynamique. Si ceci est appelé côté serveur, il doit être appelé avant registerService .

Exemple : serviceapex