Sensori AIDL HAL

Il Sensors Hardware Abstraction Layer (HAL) è l'interfaccia tra il framework dei sensori Android e i sensori di un dispositivo, come un accelerometro o un giroscopio. L'HAL Sensori definisce le funzioni che devono essere implementate per consentire al framework di controllare i sensori.

Sensors AIDL HAL è disponibile in Android 13 e versioni successive per dispositivi nuovi e aggiornati. Sensors AIDL HAL, basato su Sensors HAL 2.1 , utilizza l' interfaccia AIDL HAL ed espone i tipi di sensore head tracker e IMU ad asse limitato.

Interfaccia HAL AIDL

La principale fonte di documentazione per Sensors AIDL HAL è all'interno della definizione HAL in hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .

Implementare i sensori AIDL HAL

Per implementare Sensors AIDL HAL, un oggetto deve estendere l'interfaccia ISensors e implementare tutte le funzioni definite in hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .

Inizializzare 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 fornire tre parametri all'HAL Sensors: 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 il Wake Lock FMQ utilizzato per la sincronizzazione quando l'HAL rilascia il proprio wakelock per gli eventi del sensore WAKE_UP . L'HAL deve salvare un puntatore all'oggetto ISensorsCallback in modo che qualsiasi funzione di callback necessaria possa essere richiamata.

La funzione initialize() 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, utilizzare la funzione getSensorsList() . Questa funzione restituisce un elenco di sensori, ciascuno identificato in modo univoco dal relativo handle. L'handle per un determinato sensore non deve cambiare al riavvio del processo che ospita l'HAL dei sensori. Gli handle potrebbero cambiare tra i riavvii del dispositivo e tra i riavvii del server di sistema.

Se più sensori condividono lo stesso tipo di sensore e proprietà di attivazione, il primo sensore nell'elenco viene 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 dell'HAL dei sensori, se i dati restituiti da getSensorsList() indicano una modifica significativa rispetto all'elenco dei sensori recuperato prima del riavvio, il framework attiva un riavvio del runtime Android. Modifiche significative all'elenco dei sensori includono i casi in cui un sensore con una determinata maniglia manca o ha modificato gli attributi o in cui vengono introdotti nuovi sensori. Sebbene il riavvio del runtime Android comporti interruzioni per l'utente, è necessario perché il framework Android non è più in grado di soddisfare il contratto API Android secondo cui i sensori statici (non dinamici) non cambiano durante la durata di un'app. Ciò potrebbe anche impedire al framework di ristabilire le richieste di sensori attive effettuate dalle app. Pertanto, si consiglia ai fornitori di HAL 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 sul relativo handle. Sebbene nessuna implementazione specifica sia richiesta dall'interfaccia Sensors HAL, gli sviluppatori hanno a disposizione una serie di 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 ritornare da getSensorsList() . Questo elenco di sensori attesi può essere compilato nel binario HAL o archiviato in un file di configurazione nel file system e l'ordine di apparizione 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 tra i riavvii dell'HAL.

Configurare i sensori

Prima che un sensore venga attivato, il sensore deve essere configurato con un periodo di campionamento e una latenza di reporting massima utilizzando la funzione batch() .

Un sensore deve poter essere riconfigurato in qualsiasi momento utilizzando batch() senza perdita dei dati del sensore.

Periodo di campionamento

Il periodo di campionamento ha un significato diverso in base al tipo di sensore che si sta configurando:

  • Continuo: gli eventi del sensore vengono generati a ritmo continuo.
  • In variazione: gli eventi non vengono generati più velocemente del periodo di campionamento e possono essere generati a una velocità inferiore rispetto al periodo di campionamento se il valore misurato non cambia.
  • One-shot: il periodo di campionamento viene ignorato.
  • Speciale: per maggiori dettagli, vedere Tipi di sensori .

Per ulteriori informazioni sull'interazione tra un periodo di campionamento e le modalità di reporting di un sensore, vedere Modalità di reporting .

Latenza massima dei rapporti

La latenza massima di reporting imposta il tempo massimo in nanosecondi durante il quale gli eventi possono essere ritardati e archiviati nel FIFO hardware prima di essere scritti nell'Event FMQ tramite l'HAL mentre il SoC è attivo.

Un valore pari a zero significa che gli eventi devono essere segnalati non appena vengono misurati, saltando del tutto la FIFO o svuotando la FIFO non appena un evento dal sensore è presente nella FIFO.

Ad esempio, un accelerometro attivato a 50 Hz con una latenza di reporting massima pari a zero si attiva 50 volte al secondo quando il SoC è attivo.

Quando la latenza massima di reporting è maggiore di zero, non è necessario segnalare gli eventi del sensore non appena vengono rilevati. Gli eventi possono essere temporaneamente archiviati nel FIFO hardware e riportati in batch, a condizione che nessun evento venga ritardato oltre la latenza massima di reporting. Tutti gli eventi successivi al batch precedente vengono registrati e restituiti contemporaneamente. Ciò riduce il numero di interruzioni inviate al SoC e consente al SoC di passare a una modalità di consumo inferiore mentre il sensore acquisisce e raggruppa i dati.

Ad ogni evento è associato un timestamp. Il ritardo nell'orario in cui viene segnalato un evento non deve influire sul timestamp dell'evento. La marcatura temporale deve essere precisa e corrispondere all'ora in cui l'evento si è verificato fisicamente e non all'ora in cui è stato segnalato.

Per ulteriori informazioni e requisiti sulla segnalazione degli eventi dei sensori con latenza di segnalazione massima diversa da zero, vedere Batch .

Attiva i sensori

Il framework abilita e disabilita i sensori utilizzando la activate() . Prima di attivare un sensore, il framework deve prima configurare il sensore utilizzando batch() .

Dopo che un sensore è stato disattivato, ulteriori eventi del sensore da quel sensore non devono essere scritti nell'Event FMQ.

Sensori a filo

Se un sensore è configurato per raggruppare i dati del sensore, il framework può forzare uno svuotamento immediato degli eventi del sensore raggruppati chiamando flush() . Ciò fa sì che gli eventi del sensore raggruppati per l'handle del sensore specificato vengano immediatamente scritti nell'FMQ eventi. L'HAL dei sensori deve aggiungere un evento flush complete alla fine degli eventi del sensore scritti come risultato di una chiamata a flush() .

Lo svuotamento avviene in modo asincrono (ovvero, questa funzione deve restituire immediatamente). Se l'implementazione utilizza un singolo FIFO per più sensori, tale FIFO viene svuotato e l'evento di svuotamento completato 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 avere esito positivo e inviare un evento flush complete per quel sensore. Questo vale per tutti i sensori diversi dai sensori one-shot.

Se flush() viene chiamato per un sensore one-shot, flush() deve restituire BAD_VALUE e non generare un evento flush() completo.

Scrivere gli eventi del sensore nell'FMQ

L'Event FMQ viene utilizzato dall'HAL Sensors per inserire gli eventi dei sensori nel framework dei sensori Android.

L'FMQ eventi è un FMQ sincronizzato, il che significa che qualsiasi tentativo di scrivere sull'FMQ un numero di eventi superiore a quello consentito dallo spazio disponibile, avrà come risultato una scrittura non riuscita. In tal caso, l'HAL dovrebbe determinare se scrivere la serie corrente di eventi come due gruppi di eventi più piccoli o scrivere tutti gli eventi insieme quando è disponibile spazio sufficiente.

Quando l'HAL dei sensori ha scritto il numero desiderato di eventi del sensore nell'Event FMQ, l'HAL dei sensori deve notificare al framework che gli eventi sono pronti scrivendo il bit EventQueueFlagBits::READ_AND_PROCESS nella funzione EventFlag::wake dell'Event FMQ. L'EventFlag può essere creato dall'Event FMQ utilizzando EventFlag::createEventFlag e la funzione getEventFlagWord() dell'Event FMQ.

L'HAL Sensors AIDL supporta sia il blocco write che writeBlocking sull'Event FMQ. L'implementazione predefinita fornisce un riferimento per l'utilizzo 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 dall'Event FMQ. Il flag di notifica di scrittura deve essere impostato su EventQueueFlagBits::READ_AND_PROCESS , che notifica al framework che gli eventi sono stati scritti nell'Event FMQ.

Eventi WAKE_UP

Gli eventi WAKE_UP sono eventi del sensore che provocano la riattivazione del processore dell'applicazione (AP) e la gestione immediata dell'evento. Ogni volta che un evento WAKE_UP viene scritto nell'Event FMQ, l'HAL dei sensori deve proteggere un wakelock per garantire che il sistema rimanga attivo finché il framework non è in grado di gestire l'evento. Dopo aver ricevuto un evento WAKE_UP , il framework protegge il proprio wakelock, consentendo all'HAL dei sensori di rilasciare il proprio wakelock. Per eseguire la sincronizzazione quando l'HAL dei sensori rilascia il wakelock, utilizzare Wake Lock FMQ.

L'HAL dei sensori deve leggere il Wake Lock FMQ per determinare il numero di eventi WAKE_UP gestiti dal framework. L'HAL dovrebbe rilasciare il proprio wakelock 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 riscrive questo numero nel Wake Lock FMQ.

Il framework imposta la notifica di scrittura WakeLockQueueFlagBits::DATA_WRITTEN su Wake Lock FMQ ogni volta che scrive dati su Wake Lock FMQ.

Sensori dinamici

I sensori dinamici sono sensori che 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 dall'HAL Sensors. Ciò notifica il framework del nuovo sensore dinamico e consente al sensore di essere controllato attraverso il framework e di far sì che gli eventi del sensore vengano consumati dai client.

Allo stesso modo, quando un sensore dinamico viene disconnesso, è necessario chiamare 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 dei sensori vengono scritti in una memoria specifica anziché nell'Event FMQ ignorando 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 attraverso il framework. La funzione configDirectReport() è simile a batch() per il normale funzionamento e configura il canale del rapporto diretto.

Le funzioni registerDirectChannel() e unregisterDirectChannel() creano o distruggono un nuovo canale diretto.

Modalità operative

La funzione setOperationMode() consente al framework di configurare un sensore in modo che il framework possa inserire i dati del sensore nel sensore. Ciò è utile per i test, soprattutto per gli algoritmi che esistono al di sotto del framework.

La funzione injectSensorData() viene normalmente utilizzata per inserire parametri operativi nell'HAL dei sensori. La funzione può essere utilizzata anche per inserire eventi del sensore in un sensore specifico.

Validazione

Per convalidare l'implementazione dell'HAL dei sensori, eseguire i test CTS e VTS dei sensori.

Prove CTS

I test CTS del sensore esistono sia nei test CTS automatizzati che nell'app CTS Verifier manuale.

I test automatizzati si trovano in cts/tests/sensor/src/android/hardware/cts . Questi test verificano la funzionalità standard dei sensori, come l'attivazione dei sensori, il batching e la frequenza degli eventi dei sensori.

I test CTS Verifier si trovano in cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . Questi test richiedono un input 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 sottoposto a test soddisfi tutti i requisiti CDD.

Prove VTS

I test VTS per i sensori AIDL HAL si trovano in hardware/interfaces/sensors/aidl/vts/ . Questi test garantiscono che Sensors HAL sia implementato correttamente e che tutti i requisiti all'interno di ISensors.aidl e ISensorsCallback.aidl siano adeguatamente soddisfatti.

Inizializzare l'HAL

La funzione initialize() deve essere supportata per stabilire FMQ tra il framework e HAL.

Esporre i sensori disponibili

Nell'HAL Sensors AIDL, la funzione getSensorsList() deve restituire lo stesso valore durante l'avvio di un singolo dispositivo, anche tra i riavvii dell'HAL Sensors. Un nuovo requisito della funzione getSensorsList() è che deve restituire lo stesso valore durante l'avvio di un singolo dispositivo, anche tra i riavvii dell'HAL di Sensors. Ciò consente al framework di tentare di ristabilire le connessioni dei sensori se il server di sistema si riavvia. Il valore restituito da getSensorsList() può cambiare dopo che il dispositivo ha eseguito un riavvio.

Scrivere gli eventi del sensore nell'FMQ

Invece di attendere la chiamata di poll() , nell'HAL Sensors AIDL, l'HAL Sensors deve scrivere in modo proattivo gli eventi del sensore nell'Event FMQ ogni volta che gli eventi del sensore sono disponibili. L'HAL è anche responsabile della scrittura dei bit corretti su EventFlag per provocare una lettura FMQ all'interno del framework.

Eventi WAKE_UP

In Sensors HAL 1.0, l'HAL era in grado di rilasciare il proprio wakelock per qualsiasi evento WAKE_UP su qualsiasi chiamata successiva a poll() dopo che un WAKE_UP era stato inviato a poll() perché ciò indicava che il framework aveva elaborato tutti gli eventi del sensore e aveva ottenuto un wakelock, se necessario. Poiché, nell'HAL Sensors AIDL, l'HAL non riceve più una notifica quando il framework ha elaborato eventi scritti nell'FMQ, Wake Lock FMQ consente al framework di comunicare con l'HAL quando ha gestito gli eventi WAKE_UP .

Nell'HAL Sensors AIDL, il wakelock protetto dall'HAL Sensors 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. L'HAL Sensors AIDL richiede che onDynamicSensorsConnected e onDynamicSensorsDisconnected in ISensorsCallback vengano chiamati ogni volta che cambiano le connessioni del sensore dinamico. 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.

Supporto multiHAL

L'HAL Sensors AIDL supporta il multi-HAL utilizzando il framework Sensors Multi-HAL . Per i dettagli sull'implementazione, vedere porting da Sensors HAL 2.1 .