Sensori Multi-HAL

Sensors Multi-HAL è un framework che consente agli HAL dei sensori di funzionare insieme ad altri HAL dei sensori. Il Sensors Multi-HAL carica dinamicamente i sub-HAL dei sensori archiviati come librerie dinamiche sulla partizione del fornitore e fornisce loro un oggetto di callback in grado di gestire la pubblicazione di eventi e l'acquisizione e il rilascio del wakelock. Un sub-HAL dei sensori è un HAL dei sensori integrato in un oggetto condiviso sulla partizione del fornitore e utilizzato dal framework multi-HAL. Questi sub-HAL non dipendono l'uno dall'altro o dal codice multi-HAL che contiene la funzione principale del processo.

Sensors Multi-HAL 2.1, disponibile su dispositivi con Android 11 o versioni successive, è un'iterazione di Sensors Multi-HAL 2.0 che supporta il caricamento di sub-HAL che possono esporre il tipo di sensore dell'angolo di cerniera . Per supportare questo tipo di sensore, i sub-HAL devono utilizzare le API sub-HAL definite nell'intestazione SubHal 2.1 .

Per i dispositivi con Android 13 o versioni successive che utilizzano Sensors AIDL HAL , puoi utilizzare il livello shim multi-HAL per consentire la funzionalità multi-HAL. Per i dettagli sull'implementazione, vedere Utilizzo del Multi-HAL dei sensori con l'HAL Sensors AIDL .

Differenza tra Sensori Multi-HAL 2 e Sensori HAL 2

Sensors Multi-HAL 2, disponibile sui dispositivi con Android 10 o versioni successive, introduce diverse astrazioni su Sensors HAL 2 per semplificare l'interazione con le API HAL. Sensors Multi-HAL 2 introduce la classe HalProxy per gestire l'implementazione dell'interfaccia Sensors HAL 2 e dell'interfaccia V2_1/SubHal (o V2_0/SubHal ) per consentire HalProxy di interagire con i sub-HAL.

L'interfaccia ISensorsSubHal è diversa dall'interfaccia 2.1/ISensors.hal (o 2.0/ISensors.hal ) nei seguenti modi:

  • Il metodo di inizializzazione passa una classe IHalProxyCallback invece di due FMQ e ISensorsCallback .
  • I sub-HAL devono implementare una funzione di debug per fornire informazioni di debug nelle segnalazioni di bug.
  • I sub-HAL devono implementare una funzione di nome in modo che il sub-HAL caricato possa essere distinto dagli altri sub-HAL.

La differenza principale tra Sensors Multi-HAL 2 e Sensors HAL 2 risiede nelle funzioni di inizializzazione. Invece di fornire FMQ, l'interfaccia IHalProxyCallback fornisce due metodi, un metodo per pubblicare eventi del sensore nel framework dei sensori e un metodo per creare wakelock. Sotto il cofano, Sensors Multi-HAL gestisce tutte le interazioni con gli FMQ per garantire la consegna tempestiva degli eventi dei sensori per tutti i sub-HAL. Si consiglia vivamente ai sub-HAL di utilizzare il metodo createScopedWakelock per delegare l'onere di scadere i wakelock al Sensors Multi-HAL e per centralizzare l'utilizzo del wakelock su un wakelock comune per l'intero Sensors Multi-HAL, riducendo al minimo il blocco e lo sblocco chiamate.

Sensors Multi-HAL 2 dispone anche di alcune funzionalità di sicurezza integrate. Gestisce le situazioni in cui il sensore FMQ è pieno o in cui il framework del sensore Android si riavvia e lo stato del sensore deve essere ripristinato. Inoltre, quando gli eventi vengono pubblicati nella classe HalProxy ma il framework del sensore non è in grado di accettarli immediatamente, Sensors Multi-HAL può spostare gli eventi in un thread in background per consentire il lavoro in tutti i sub-HAL in attesa degli eventi. da pubblicare.

Codice sorgente e implementazione di riferimento

Il codice Multi-HAL di tutti i sensori è disponibile in hardware/interfaces/sensors/common/default/2.X/multihal/ . Di seguito sono riportati i suggerimenti per alcune risorse.

  • HalProxy.h : l'oggetto HalProxy viene istanziato dal multi-HAL di Sensors e gestisce il passaggio dei dati dai sub-HAL al framework del sensore.
  • HalProxy.cpp : l'implementazione di HalProxy contiene tutta la logica necessaria per multiplexare la comunicazione tra sub-HAL e la struttura del sensore.
  • SubHal.h : l'interfaccia ISensorsSubHal definisce l'interfaccia che i sub-HAL devono seguire per essere compatibili con HalProxy . Il sub-HAL implementa il metodo di inizializzazione in modo che l'oggetto HalProxyCallback possa essere utilizzato per postEvents e createScopedWakelock .

    Per le implementazioni Multi-HAL 2.0, utilizzare la versione 2.0 di SubHal.h .

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/ : questi test unitari verificano l'implementazione HalProxy .

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ : questa implementazione sub-HAL di esempio utilizza sensori falsi per generare dati falsi. Utile per testare il modo in cui interagiscono più HAL secondari su un dispositivo.

Implementazione

Questa sezione descrive come implementare Sensors Multi-HAL nelle seguenti situazioni:

Utilizzare i sensori Multi-HAL con i sensori AIDL HAL

Per consentire la funzionalità multi-HAL con Sensors AIDL HAL, importare il modulo shim layer AIDL Multi-HAL, che si trova in hardware/interfaces/sensors/aidl/default/multihal/ . Il modulo gestisce la conversione tra i tipi di definizione HAL dei sensori AIDL e HIDL e definisce un wrapper attorno all'interfaccia multi-HAL descritta in Implementazione di Sensors Multi-HAL 2.1 . Il livello shim AIDL multi-HAL è compatibile con i dispositivi che implementano Sensors Multi-HAL 2.1.

Lo strato di spessore AIDL multi-HAL consente di esporre i tipi di sensori IMU ad asse limitato e head tracker nell'HAL Sensors AIDL. Per utilizzare questi tipi di sensore definiti dall'interfaccia AIDL HAL, impostare il campo type nella struttura SensorInfo nell'implementazione getSensorsList_2_1() . Ciò è sicuro perché i campi del tipo di sensore supportato da numeri interi dei sensori AIDL e HIDL HAL non si sovrappongono.

Implementare sensori Multi-HAL 2.1

Per implementare Sensors Multi-HAL 2.1 su un nuovo dispositivo, attenersi alla seguente procedura:

  1. Implementare l'interfaccia ISensorsSubHal come descritto in SubHal.h .
  2. Implementare il metodo sensorsHalGetSubHal_2_1 in SubHal.h .
  3. Aggiungi una destinazione cc_library_shared per creare il sub-HAL appena implementato. Quando aggiungi il target:

    1. Assicurati che la destinazione venga spostata da qualche parte nella partizione del fornitore del dispositivo.
    2. Nel file di configurazione situato in /vendor/etc/sensors/hals.conf , aggiungi il percorso della libreria su una nuova riga. Se necessario, creare il file hals.conf .

    Per un esempio di voce Android.bp per la creazione di una libreria sub-HAL, vedere hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp .

  4. Rimuovere tutte le voci android.hardware.sensors dal file manifest.xml , che contiene l'elenco degli HAL supportati sul dispositivo.

  5. Rimuovi tutti i file android.hardware.sensors service e service.rc dal file device.mk e aggiungi android.hardware.sensors@2.1-service.multihal e android.hardware.sensors@2.1-service.multihal.rc a PRODUCT_PACKAGES .

All'avvio, HalProxy si avvia, cerca il sub-HAL appena implementato e lo inizializza chiamando sensorsHalGetSubHal_2_1 .

Porta da Sensori Multi-HAL 2.0 a Multi-HAL 2.1

Per effettuare il porting da Multi-HAL 2.0 a Multi-HAL 2.1, implementa l'interfaccia SubHal e ricompila il tuo sub-HAL.

Queste sono le differenze tra le interfacce SubHal 2.0 e 2.1:

  • IHalProxyCallback utilizza i tipi creati nella versione 2.1 della specifica ISensors.hal .
  • La funzione initialize() passa un nuovo IHalProxyCallback invece di quello dell'interfaccia SubHal 2.0
  • I sub-HAL devono implementare getSensorsList_2_1 e injectSensorData_2_1 invece di getSensorsList e injectSensorData poiché questi metodi utilizzano i nuovi tipi aggiunti nella versione 2.1 della specifica ISensors.hal .
  • I sub-HAL devono esporre sensorsHalGetSubHal_2_1 anziché sensorsHalGetSubHal affinché il Multi-HAL li tratti come sub-HAL della versione 2.1.

Porta da Sensori HAL 2.0

Quando si esegue l'aggiornamento a Sensors Multi-HAL 2.0 da Sensors HAL 2.0 , assicurarsi che l'implementazione dell'HAL soddisfi i seguenti requisiti.

Inizializzare l'HAL

Sensori HAL 2.0 dispone di una funzione di inizializzazione che consente al servizio sensore di passare FMQ e una richiamata dinamica del sensore. In Sensors Multi-HAL 2.0, la funzione initialize() passa un singolo callback che deve essere utilizzato per pubblicare eventi del sensore, ottenere wakelock e notificare la connessione e la disconnessione dinamica del sensore.

Pubblica gli eventi del sensore nell'implementazione Multi-HAL

Invece di pubblicare gli eventi del sensore tramite FMQ, il sub-HAL deve scrivere gli eventi del sensore IHalProxyCallback quando gli eventi del sensore sono disponibili.

Eventi WAKE_UP

In Sensors HAL 2.0, l'HAL può gestire il wakelock per la sua implementazione. In Sensors Multi-HAL 2.0, i sub-HAL consentono all'implementazione Multi-HAL di gestire i wakelock e possono richiedere l'acquisizione di un wakelock richiamando createScopedWakelock . Un wakelock con ambito bloccato deve essere acquisito e passato a postEvents quando si pubblicano eventi di riattivazione nell'implementazione Multi-HAL.

Sensori dinamici

Sensors Multi-HAL 2.0 richiede che onDynamicSensorsConnected e onDynamicSensorsDisconnected in IHalProxyCallback vengano chiamati ogni volta che cambiano le connessioni dei sensori dinamici. Questi callback sono disponibili come parte del puntatore IHalProxyCallback fornito tramite la funzione initialize() .

Porta da Sensori HAL 1.0

Quando si esegue l'aggiornamento a Sensors Multi-HAL 2.0 da Sensors HAL 1.0 , assicurarsi che l'implementazione dell'HAL soddisfi i seguenti requisiti.

Inizializzare l'HAL

La funzione initialize() deve essere supportata per stabilire il callback tra il sub-HAL e l'implementazione Multi-HAL.

Esporre i sensori disponibili

In Sensors Multi-HAL 2.0, la funzione getSensorsList() deve restituire lo stesso valore durante l'avvio di un singolo dispositivo, anche tra i riavvii dell'HAL dei sensori. 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.

Pubblica gli eventi del sensore nell'implementazione Multi-HAL

In Sensors HAL 2.0, invece di attendere la chiamata poll() , il sub-HAL deve scrivere in modo proattivo gli eventi del sensore su IHalProxyCallback ogni volta che gli eventi del sensore sono disponibili.

Eventi WAKE_UP

In Sensors HAL 1.0, l'HAL può gestire il wakelock per la sua implementazione. In Sensors Multi-HAL 2.0, i sub-HAL consentono all'implementazione Multi-HAL di gestire i wakelock e possono richiedere l'acquisizione di un wakelock invocando createScopedWakelock . Un wakelock con ambito bloccato deve essere acquisito e passato a postEvents quando si pubblicano eventi di riattivazione nell'implementazione Multi-HAL.

Sensori dinamici

In Sensors HAL 1.0, i sensori dinamici vengono restituiti tramite la funzione poll() . Sensors Multi-HAL 2.0 richiede che onDynamicSensorsConnected e onDynamicSensorsDisconnected in IHalProxyCallback vengano chiamati ogni volta che cambiano le connessioni dei sensori dinamici. Questi callback sono disponibili come parte del puntatore IHalProxyCallback fornito tramite la funzione initialize() .

Porta da Sensors Multi-HAL 1.0

Per trasferire un'implementazione esistente da Sensors Multi-HAL 1.0 , attenersi alla seguente procedura.

  1. Assicurarsi che la configurazione dell'HAL dei sensori si trovi in /vendor/etc/sensors/hals.conf. Ciò potrebbe comportare lo spostamento del file situato in /system/etc/sensors/hals.conf .
  2. Rimuovere qualsiasi riferimento a hardware/hardware.h e hardware/sensors.h poiché non sono supportati per HAL 2.0.
  3. Trasferire sub-HAL come descritto in Porting da Sensors Hal 1.0 .
  4. Imposta Sensors Multi-HAL 2.0 come HAL designato seguendo i passaggi 3 e 4 nella sezione Implementazione Sensors Multi-HAL 2.0 .

Validazione

Esegui VTS

Dopo aver integrato uno o più sub-HAL con Sensors Multi-Hal 2.1, utilizza Vendor Test Suite (VTS) per garantire che le implementazioni sub-HAL soddisfino tutti i requisiti stabiliti dall'interfaccia Sensors HAL.

Per eseguire solo i test VTS dei sensori quando VTS è configurato su una macchina host, eseguire i seguenti comandi:

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_0Target && \
  vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_1Target

Se stai eseguendo il layer shim AIDL Multi-HAL, esegui VtsAidlHalSensorsTargetTest .

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

Esegui test unitari

Gli unit test in HalProxy_test.cpp testano HalProxy utilizzando falsi HAL secondari istanziati nello unit test e non caricati dinamicamente. Quando si crea un nuovo sub-HAL, questi test dovrebbero servire da guida su come aggiungere unit test che verifichino che il nuovo sub-HAL sia implementato correttamente.

Per eseguire i test, eseguire i seguenti comandi:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

Prova con i sub-HAL falsi

I falsi sub-HAL sono implementazioni fittizie dell'interfaccia ISensorsSubHal . I sub-HAL espongono diversi elenchi di sensori. Quando i sensori vengono attivati, pubblicano periodicamente eventi del sensore generati automaticamente su HalProxy in base agli intervalli specificati in una determinata richiesta del sensore.

I falsi sub-HAL possono essere utilizzati per testare il funzionamento del codice Multi-HAL completo con altri sub-HAL caricati nel sistema e per evidenziare vari aspetti del codice Sensors Multi-HAL.

Due falsi sub-HAL sono disponibili in hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ .

Per creare e inviare i falsi HAL secondari a un dispositivo, attenersi alla seguente procedura:

  1. Esegui i comandi seguenti per creare e inviare i tre diversi falsi HAL secondari al dispositivo:

    $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
    mma
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  2. Aggiorna la configurazione dell'HAL dei sensori su /vendor/etc/sensors/hals.conf con i percorsi per i falsi HAL secondari.

    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  3. Riavvia HalProxy e carica i nuovi sub-HAL elencati nel file config.

    adb shell stop
    adb shell start
    

Debug

Gli sviluppatori possono eseguire il debug del framework utilizzando il comando lshal . Per richiedere l'output di debug dell'HAL dei sensori, eseguire il comando seguente:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

Le informazioni sullo stato corrente di HalProxy e dei suoi sub-HAL vengono quindi inviate al terminale. Di seguito è riportato un esempio dell'output del comando per l'oggetto HalProxy e i falsi HAL secondari.

Internal values:
  Threads are running: true
  Wakelock timeout start time: 200 ms ago
  Wakelock timeout reset time: 73208 ms ago
  Wakelock ref count: 0
  # of events on pending write queue: 0
  # of non-dynamic sensors across all subhals: 8
  # of dynamic sensors across all subhals: 0
SubHals (2):
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2

Se il numero specificato per # of events on pending write queue è un numero elevato (1000 o più), ciò indica che ci sono molti eventi in sospeso da scrivere nel framework dei sensori. Ciò indica che il servizio del sensore è bloccato o si è bloccato e non sta elaborando gli eventi del sensore oppure che un batch di grandi dimensioni di eventi del sensore è stato recentemente pubblicato da un HAL secondario.

Se il conteggio dei riferimenti al wakelock è maggiore di 0 , significa che HalProxy ha acquisito un wakelock. Questo dovrebbe essere maggiore di 0 solo se uno ScopedWakelock viene trattenuto intenzionalmente o se gli eventi di riattivazione sono stati inviati a HalProxy e non sono stati elaborati dal framework del sensore.

Il descrittore di file passato al metodo di debug di HalProxy viene passato a ciascun sub-HAL, quindi gli sviluppatori devono implementare il metodo di debug come parte dell'interfaccia ISensorsSubHal .