L'implementazione dell'arresto dinamico prevede il collegamento dei flussi di dati e l'esecuzione di processi dinamici, come descritto nelle sezioni seguenti.
Modifiche alle definizioni HAL
L'arresto dinamico richiede informazioni su quali processi servono quali interfacce HAL (queste informazioni possono essere utili anche in un secondo momento in altri contesti), nonché di non avviare i processi all'avvio e di non riavviarli (fino a quando non vengono richiesti di nuovo) al termine.
# 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
Modifiche a init e hwservicemanager
L'arresto dinamico richiede inoltre che hwservicemanager
dica
init
di avviare i servizi richiesti. In Android 9,
init
include tre messaggi di controllo aggiuntivi (ad es.
ctl.start
): ctl.interface_start
,
ctl.interface_stop
e ctl.interface_restart
.
Questi messaggi possono essere utilizzati per segnalare a init
di attivare e disattivare specifiche interfacce hardware. Quando viene richiesto un servizio e non è registrato, hwservicemanager
richiede di avviarlo. Tuttavia, gli HAL dinamici non richiedono l'utilizzo di nessuno di questi elementi.
Determinare l'uscita HAL
In Android 9, l'uscita HAL deve essere determinata manualmente. Per Android 10 e versioni successive, può essere determinato anche con i cicli di vita automatici.
L'arresto dinamico richiede più criteri per decidere quando avviare un HAL e quando arrestarlo. Se un HAL decide di uscire per qualsiasi motivo, verrà riavviato automaticamente quando sarà di nuovo necessario utilizzando le informazioni fornite nella definizione HAL e l'infrastruttura fornita dalle modifiche a init
e hwservicemanager
. Potrebbero essere impiegate diverse strategie, tra cui:
- Un HAL potrebbe scegliere di chiamare exit su se stesso se qualcuno chiama un'API simile o chiusa. Questo comportamento deve essere specificato nell'interfaccia HAL corrispondente.
- Gli HAL possono arrestarsi al termine dell'attività (documentato nel file HAL).
Cicli di vita automatici
Android 10 aggiunge ulteriore supporto al kernel e
hwservicemanager
, che consente agli HAL di arrestarsi automaticamente
quando non hanno clienti. Per utilizzare questa funzionalità, svolgi tutti i passaggi descritti in Modifiche alle definizioni HAL, nonché:
- Registra il servizio in C++ con
LazyServiceRegistrar
anziché con la funzione membroregisterAsService
, ad esempio:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Verifica che il client HAL mantenga un riferimento all'HAL di primo livello (l'interfaccia registrata con
hwservicemanager
) solo quando è in uso. Per evitare ritardi se questo riferimento viene eliminato in un thread hwbinder che continua a essere eseguito, il client deve chiamare ancheIPCThreadState::self()->flushCommands()
dopo aver eliminato il riferimento per assicurarsi che al driver binder venga inviata una notifica delle modifiche associate al conteggio dei riferimenti.