Multi-HAL per i sensori

Sensors Multi-HAL è un framework che consente alle HAL dei sensori di essere eseguite insieme ad altre HAL dei sensori. Sensors Multi-HAL carica dinamicamente le sotto-HAL dei sensori archiviate come librerie dinamiche nella partizione del fornitore e fornisce loro un oggetto di callback in grado di gestire la pubblicazione degli eventi e l'acquisizione e il rilascio del wakelock. Una sotto-HAL dei sensori è una HAL dei sensori integrata in un oggetto condiviso nella partizione del fornitore e utilizzata dal framework multi-HAL. Queste sotto-HAL non dipendono l'una dall'altra o dal codice multi-HAL che contiene la funzione principale per il processo.

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

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

Differenza tra Sensors Multi-HAL 2 e Sensors HAL 2

Sensors Multi-HAL 2, disponibile sui dispositivi con Android 10 o versioni successive, introduce diverse astrazioni sopra 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 l'interfaccia V2_1/SubHal (o V2_0/SubHal) per consentire a HalProxy di interagire con le sotto-HAL.

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

  • Il metodo di inizializzazione passa una classe IHalProxyCallback anziché due FMQ e ISensorsCallback.
  • Le sotto-HAL devono implementare una funzione di debug per fornire informazioni di debug nei report sui bug.
  • Le sotto-HAL devono implementare una funzione di denominazione in modo che la sotto-HAL caricata possa essere distinta dalle altre sotto-HAL.

La differenza principale tra Sensors Multi-HAL 2 e Sensors HAL 2 risiede nelle funzioni di inizializzazione. Anziché fornire FMQ, l'interfaccia IHalProxyCallback fornisce due metodi: un metodo per pubblicare gli eventi dei sensori nel framework dei sensori e un metodo per creare blocchi di riattivazione. Dietro le quinte, Sensors Multi-HAL gestisce tutte le interazioni con le FMQ per garantire la consegna tempestiva degli eventi dei sensori per tutte le sotto-HAL. È vivamente consigliato che le sotto-HAL utilizzino il metodo createScopedWakelock per delegare l'onere di timeout dei wakelock a Sensors Multi-HAL e per centralizzare l'utilizzo dei wakelock in un wakelock comune per l'intero Sensors Multi-HAL, il che riduce al minimo le chiamate di blocco e sblocco.

Sensors Multi-HAL 2 ha anche alcune funzionalità di sicurezza integrate. Gestisce le situazioni in cui la FMQ del sensore è piena o in cui il framework dei sensori Android viene riavviato e lo stato del sensore deve essere reimpostato. Inoltre, quando gli eventi vengono pubblicati nella classe HalProxy, ma il framework dei sensori non è in grado di accettarli immediatamente, Sensors Multi-HAL può spostare gli eventi in un thread in background per consentire la continuazione del lavoro su tutte le sotto-HAL durante l'attesa della pubblicazione degli eventi.

Codice sorgente e implementazione di riferimento

Tutto il codice di Sensors Multi-HAL è disponibile in hardware/interfaces/sensors/common/default/2.X/multihal/. Ecco alcuni puntatori alle risorse.

  • HalProxy.h: L'oggetto HalProxy viene istanziato da Sensors Multi-HAL e gestisce il passaggio dei dati dalle sotto-HAL al framework dei sensori.
  • HalProxy.cpp: L'implementazione di HalProxy contiene tutta la logica necessaria per multiplexare la comunicazione tra le sotto-HAL e il framework dei sensori.
  • SubHal.h: l'interfaccia ISensorsSubHal definisce l'interfaccia che le sotto-HAL devono seguire per essere compatibili con HalProxy. La sotto-HAL implementa il metodo di inizializzazione in modo che l'oggetto HalProxyCallback possa essere utilizzato per postEvents e createScopedWakelock.

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

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

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: questa implementazione di sotto-HAL di esempio utilizza sensori fittizi per generare dati fittizi. Utile per testare l'interazione di più sotto-HAL su un dispositivo.

Implementazione

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

Utilizzare Sensors Multi-HAL con la HAL dei sensori AIDL

Per consentire la funzionalità multi-HAL con la HAL dei sensori AIDL, importa il modulo del livello di shim multi-HAL AIDL, 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 di shim multi-HAL AIDL è compatibile con i dispositivi che implementano Sensors Multi-HAL 2.1.

Il livello di shim multi-HAL AIDL consente di esporre i tipi di sensori del rilevatore della testa e dell'IMU ad asse limitato nella HAL dei sensori AIDL. Per utilizzare questi tipi di sensori definiti dall'interfaccia HAL AIDL, imposta il campo type nella struct SensorInfo nell'implementazione di getSensorsList_2_1(). Questa operazione è sicura perché i campi dei tipi di sensori basati su numeri interi delle HAL dei sensori AIDL e HIDL non si sovrappongono.

Implementare Sensors Multi-HAL 2.1

Per implementare Sensors Multi-HAL 2.1 su un nuovo dispositivo:

  1. Implementa l'interfaccia ISensorsSubHal come descritto in SubHal.h.
  2. Implementa il sensorsHalGetSubHal_2_1 metodo in SubHal.h.
  3. Aggiungi un target cc_library_shared per creare la sotto-HAL appena implementata. Quando aggiungi il target:

    1. Assicurati che il target venga eseguito il push in un punto qualsiasi della partizione del fornitore del dispositivo.
    2. Nel file di configurazione che si trova in /vendor/etc/sensors/hals.conf, aggiungi il percorso alla libreria su una nuova riga. Se necessario, crea il file hals.conf.

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

  4. Rimuovi tutte le voci android.hardware.sensors dal manifest.xml file, che contiene l'elenco delle HAL supportate sul dispositivo.

  5. Rimuovi tutti i file di servizio android.hardware.sensors e service.rc da l 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 la sotto-HAL appena implementata e la inizializza chiamando sensorsHalGetSubHal_2_1.

Eseguire il porting da Sensors Multi-HAL 2.0 a Multi-HAL 2.1

Per eseguire il porting da Multi-HAL 2.0 a Multi-HAL 2.1, implementa l' SubHal interfaccia e ricompila la sotto-HAL.

Di seguito sono riportate 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 anziché quello dell'interfaccia SubHal 2.0.
  • Le sotto-HAL devono implementare getSensorsList_2_1 e injectSensorData_2_1 anziché getSensorsList e injectSensorData, poiché questi metodi utilizzano i nuovi tipi aggiunti nella versione 2.1 della specifica ISensors.hal.
  • Le sotto-HAL devono esporre sensorsHalGetSubHal_2_1 anziché sensorsHalGetSubHal affinché Multi-HAL le tratti come sotto-HAL della versione 2.1.

Eseguire il porting da Sensors HAL 2.0

Quando esegui l'upgrade a Sensors Multi-HAL 2.0 da Sensors HAL 2.0, assicurati che l'implementazione HAL soddisfi i seguenti requisiti.

Inizializzare la HAL

Sensors HAL 2.0 ha una funzione di inizializzazione che consente al servizio dei sensori di passare FMQ e un callback dinamico dei sensori. In Sensors Multi-HAL 2.0, la funzione initialize() passa un singolo callback che deve essere utilizzato per pubblicare gli eventi dei sensori, ottenere blocchi di riattivazione e notificare la connessione e la disconnessione dei sensori dinamici.

Pubblicare gli eventi dei sensori nell'implementazione Multi-HAL

Anziché pubblicare gli eventi dei sensori tramite la FMQ, la sotto-HAL deve scrivere gli eventi dei sensori in IHalProxyCallback quando sono disponibili.

Eventi WAKE_UP

In Sensors HAL 2.0, la HAL può gestire il wakelock per la sua implementazione. In Sensors Multi-HAL 2.0, le sotto-HAL consentono all'implementazione Multi-HAL di gestire i wakelock e possono richiedere l'acquisizione di un wakelock richiamando createScopedWakelock. Quando pubblichi eventi di riattivazione nell'implementazione Multi-HAL, devi acquisire e passare a postEvents un wakelock con ambito bloccato.

Sensori dinamici

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

Eseguire il porting da Sensors HAL 1.0

Quando esegui l'upgrade a Sensors Multi-HAL 2.0 da Sensors HAL 1.0, assicurati che l'implementazione HAL soddisfi i seguenti requisiti.

Inizializzare la HAL

La funzione initialize() deve essere supportata per stabilire il callback tra la sotto-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 un singolo avvio del dispositivo, anche in caso di riavvio della HAL dei sensori. In questo modo, il framework può 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.

Pubblicare gli eventi dei sensori nell'implementazione Multi-HAL

In Sensors HAL 2.0, anziché attendere poll()la chiamata di, la sotto-HAL deve scrivere in modo proattivo gli eventi dei sensori in IHalProxyCallback ogni volta che sono disponibili.

Eventi WAKE_UP

In Sensors HAL 1.0, la HAL può gestire il wakelock per la sua implementazione. In Sensors Multi-HAL 2.0, le sotto-HAL consentono all'implementazione Multi-HAL di gestire i wakelock e possono richiedere l'acquisizione di un wakelock richiamando createScopedWakelock. Quando pubblichi eventi di riattivazione nell'implementazione Multi-HAL, devi acquisire e passare a postEvents un wakelock con ambito bloccato.

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 vengano chiamati ogni volta che le connessioni dei sensori dinamici cambiano.IHalProxyCallback Questi callback sono disponibili come parte del puntatore IHalProxyCallback fornito tramite la funzione initialize().

Eseguire il porting da Sensors Multi-HAL 1.0

Per eseguire il porting di un'implementazione esistente da Sensors Multi-HAL 1.0, procedi nel seguente modo.

  1. Assicurati che la configurazione HAL dei sensori si trovi in /vendor/etc/sensors/hals.conf. Potrebbe essere necessario spostare il file che si trova in /system/etc/sensors/hals.conf.
  2. Rimuovi tutti i riferimenti a hardware/hardware.h e hardware/sensors.h , poiché non sono supportati per HAL 2.0.
  3. Esegui il porting delle sotto-HAL come descritto in Eseguire il porting da Sensors HAL 1.0.
  4. Imposta Sensors Multi-HAL 2.0 come HAL designata seguendo i passaggi 3 e 4 della sezione Implementare Sensors Multi-HAL 2.0.

Convalida

Eseguire VTS

Dopo aver integrato una o più sotto-HAL con Sensors Multi-HAL 2.1, utilizza Vendor Test Suite (VTS) per assicurarti che le implementazioni delle sotto-HAL soddisfino tutti i requisiti impostati dall'interfaccia Sensors HAL.

Per eseguire solo i test VTS dei sensori quando VTS è configurato su una macchina host, esegui 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 esegui il livello di shim multi-HAL AIDL, esegui VtsAidlHalSensorsTargetTest.

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

Eseguire i test delle unità

I test delle unità in HalProxy_test.cpp testano HalProxy utilizzando sotto-HAL fittizie che vengono istanziate nel test delle unità e non vengono caricate dinamicamente. Quando crei una nuova sotto-HAL, questi test devono fungere da guida su come aggiungere test delle unità che verifichino che la nuova sotto-HAL sia implementata correttamente.

Per eseguire i test, esegui i seguenti comandi:

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

Eseguire il test con le sotto-HAL fittizie

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

Le sotto-HAL fittizie possono essere utilizzate per testare il funzionamento del codice Multi-HAL completo con altre sotto-HAL caricate nel sistema e per stressare vari aspetti del codice Sensors Multi-HAL.

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

Per creare ed eseguire il push delle sotto-HAL fittizie su un dispositivo:

  1. Esegui i seguenti comandi per creare ed eseguire il push delle tre diverse sotto-HAL fittizie sul 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 HAL dei sensori in /vendor/etc/sensors/hals.conf con i percorsi delle sotto-HAL fittizie.

    /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 le nuove sotto-HAL elencate nella configurazione.

    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 della HAL dei sensori, esegui il seguente comando:

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

Le informazioni sullo stato attuale di HalProxy e delle relative sotto-HAL vengono quindi inviate al terminale. Di seguito è riportato un esempio dell'output del comando per l'oggetto HalProxy e le sotto-HAL fittizie.

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 è elevato (1000 o più), indica che sono presenti molti eventi in attesa di essere scritti nel framework dei sensori. Ciò indica che il servizio dei sensori è in deadlock o si è arrestato in modo anomalo e non sta elaborando gli eventi dei sensori oppure che di recente è stato pubblicato un batch di eventi dei sensori di grandi dimensioni da una sotto-HAL.

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

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