L'implementazione dell'arresto dinamico implica il collegamento dei flussi di dati e l'esecuzione di processi dinamici come descritto in dettaglio nelle sezioni seguenti.
Modifiche alle definizioni HAL
L'arresto dinamico richiede informazioni su quali processi servono quali interfacce HAL (queste informazioni potrebbero anche essere utili in seguito in altri contesti) così come non avviare i processi all'avvio e non riavviarli (fino a quando non verranno nuovamente richiesti) alla chiusura.
# 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
indichi a init
di avviare i servizi richiesti. In Android 9, init
include tre messaggi di controllo aggiuntivi (ad esempio ctl.start
): ctl.interface_start
, ctl.interface_stop
e ctl.interface_restart
. Questi messaggi possono essere utilizzati per segnalare init
di attivare e disattivare specifiche interfacce hardware. Quando un servizio viene richiesto e non è registrato, hwservicemanager
richiede che il servizio venga avviato. Tuttavia, gli HAL dinamici non richiedono l'utilizzo di nessuno di questi.
Determinare l'uscita HAL
In Android 9, l'uscita HAL deve essere determinata manualmente. Per Android 10 e versioni successive è possibile determinarlo anche con cicli di vita automatici .
L'arresto dinamico richiede più policy per decidere quando avviare un HAL e quando arrestare un HAL. Se un HAL decide di uscire per qualsiasi motivo, verrà riavviato automaticamente quando sarà nuovamente necessario utilizzando le informazioni fornite nella definizione dell'HAL e l'infrastruttura fornita dalle modifiche a init
e hwservicemanager
. Ciò potrebbe comportare un paio di strategie diverse, tra cui:
- Un HAL può scegliere di chiamare exit su se stesso se qualcuno chiama su di esso un'API di chiusura o simile. Questo comportamento deve essere specificato nell'interfaccia HAL corrispondente.
- Gli HAL possono spegnersi una volta completata l'attività (documentata nel file HAL).
Cicli di vita automatici
Android 10 aggiunge ulteriore supporto al kernel e hwservicemanager
, che consente agli HAL di spegnersi automaticamente ogni volta che non hanno client. Per utilizzare questa funzionalità, eseguire tutti i passaggi descritti in Modifiche alle definizioni HAL nonché:
- Registra il servizio in C++ con
LazyServiceRegistrar
invece della funzione membro,registerAsService
, ad esempio:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Verificare che il client HAL mantenga un riferimento all'HAL di livello superiore (l'interfaccia registrata con
hwservicemanager
) solo quando è in uso. Per evitare ritardi se questo riferimento viene eliminato su un thread hwbinder che continua l'esecuzione, il client dovrebbe anche chiamareIPCThreadState::self()->flushCommands()
dopo aver eliminato il riferimento per garantire che il driver del raccoglitore venga informato del conteggio dei riferimenti associati i cambiamenti.