L'Hardware Abstraction Layer (HAL) dei sensori è l'interfaccia tra il framework dei sensori Android e i sensori di un dispositivo, come un accelerometro o un giroscopio. L'HAL dei sensori definisce le funzioni che devono essere implementate per consentire al framework di controllare i sensori.
Sensors HAL 2.0 è disponibile in Android 10 e versioni successive per i dispositivi nuovi e aggiornati. Sensors HAL 2.0 è basato su Sensors HAL 1.0, ma presenta diverse differenze fondamentali, che ne impediscono la compatibilità con le versioni precedenti. Sensors HAL 2.0 utilizza Fast Message Queues (FMQ) per inviare eventi dei sensori da HAL al framework dei sensori Android.
Sensors HAL 2.1 è disponibile in Android 11 e versioni successive
per i dispositivi nuovi e aggiornati. Sensors HAL 2.1 è un'iterazione di Sensors HAL 2.0
che espone il
tipo di sensore HINGE_ANGLE e aggiorna vari metodi per accettare il tipo HINGE_ANGLE
.
Interfaccia HAL 2.1
La fonte principale di documentazione per Sensors HAL 2.1 si trova nella definizione HAL
in
hardware/interfaces/sensors/2.1/ISensors.hal.
In caso di conflitto tra i requisiti di questa pagina e quelli di ISensors.hal
,
utilizza i requisiti di ISensors.hal
.
Interfaccia HAL 2.0
La fonte principale di documentazione per Sensors HAL 2.0 si trova all'interno della definizione HAL all'indirizzo
hardware/interfaces/sensors/2.0/ISensors.hal.
In caso di conflitto tra i requisiti di questa pagina e quelli di ISensors.hal
,
utilizza i requisiti di ISensors.hal
.
Implementare Sensors HAL 2.0 e HAL 2.1
Per implementare Sensors HAL 2.0 o 2.1, un oggetto deve estendere l'interfaccia ISensors
e implementare tutte le funzioni definite in
2.0/ISensors.hal
o
2.1/ISensors.hal
.
Inizializza l'HAL
L'HAL dei sensori deve essere inizializzato dal framework dei sensori Android prima di poter essere utilizzato. Il framework chiama la funzione initialize()
per HAL 2.0 e la funzione initialize_2_1()
per HAL 2.1 per fornire tre parametri a Sensors HAL: due descrittori FMQ e un puntatore a un oggetto ISensorsCallback
.
L'HAL utilizza il primo descrittore per creare l'Event FMQ utilizzato per scrivere gli eventi del sensore nel framework. L'HAL utilizza il secondo descrittore per creare la FMQ Wake
Lock utilizzata per sincronizzare il momento in cui l'HAL rilascia il wake lock per gli eventi del sensore WAKE_UP
. L'HAL deve salvare un puntatore all'oggetto ISensorsCallback
in modo che
possano essere richiamate le funzioni di callback necessarie.
La funzione initialize()
o initialize_2_1()
deve essere la prima funzione
chiamata durante l'inizializzazione dell'HAL dei sensori.
Esporre i sensori disponibili
Per ottenere un elenco di tutti i sensori statici disponibili nel dispositivo, utilizza la funzione
getSensorsList()
su HAL 2.0 e la funzione getSensorsList_2_1()
su
HAL 2.1. Questa funzione restituisce un elenco di sensori, ognuno identificato in modo univoco dal
suo handle. L'handle di un determinato sensore non deve cambiare quando il processo
che ospita l'HAL dei sensori viene riavviato. Gli handle possono cambiare in seguito ai riavvii del dispositivo e
ai riavvii del server di sistema.
Se più sensori condividono lo stesso tipo di sensore e la stessa proprietà di riattivazione, il
primo sensore nell'elenco è chiamato sensore predefinito e viene restituito
alle app che utilizzano la funzione getDefaultSensor(int sensorType, bool wakeUp)
.
Stabilità dell'elenco dei sensori
Dopo il riavvio di Sensors HAL, se i dati restituiti da getSensorsList()
o
getSensorsList_2_1()
indicano una variazione significativa rispetto all'elenco dei sensori
recuperato prima del riavvio, il framework attiva un riavvio di
Android Runtime. Le modifiche significative all'elenco dei sensori includono i casi in cui un
sensore con un determinato handle è mancante o ha modificato gli attributi oppure in cui vengono introdotti nuovi
sensori. Sebbene il riavvio di Android Runtime sia un'operazione che disturba l'utente, è necessario perché il framework Android non può più rispettare il contratto API Android secondo cui i sensori statici (non dinamici) non cambiano durante il ciclo di vita di un'app. Ciò potrebbe anche impedire al framework di ristabilire le richieste di sensori attivi effettuate dalle app. Pertanto, ai fornitori HAL si consiglia di
evitare modifiche evitabili all'elenco dei sensori.
Per garantire la stabilità degli handle dei sensori, l'HAL deve mappare in modo deterministico un determinato sensore fisico nel dispositivo al suo handle. Sebbene l'interfaccia HAL dei sensori non imponga un'implementazione specifica, gli sviluppatori hanno a disposizione diverse opzioni per soddisfare questo requisito.
Ad esempio, l'elenco dei sensori può essere ordinato utilizzando una combinazione degli attributi fissi di ciascun sensore, come fornitore, modello e tipo di sensore. Un'altra opzione si basa
sul fatto che il set di sensori statici del dispositivo è fisso nell'hardware, quindi
l'HAL deve sapere quando tutti i sensori previsti hanno completato l'inizializzazione prima di
restituire un valore da getSensorsList()
o getSensorsList_2_1()
. Questo elenco di
sensori previsti può essere compilato nel binario HAL o archiviato in un
file di configurazione nel file system e l'ordine di visualizzazione può essere utilizzato
per derivare handle stabili. Sebbene la soluzione migliore dipenda dai dettagli di implementazione specifici dell'HAL, il requisito fondamentale è che gli handle dei sensori non cambino al riavvio dell'HAL.
Configurare i sensori
Prima di essere attivato, un sensore deve essere configurato con un periodo di campionamento e una latenza massima di reporting utilizzando la funzione batch()
.
Un sensore deve poter essere riconfigurato in qualsiasi momento utilizzando batch()
senza la
perdita di dati.
Periodo di campionamento
Il periodo di campionamento ha un significato diverso a seconda del tipo di sensore che viene configurato:
- Continuo: gli eventi del sensore vengono generati a una velocità continua.
- Al cambio: gli eventi vengono generati a una velocità non superiore al periodo di campionamento e potrebbero essere generati a una velocità inferiore al periodo di campionamento se il valore misurato non cambia.
- Una tantum: il periodo di campionamento viene ignorato.
- Speciale: per maggiori dettagli, vedi Tipi di sensori.
Per informazioni sull'interazione tra un periodo di campionamento e le modalità di report di un sensore, consulta Modalità di report.
Latenza massima del report
La latenza massima dei report imposta il tempo massimo in nanosecondi in cui gli eventi possono essere ritardati e archiviati nella FIFO hardware prima di essere scritti nell'FMQ eventi tramite l'HAL mentre il SoC è attivo.
Un valore pari a zero indica che gli eventi devono essere segnalati non appena vengono misurati, saltando del tutto la coda FIFO o svuotandola non appena un evento del sensore è presente nella coda FIFO.
Ad esempio, un accelerometro attivato a 50 Hz con una latenza massima di reporting di zero genera interruzioni 50 volte al secondo quando il SoC è attivo.
Quando la latenza massima di reporting è maggiore di zero, gli eventi del sensore non devono essere segnalati non appena vengono rilevati. Gli eventi possono essere memorizzati temporaneamente nella FIFO hardware e segnalati in batch, a condizione che nessun evento venga ritardato di più della latenza massima di reporting. Tutti gli eventi dal batch precedente vengono registrati e restituiti contemporaneamente. In questo modo si riduce il numero di interruzioni inviate al SoC e il SoC può passare a una modalità a basso consumo mentre il sensore acquisisce e raggruppa i dati.
A ogni evento è associato un timestamp. Il ritardo nell'ora in cui viene segnalato un evento non deve influire sul timestamp dell'evento. Il timestamp deve essere accurato e corrispondere all'ora in cui si è verificato fisicamente l'evento, non all'ora in cui è stato segnalato.
Per ulteriori informazioni e requisiti sulla segnalazione di eventi dei sensori con latenza di segnalazione massima diversa da zero, vedi Batching.
Attivare i sensori
Il framework attiva e disattiva i sensori utilizzando la funzione activate()
.
Prima di attivare un sensore, il framework deve prima configurarlo
utilizzando batch()
.
Dopo la disattivazione di un sensore, gli eventi aggiuntivi del sensore non devono essere scritti nella FMQ eventi.
Sensori per scarico
Se un sensore è configurato per raggruppare i dati, il framework può forzare
lo svuotamento immediato degli eventi del sensore raggruppati chiamando flush()
. In questo modo gli eventi dei sensori batch per l'handle del sensore specificato vengono scritti immediatamente nella FMQ eventi. L'HAL dei sensori deve aggiungere un evento di svuotamento completato
alla fine degli eventi del sensore scritti in seguito a una chiamata a
flush()
.
Lo svuotamento avviene in modo asincrono (ovvero, questa funzione deve restituire immediatamente). Se l'implementazione utilizza una singola coda FIFO per più sensori, questa viene svuotata e l'evento di completamento dello svuotamento viene aggiunto solo per il sensore specificato.
Se il sensore specificato non ha FIFO (nessun buffering possibile) o se il FIFO era
vuoto al momento della chiamata, flush()
deve comunque riuscire e inviare un evento di completamento
dello svuotamento per quel sensore. Questo vale per tutti i sensori diversi da quelli
one-shot.
Se flush()
viene chiamato per un sensore one-shot, flush()
deve restituire
BAD_VALUE
e non generare un evento di completamento dello scarico.
Scrivere eventi sensore nella FMQ
La coda di messaggi veloce per gli eventi viene utilizzata da Sensors HAL per inserire gli eventi dei sensori nel framework dei sensori Android.
La FMQ eventi è una FMQ sincronizzata, il che significa che qualsiasi tentativo di scrivere più eventi nella FMQ rispetto allo spazio disponibile comporta un errore di scrittura. In questo caso, l'HAL deve determinare se scrivere l'insieme corrente di eventi come due gruppi più piccoli di eventi o scrivere tutti gli eventi insieme quando è disponibile spazio sufficiente.
Quando l'HAL dei sensori ha scritto il numero desiderato di eventi del sensore
nella FMQ eventi, deve notificare al framework che gli eventi sono pronti
scrivendo il bit EventQueueFlagBits::READ_AND_PROCESS
nella funzione
EventFlag::wake
della FMQ eventi. EventFlag può essere creato da Event FMQ
utilizzando EventFlag::createEventFlag
e la funzione getEventFlagWord()
di Event FMQ.
Sensors HAL 2.0/2.1 supporta sia write
che writeBlocking
su Event FMQ.
L'implementazione predefinita fornisce un riferimento per l'utilizzo di write
. Se viene utilizzata la funzione
writeBlocking
, il flag readNotification
deve essere impostato su
EventQueueFlagBits::EVENTS_READ
, che viene impostato dal framework quando legge
gli eventi dalla FMQ eventi. Il flag di notifica di scrittura deve essere impostato su
EventQueueFlagBits::READ_AND_PROCESS
, che comunica al framework che gli eventi
sono stati scritti nella FMQ eventi.
Eventi WAKE_UP
Gli eventi WAKE_UP
sono eventi del sensore che causano l'attivazione del processore dell'applicazione (AP) e la gestione immediata dell'evento. Ogni volta che viene scritto un evento WAKE_UP
nella FMQ eventi, la HAL dei sensori deve acquisire un wake lock per garantire che il
sistema rimanga attivo finché il framework non è in grado di gestire l'evento. Al ricevimento di un
evento WAKE_UP
, il framework acquisisce il proprio wake lock, consentendo all'HAL dei sensori di rilasciare il proprio wake lock. Per sincronizzare il momento in cui l'HAL dei sensori
rilascia il wake lock, utilizza la FMQ wake lock.
L'HAL dei sensori deve leggere la FMQ di Wake Lock per determinare il numero di eventi WAKE_UP
gestiti dal framework. L'HAL deve rilasciare il wake lock
per gli eventi WAKE_UP
solo se il numero totale di eventi WAKE_UP
non gestiti è zero.
Dopo aver gestito gli eventi del sensore, il framework conta il numero di eventi
contrassegnati come eventi WAKE_UP
e scrive questo numero nel FMQ di Wake Lock.
Il framework imposta la notifica di scrittura WakeLockQueueFlagBits::DATA_WRITTEN
sulla FMQ di Wake Lock ogni volta che scrive dati nella FMQ di Wake Lock.
Sensori dinamici
I sensori dinamici non fanno fisicamente parte del dispositivo, ma possono essere utilizzati come input per il dispositivo, ad esempio un gamepad con un accelerometro.
Quando è collegato un sensore dinamico, la funzione onDynamicSensorConnected
in
ISensorsCallback
deve essere chiamata da Sensors HAL. In questo modo, il framework viene informato del nuovo sensore dinamico e consente di controllarlo tramite il framework e di far sì che gli eventi del sensore vengano utilizzati dai client.
Allo stesso modo, quando un sensore dinamico viene disconnesso, deve essere chiamata la funzione
onDynamicSensorDisconnected
in ISensorsCallback
in modo
che il framework possa rimuovere qualsiasi sensore non più disponibile.
Canale diretto
Il canale diretto è un metodo di funzionamento in cui gli eventi del sensore vengono scritti in
una memoria specifica anziché nella FMQ eventi, bypassando l'Android Sensors
Framework. Un client che registra un canale diretto deve leggere gli eventi del sensore
direttamente dalla memoria utilizzata per creare il canale diretto e non
riceverà gli eventi del sensore tramite il framework. La funzione configDirectReport()
è simile a batch()
per il normale funzionamento e configura il canale di report diretto.
Le funzioni registerDirectChannel()
e unregisterDirectChannel()
creano
o eliminano un nuovo canale diretto.
Modalità operative
La funzione setOperationMode()
consente al framework di configurare un sensore
in modo che possa inserire i dati del sensore nel sensore. Questo è utile per i test, soprattutto per gli algoritmi che esistono al di sotto del framework.
La funzione injectSensorData()
in HAL 2.0 e la funzione injectSensorsData_2_1()
in HAL 2.0 viene normalmente utilizzata per inserire parametri operativi in Sensors HAL. La funzione può essere utilizzata anche per inserire eventi del sensore in un
sensore specifico.
Convalida
Per convalidare l'implementazione dell'HAL dei sensori, esegui i test CTS e VTS dei sensori.
Test CTS
I test CTS dei sensori sono disponibili sia nei test CTS automatizzati sia nell'app CTS Verifier manuale.
I test automatici si trovano in cts/tests/sensor/src/android/hardware/cts. Questi test verificano la funzionalità standard dei sensori, ad esempio l'attivazione dei sensori, il batching e le frequenze degli eventi dei sensori.
I test CTS Verifier si trovano in cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Questi test richiedono l'inserimento manuale da parte dell'operatore del test e garantiscono che i sensori riportino valori accurati.
Il superamento dei test CTS è fondamentale per garantire che il dispositivo in esame soddisfi tutti i requisiti CDD.
Test VTS
I test VTS per Sensors HAL 2.0 si trovano in
hardware/interfaces/sensors/2.0/vts.
I test VTS per Sensors HAL 2.1 si trovano in
hardware/interfaces/sensors/2.1/vts.
Questi test assicurano che l'HAL dei sensori sia implementato correttamente e che tutti i requisiti all'interno di ISensors.hal
e ISensorsCallback.hal
siano soddisfatti correttamente.
Eseguire l'upgrade a Sensors HAL 2.1 dalla versione 2.0
Quando esegui l'upgrade a Sensors HAL 2.1 dalla versione 2.0, l'implementazione HAL deve includere i metodi initialize_2_1()
, getSensorsList_2_1()
e injectSensorsData_2_1()
, insieme ai tipi HAL 2.1. Questi metodi devono soddisfare gli stessi
requisiti descritti sopra per HAL 2.0.
Poiché gli HAL delle versioni secondarie devono supportare tutte le funzioni degli HAL precedenti, gli HAL 2.1 devono supportare l'inizializzazione come HAL 2.0. Per evitare la complessità di supportare entrambe le versioni HAL, è consigliabile utilizzare Multi-HAL 2.1.
Per un esempio di come implementare il tuo HAL Sensors 2.1, consulta Sensors.h.
Eseguire l'upgrade a Sensors HAL 2.0 dalla versione 1.0
Quando esegui l'upgrade a Sensors HAL 2.0 dalla versione 1.0, assicurati che l'implementazione di HAL soddisfi i seguenti requisiti.
Inizializza l'HAL
La funzione initialize()
deve essere supportata per stabilire FMQ tra il framework e HAL.
Esporre i sensori disponibili
In Sensors HAL 2.0, la funzione getSensorsList()
deve restituire lo stesso valore
durante un singolo avvio del dispositivo, anche in caso di riavvii di Sensors HAL. Un nuovo requisito
della funzione getSensorsList()
è che deve restituire lo stesso valore durante
un singolo avvio del dispositivo, anche in caso di riavvii di Sensors HAL. Ciò consente al
framework di tentare di ristabilire le connessioni dei sensori se il server di sistema
viene riavviato. Il valore restituito da getSensorsList()
può cambiare dopo il riavvio del dispositivo.
Scrivere eventi sensore nella FMQ
Anziché attendere la chiamata di poll()
, in Sensors HAL 2.0, Sensors
HAL deve scrivere in modo proattivo gli eventi del sensore nell'Event FMQ ogni volta che sono disponibili. L'HAL è anche responsabile della scrittura dei bit corretti in
EventFlag
per causare una lettura FMQ all'interno del framework.
Eventi WAKE_UP
In Sensors HAL 1.0, l'HAL era in grado di rilasciare il proprio wake lock per qualsiasi evento WAKE_UP
in qualsiasi chiamata successiva a poll()
dopo la pubblicazione di un WAKE_UP
in
poll()
perché ciò indicava che il framework aveva elaborato tutti gli eventi del sensore e aveva ottenuto un wake lock, se necessario. Poiché in Sensors HAL 2.0,
l'HAL non sa più quando il framework ha elaborato gli eventi scritti nella
FMQ, la FMQ Wake Lock consente al framework di comunicare all'HAL quando
ha gestito gli eventi WAKE_UP
.
In Sensors HAL 2.0, il wake lock protetto da Sensors HAL per gli eventi WAKE_UP
deve iniziare con SensorsHAL_WAKEUP
.
Sensori dinamici
I sensori dinamici sono stati restituiti utilizzando la funzione poll()
in Sensors HAL 1.0.
Sensors HAL 2.0 richiede che onDynamicSensorsConnected
e
onDynamicSensorsDisconnected
in ISensorsCallback
vengano chiamati ogni volta che cambiano le connessioni
dinamiche dei sensori. Questi callback sono disponibili come parte del
puntatore ISensorsCallback
fornito tramite la funzione initialize()
.
Modalità operative
La modalità DATA_INJECTION
per i sensori WAKE_UP
deve essere supportata in Sensors HAL
2.0.
Supporto di più HAL
Sensors HAL 2.0 e 2.1 supportano più HAL utilizzando il framework Sensors Multi-HAL. Per i dettagli di implementazione, vedi Porting da Sensors HAL 1.0.