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 sub-HAL dei sensori memorizzate come librerie dinamiche nella partizione del fornitore e fornisce loro un oggetto di callback che può gestire la pubblicazione di eventi e l'acquisizione e il rilascio del wake lock. Una sub-HAL dei sensori è una HAL dei sensori integrata in un oggetto condiviso nella partizione del fornitore e viene utilizzata dal framework multi-HAL. Questi sub-HAL non dipendono l'uno dall'altro 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 sub-HAL in grado di esporre il tipo di sensore angolo della cerniera. Per supportare questo tipo di sensore, le 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 l'HAL AIDL dei sensori, puoi utilizzare il livello shim multi-HAL per consentire la funzionalità multi-HAL. Per i dettagli di implementazione, vedi Utilizzo di Sensors Multi-HAL con Sensors AIDL HAL.
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 sub-HAL.
L'interfaccia di ISensorsSubHal
è diversa da quella di
2.1/ISensors.hal
(o
2.0/ISensors.hal
)
per i seguenti motivi:
- Il metodo initialize passa una classe
IHalProxyCallback
anziché due FMQ eISensorsCallback
. - Le sub-HAL devono implementare una funzione di debug per fornire informazioni di debug nelle segnalazioni di bug.
- Le sub-HAL devono implementare una funzione di denominazione in modo che la sub-HAL caricata possa essere distinta dalle altre sub-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: uno per pubblicare eventi dei sensori nel framework
dei sensori e uno per creare wake lock. A livello interno, Sensors
Multi-HAL gestisce tutte le interazioni con le FMQ per garantire la distribuzione tempestiva degli
eventi dei sensori per tutti gli HAL secondari. È consigliabile che le sub-HAL utilizzino il metodo
createScopedWakelock
per delegare l'onere del timeout dei wake lock a
Sensors Multi-HAL e per centralizzare l'utilizzo dei wake lock in un unico wake lock comune
per l'intera Sensors Multi-HAL, il che riduce al minimo le chiamate di blocco e sblocco.
Sensors Multi-HAL 2 dispone anche di alcune funzionalità di sicurezza integrate. Gestisce
le situazioni in cui la coda di messaggi veloci del sensore è piena o in cui il framework dei sensori Android
si riavvia 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 accettare
gli eventi immediatamente, Sensors Multi-HAL può spostare gli eventi in un thread
in background per consentire la continuazione del lavoro in tutti gli HAL secondari durante l'attesa della
pubblicazione degli eventi.
Codice sorgente e implementazione di riferimento
Tutto il codice Multi-HAL dei sensori è disponibile in
hardware/interfaces/sensors/common/default/2.X/multihal/
.
Ecco alcuni suggerimenti per alcune risorse.
HalProxy.h
: L'oggettoHalProxy
viene istanziato da Sensors multi-HAL e gestisce il passaggio dei dati dalle sub-HAL al framework dei sensori.HalProxy.cpp
: L'implementazione diHalProxy
contiene tutta la logica necessaria per multiplexare la comunicazione tra le sub-HAL e il framework dei sensori.SubHal.h
: L'interfacciaISensorsSubHal
definisce l'interfaccia che le sub-HAL devono seguire per essere compatibili conHalProxy
. La sub-HAL implementa il metodo initialize in modo che l'oggettoHalProxyCallback
possa essere utilizzato perpostEvents
ecreateScopedWakelock
.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 diHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: Questa implementazione di sub-HAL di esempio utilizza sensori fittizi per generare dati fittizi. Utile per testare l'interazione di più sub-HAL su un dispositivo.
Implementazione
Questa sezione descrive come implementare Sensors Multi-HAL nelle seguenti situazioni:
- Utilizzo di Sensors Multi-HAL con Sensors AIDL HAL
- Implementazione di Sensors Multi-HAL 2.1
- Porting da Sensors Multi-HAL 2.0 a Multi-HAL 2.1
- Porting da Sensors HAL 2.0
- Porting da Sensors HAL 1.0
- Porting da Sensors Multi-HAL 1.0
Utilizzare Sensors Multi-HAL con Sensors AIDL HAL
Per consentire la funzionalità multi-HAL con l'HAL AIDL Sensors, importa il modulo del livello 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 intorno all'interfaccia multi-HAL descritta in Implementazione di Sensors Multi-HAL 2.1. Il livello shim multi-HAL AIDL è compatibile con i dispositivi che implementano Sensors Multi-HAL 2.1.
Il livello shim multi-HAL AIDL consente di esporre i tipi di sensori head tracker e IMU ad assi limitati nell'HAL AIDL dei sensori. Per utilizzare questi tipi di sensore
definiti dall'interfaccia AIDL HAL, imposta il campo type
nello
struct SensorInfo
nell'implementazione di getSensorsList_2_1()
. Questa operazione è sicura
perché i campi del tipo di sensore 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, segui questi passaggi:
- Implementa l'interfaccia
ISensorsSubHal
come descritto inSubHal.h
. - Implementa il
metodo
sensorsHalGetSubHal_2_1
inSubHal.h
. Aggiungi un target
cc_library_shared
per creare il nuovo sub-HAL implementato. Quando aggiungi la destinazione:- Assicurati che il target venga inviato a una posizione nella partizione del fornitore del dispositivo.
- Nel file di configurazione che si trova in
/vendor/etc/sensors/hals.conf
, aggiungi il percorso della libreria su una nuova riga. Se necessario, crea il filehals.conf
.
Per un esempio di voce
Android.bp
per la creazione di una libreria sub-HAL, vedihardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Rimuovi tutte le voci
android.hardware.sensors
dal filemanifest.xml
, che contiene l'elenco degli HAL supportati sul dispositivo.Rimuovi tutti i servizi
android.hardware.sensors
e i fileservice.rc
dal filedevice.mk
e aggiungiandroid.hardware.sensors@2.1-service.multihal
eandroid.hardware.sensors@2.1-service.multihal.rc
aPRODUCT_PACKAGES
.
All'avvio, HalProxy
si avvia, cerca la sub-HAL appena implementata e
la inizializza chiamando
sensorsHalGetSubHal_2_1
.
Porta 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'interfaccia
SubHal
e ricompila la tua sub-HAL.
Di seguito sono riportate le differenze tra le interfacce 2.0 e 2.1 di SubHal
:
IHalProxyCallback
utilizza i tipi creati nella versione 2.1 della specificaISensors.hal
.- La funzione
initialize()
passa un nuovoIHalProxyCallback
anziché quello dell'interfaccia 2.0SubHal
- Le sub-HAL devono implementare
getSensorsList_2_1
einjectSensorData_2_1
anzichégetSensorsList
einjectSensorData
, poiché questi metodi utilizzano i nuovi tipi aggiunti nella versione 2.1 della specificaISensors.hal
. - Le sub-HAL devono esporre
sensorsHalGetSubHal_2_1
anzichésensorsHalGetSubHal
affinché la Multi-HAL le tratti come sub-HAL di versione 2.1.
Porta 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.
Inizializza l'HAL
Sensors HAL 2.0 ha una funzione di inizializzazione che consente al servizio sensore di
passare FMQ e un callback del sensore dinamico. In Sensors Multi-HAL 2.0, la funzione
initialize()
passa un singolo callback che deve essere utilizzato per pubblicare
eventi del sensore, ottenere wake lock e notificare la connessione e
la disconnessione dei sensori dinamici.
Pubblica gli eventi del sensore nell'implementazione di Multi-HAL
Anziché pubblicare eventi del sensore tramite FMQ, la sub-HAL deve scrivere gli eventi del sensore in
IHalProxyCallback
quando sono disponibili.
Eventi WAKE_UP
In Sensors HAL 2.0, l'HAL può gestire il wake lock per la sua implementazione. In
Sensors Multi-HAL 2.0, le sub-HAL consentono all'implementazione di Multi-HAL di
gestire i wake lock e possono richiedere l'acquisizione di un wake lock richiamando
createScopedWakelock
.
Un wake lock con ambito bloccato deve essere acquisito e passato a postEvents
quando
vengono pubblicati eventi di riattivazione nell'implementazione di Multi-HAL.
Sensori dinamici
Sensors Multi-HAL 2.0 richiede che onDynamicSensorsConnected
e
onDynamicSensorsDisconnected
in
IHalProxyCallback
vengano chiamati ogni volta che cambiano le connessioni dinamiche dei sensori. Questi callback sono
disponibili come parte del puntatore IHalProxyCallback
fornito tramite
la funzione initialize()
.
Porta 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.
Inizializza l'HAL
La funzione initialize()
deve essere supportata per stabilire il callback tra l'HAL secondario e l'implementazione di 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 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.
Pubblica gli eventi del sensore nell'implementazione di Multi-HAL
In Sensors HAL 2.0, anziché attendere la chiamata di poll()
, la sub-HAL
deve scrivere in modo proattivo gli eventi del sensore in
IHalProxyCallback
ogni volta che sono disponibili.
Eventi WAKE_UP
In Sensors HAL 1.0, l'HAL può gestire il wake lock per la sua implementazione. In
Sensors Multi-HAL 2.0, le sub-HAL consentono all'implementazione di Multi-HAL di
gestire i wake lock e possono richiedere l'acquisizione di un wake lock richiamando
createScopedWakelock
.
Un wake lock con ambito bloccato deve essere acquisito e passato a postEvents
quando
vengono pubblicati eventi di riattivazione nell'implementazione di 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 dinamiche dei sensori. Questi callback sono
disponibili come parte del puntatore IHalProxyCallback
fornito tramite
la funzione initialize()
.
Porta da Sensors Multi-HAL 1.0
Per eseguire il porting di un'implementazione esistente da Sensors Multi-HAL 1.0, segui questi passaggi.
- 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
. - Rimuovi tutti i riferimenti a
hardware/hardware.h
ehardware/sensors.h
in quanto non sono supportati per HAL 2.0. - Trasferisci le sub-HAL delle porte come descritto in Porting da Sensors Hal 1.0.
- Imposta Sensors Multi-HAL 2.0 come HAL designato seguendo i passaggi 3 e 4 della sezione Implementazione di Sensors Multi-HAL 2.0.
Convalida
Esegui VTS
Dopo aver integrato uno o più sub-HAL con Sensors Multi-Hal 2.1, utilizza la Vendor Test Suite (VTS) per assicurarti che le implementazioni dei sub-HAL soddisfino tutti i requisiti stabiliti dall'interfaccia HAL di Sensors.
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 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 delle unità
I test delle unità in HalProxy_test.cpp
test HalProxy
utilizzano sub-HAL falsi che
vengono istanziati nel test delle unità e non vengono caricati dinamicamente. Quando crei una
nuova sub-HAL, questi test devono fungere da guida su come aggiungere test unitari che
verifichino che la nuova sub-HAL sia implementata correttamente.
Per eseguire i test, esegui questi comandi:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Testare con le HAL secondarie fittizie
I sub-HAL falsi sono implementazioni fittizie dell'interfaccia ISensorsSubHal
.
Gli HAL secondari espongono elenchi diversi 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.
Le sub-HAL false possono essere utilizzate per testare il funzionamento del codice Multi-HAL completo con altre sub-HAL caricate nel sistema e per mettere alla prova vari aspetti del codice Multi-HAL dei sensori.
Due falsi sub-HAL sono disponibili all'indirizzo
hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
.
Per creare e inviare le sub-HAL fittizie a un dispositivo, segui questi passaggi:
Esegui i seguenti comandi per creare ed eseguire il push dei tre diversi sub-HAL fittizi 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
Aggiorna la configurazione HAL dei sensori in
/vendor/etc/sensors/hals.conf
con i percorsi per le sub-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
Riavvia
HalProxy
e carica i nuovi sub-HAL elencati 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 dell'HAL Sensors, esegui questo comando:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Le informazioni sullo stato attuale di HalProxy
e dei relativi sub-HAL vengono quindi
output nel terminale. Di seguito è riportato un esempio dell'output del comando per l'oggetto
HalProxy
e le false sub-HAL.
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ù), significa che ci sono molti eventi in attesa di essere scritti nel framework dei sensori. Ciò indica che il servizio sensore è in deadlock o si è arrestato in modo anomalo e
non elabora gli eventi sensore oppure che di recente è stato pubblicato un batch di grandi dimensioni di eventi sensore
da una sub-HAL.
Se il conteggio dei riferimenti del wake lock è maggiore di 0
, significa che HalProxy
ha
acquisito un wake lock. Deve essere maggiore di 0
solo se è in corso una ScopedWakelock
intenzionale o se gli eventi di riattivazione sono stati inviati a HalProxy
e non sono
stati elaborati dal framework dei sensori.
Il descrittore di file passato al metodo di debug di HalProxy
viene passato a ogni
sub-HAL, pertanto gli sviluppatori devono implementare il metodo di debug come parte dell'interfaccia
ISensorsSubHal
.