Esegui i servizi AIDL in modo dinamico

In Android 11 e versioni successive, i servizi AIDL nativi in esecuzione nella partizione di sistema possono essere avviati e arrestati dinamicamente in base alle necessità. I servizi dinamici vengono avviati quando vengono richiesti per la prima volta e si interrompono automaticamente quando non sono più in uso.

Servizi che possono essere eseguiti in modo dinamico

Questa funzionalità è disponibile solo per i servizi nativi i cui cicli di vita possono essere controllati da init e servicemanager. I servizi all'interno dei pacchetti di app non sono supportati e devono utilizzare servizi associati.

L'arresto dinamico funziona arrestando il processo in cui viene eseguito il servizio. Se nello stesso processo esistono più servizi, tutti devono essere registrati come dinamici per essere compatibili con questa funzionalità. Il processo verrà arrestato quando tutti i servizi non vengono utilizzati.

Configura il file .rc init di un servizio

Per eseguire un servizio in modo dinamico, aggiungi le seguenti opzioni al file init .rc del servizio dopo la riga service <name> <cmd> iniziale.

interface aidl serviceName
disabled
oneshot

Queste opzioni svolgono le seguenti funzioni:

  • interface aidl serviceName: consente a servicemanager di trovare il servizio. Se il servizio utilizza più interfacce, dichiara ciascuna interfaccia su una riga separata. Questi nomi devono corrispondere esattamente a quelli previsti da servicemanager e potrebbero differire dal nome del processo.
  • disabled: impedisce l'avvio automatico del servizio all'avvio.
  • oneshot: impedisce il riavvio automatico del servizio ogni volta che viene interrotto.

Per saperne di più, consulta il file Readme di Android Init Language in AOSP.

Esempi:

Registrare un servizio

Ogni servizio viene creato e registrato con servicemanager. La registrazione spesso avviene in un file denominato main.cpp, ma l'implementazione può variare. La registrazione in genere è simile alla seguente:

using android::defaultServiceManager;

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

La registrazione a volte viene astratta da BinderService::publish o BinderService::instantiate, che chiamano il codice precedente.

Per registrare un servizio come dinamico, sostituisci il relativo codice di registrazione con il seguente:

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

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

servicemanager comunica con LazyServiceRegistrar per arrestare i servizi in base ai conteggi dei riferimenti.

Esempi:

Configura i client di servizio AIDL

Recuperare il servizio

Per recuperare un servizio lazy, il servizio deve essere avviato e poi recuperato. La chiamata di getService sul gestore del servizio avvierà il servizio, ma in genere vuoi ottenere il servizio non appena è disponibile e devono essere utilizzate le varianti di waitForService. Consulta la documentazione specifica per il backend su come utilizzarli.

Rilasciare il servizio

L'arresto dinamico si basa sul conteggio dei riferimenti, pertanto i client non devono mantenere il servizio quando non è in uso.

Esempi:

Disattivare temporaneamente l'arresto

Se vuoi che un servizio venga eseguito in modo indipendente fino al completamento di determinate attività e poi passi al comportamento dinamico, puoi utilizzare LazyServiceRegistrar::forcePersist per attivare e disattivare l'arresto dinamico. Se viene chiamato dal lato server, deve essere chiamato prima di registerService.

Esempio: apexservice