Die Sensors Multi-HAL ist ein Framework, mit dem Sensor-HALs neben anderen Sensor-HALs ausgeführt werden können. Die Sensors Multi-HAL lädt dynamisch Sensor-Unter-HALs, die als dynamische Bibliotheken auf der Anbieterpartition gespeichert sind, und weist ihnen ein Rückrufobjekt zu, das Ereignisse posten und die Wake-Lock erwerben und freigeben kann. Ein untergeordneter HAL für Sensoren ist ein HAL für Sensoren, der in ein gemeinsam genutztes Objekt auf der Anbieterpartition eingebunden ist und vom Multi-HAL-Framework verwendet wird. Diese Sub-HALs hängen nicht voneinander oder vom Multi-HAL-Code ab, der die Hauptfunktion für den Prozess enthält.
Sensors Multi-HAL 2.1, verfügbar auf Geräten mit Android 11 oder höher, ist eine Iteration von Sensors Multi-HAL 2.0, die das Laden von Unter-HALs unterstützt, die den Sensortyp Scharnierwinkel sichtbar machen können. Zur Unterstützung dieses Sensortyps müssen Sub-HALs die im 2.1 SubHal-Header definierten Sub-HAL-APIs verwenden.
Bei Geräten mit Android 13 oder höher, die Sensors AIDL HAL verwenden, können Sie die Multi-HAL-Shim-Ebene verwenden, um Multi-HAL-Funktionen zuzulassen. Implementierungsdetails finden Sie unter Sensors Multi-HAL mit der Sensors AIDL HAL verwenden.
Unterschied zwischen Sensors Multi-HAL 2 und Sensors HAL 2
Sensors Multi-HAL 2 ist auf Geräten mit Android 10 oder höher verfügbar und bietet mehrere Abstraktionen zusätzlich zu Sensors HAL 2, um die Interaktion mit HAL APIs zu vereinfachen. Sensors Multi-HAL 2 führt die HalProxy-Klasse ein, um die HAL 2-Schnittstelle von Sensors und die Schnittstelle V2_1/SubHal
(oder V2_0/SubHal
) zu implementieren, damit HalProxy
mit Unter-HALs interagieren kann.
Die Schnittstelle ISensorsSubHal
unterscheidet sich in folgenden Punkten von der Schnittstelle 2.1/ISensors.hal
(oder 2.0/ISensors.hal
):
- Die Methode „initialize“ übergibt eine
IHalProxyCallback
-Klasse anstelle von zwei FMQs undISensorsCallback
. - Sub-HALs müssen eine Fehlerbehebungsfunktion implementieren, um in Fehlerberichten Informationen zur Fehlerbehebung zur Verfügung zu stellen.
- Untergeordnete HALs müssen eine Namensfunktion implementieren, damit die geladene untergeordnete HAL von anderen untergeordneten HALs unterschieden werden kann.
Der Hauptunterschied zwischen Sensors Multi-HAL 2 und Sensors HAL 2 besteht in den Initialisierungsfunktionen. Anstelle von FMQs bietet die IHalProxyCallback
-Schnittstelle zwei Methoden: eine Methode zum Senden von Sensorereignissen an das Sensoren-Framework und eine Methode zum Erstellen von Wakelocks. Im Hintergrund verwaltet die Multi-HAL für Sensoren alle Interaktionen mit den FMQs, um eine zeitnahe Übermittlung von Sensorereignissen für alle untergeordneten HALs zu gewährleisten. Es wird dringend empfohlen, Sub-HALs die Methode createScopedWakelock
zu verwenden, um die Last für das Zeitlimit von Wakelocks an das Sensors Multi-HAL zu delegieren und die Wakelock-Nutzung auf einen gemeinsamen Wakelock für die gesamten Multi-HAL-Sensoren zu zentralisieren, wodurch das Sperren und Entsperren von Aufrufen minimiert wird.
Die Sensoren Multi-HAL 2 haben außerdem einige integrierte Sicherheitsfunktionen. Sie verarbeitet Situationen, in denen der FMQ des Sensors voll ist oder das Android-Sensor-Framework neu gestartet wird und der Sensorstatus zurückgesetzt werden muss. Wenn Ereignisse an die HalProxy
-Klasse gepostet werden, das Sensor-Framework sie aber nicht sofort akzeptieren kann, kann die Multi-HAL von Google Pixel die Ereignisse in einen Hintergrund-Thread verschieben, damit die Arbeit in allen untergeordneten HALs fortgesetzt werden kann, während auf das Posten der Ereignisse gewartet wird.
Implementierung von Quellcode und Referenz
Der Multi-HAL-Code aller Sensoren ist in hardware/interfaces/sensors/common/default/2.X/multihal/
verfügbar.
Hier finden Sie einige hilfreiche Ressourcen.
HalProxy.h
: DasHalProxy
-Objekt wird von Sensors Multi-HAL instanziiert und verarbeitet die Übergabe von Daten von den untergeordneten HALs an das Sensor-Framework.HalProxy.cpp
: Die Implementierung vonHalProxy
enthält die gesamte Logik, die für die Multiplex-Kommunikation zwischen Sub-HALs und dem Sensor-Framework erforderlich ist.SubHal.h
: DieISensorsSubHal
-Schnittstelle definiert die Schnittstelle, der untergeordnete HALs entsprechen müssen, um mitHalProxy
kompatibel zu sein. Die untergeordnete HAL implementiert die Methode „initialize“, damit dasHalProxyCallback
-Objekt fürpostEvents
undcreateScopedWakelock
verwendet werden kann.Verwenden Sie für Multi-HAL 2.0-Implementierungen Version 2.0 von
SubHal.h
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: Mit diesen Unittests wird dieHalProxy
-Implementierung überprüft.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: In dieser Beispielimplementierung der Sub-HAL werden gefälschte Sensoren verwendet, um gefälschte Daten zu generieren. Nützlich zum Testen der Interaktion mehrerer untergeordneter HALs auf einem Gerät.
Implementierung
In diesem Abschnitt wird beschrieben, wie Sensors Multi-HAL in den folgenden Situationen implementiert wird:
- Sensoren Multi-HAL mit den Sensoren AIDL HAL verwenden
- Sensoren Multi-HAL 2.1 implementieren
- Porting von Sensoren Multi-HAL 2.0 zu Multi-HAL 2.1
- Portierung von Sensors HAL 2.0
- Porting von Sensoren HAL 1.0
- Porting von Sensoren Multi-HAL 1.0
Sensors Multi-HAL mit der Sensors AIDL HAL verwenden
Wenn Sie die Multi-HAL-Funktion mit der Sensors AIDL HAL zulassen möchten, importieren Sie das AIDL-Multi-HAL-Shimstapelmodul, das sich unter hardware/interfaces/sensors/aidl/default/multihal/ befindet. Das Modul übernimmt die Umwandlung zwischen HAL-Definitionen von AIDL- und HIDL-Sensoren und definiert einen Wrapper für die Multi-HAL-Schnittstelle, die in Implementing Sensors Multi-HAL 2.1 beschrieben wird. Die AIDL-Multi-HAL-Shimsschicht ist mit Geräten kompatibel, die Sensors Multi-HAL 2.1 implementieren.
Mit der AIDL-Multi-HAL-Shim-Ebene können Sie den Kopftracker und die IMU-Sensortypen mit begrenzter Achse im AIDL HAL-Sensor der Sensoren sichtbar machen. Wenn Sie diese von der AIDL HAL-Schnittstelle definierten Sensortypen verwenden möchten, setzen Sie das Feld type
in der Struktur SensorInfo
in der getSensorsList_2_1()
-Implementierung. Das ist sicher, da sich die Felder für den Sensortyp der AIDL- und HIDL-Sensoren HAL nicht überschneiden.
Sensoren implementieren Multi-HAL 2.1
So implementieren Sie Sensors Multi-HAL 2.1 auf einem neuen Gerät:
- Implementieren Sie die
ISensorsSubHal
-Schnittstelle wie unterSubHal.h
beschrieben. - Implementieren Sie die Methode
sensorsHalGetSubHal_2_1
inSubHal.h
. Fügen Sie ein
cc_library_shared
-Ziel hinzu, um die neu implementierte Unter-HAL zu erstellen. Gehen Sie beim Hinzufügen des Ziels so vor:- Achten Sie darauf, dass das Ziel an eine Stelle auf der Anbieterpartition des Geräts gesendet wird.
- Fügen Sie in der Konfigurationsdatei unter
/vendor/etc/sensors/hals.conf
den Pfad zur Bibliothek in einer neuen Zeile hinzu. Erstellen Sie bei Bedarf die Dateihals.conf
.
Ein Beispiel für einen
Android.bp
-Eintrag zum Erstellen einer untergeordneten HAL-Bibliothek finden Sie unterhardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Entfernen Sie alle
android.hardware.sensors
-Einträge aus der Dateimanifest.xml
, die die Liste der unterstützten HALs auf dem Gerät enthält.Entfernen Sie alle
android.hardware.sensors
-Dienst- undservice.rc
-Dateien aus der Dateidevice.mk
und fügen Sieandroid.hardware.sensors@2.1-service.multihal
undandroid.hardware.sensors@2.1-service.multihal.rc
zuPRODUCT_PACKAGES
hinzu.
Beim Booten startet HalProxy
, sucht nach dem neu implementierten Unter-HAL und initialisiert es durch Aufrufen von sensorsHalGetSubHal_2_1
.
Anschluss von Sensoren Multi-HAL 2.0 zu Multi-HAL 2.1
Wenn Sie von Multi-HAL 2.0 zu Multi-HAL 2.1 wechseln möchten, implementieren Sie die Schnittstelle SubHal
und kompilieren Sie die untergeordnete HAL neu.
Das sind die Unterschiede zwischen den SubHal
-Benutzeroberflächen 2.0 und 2.1:
IHalProxyCallback
verwendet die in Version 2.1 der SpezifikationISensors.hal
erstellten Typen.- Die Funktion
initialize()
übergibt eine neueIHalProxyCallback
anstelle derjenigen aus der 2.0-SubHal
-Oberfläche. - Sub-HALs müssen
getSensorsList_2_1
undinjectSensorData_2_1
anstelle vongetSensorsList
undinjectSensorData
implementieren, da diese Methoden die neuen Typen verwenden, die in Version 2.1 derISensors.hal
-Spezifikation hinzugefügt wurden. - Sub-HALs müssen
sensorsHalGetSubHal_2_1
stattsensorsHalGetSubHal
verfügbar machen, damit Multi-HAL sie als Unter-HALs der Version 2.1 behandeln können.
Port von Sensors HAL 2.0
Wenn Sie von Sensors HAL 2.0 auf Sensors Multi-HAL 2.0 upgraden, achten Sie darauf, dass die HAL-Implementierung die folgenden Anforderungen erfüllt.
HAL initialisieren
HAL 2.0 der Sensoren hat eine Initialisierungsfunktion, mit der der Sensordienst FMQs und einen dynamischen Sensor-Callback übergeben kann. In Sensors Multi-HAL 2.0 übergibt die Funktion initialize()
einen einzelnen Callback, der verwendet werden muss, um Sensorereignisse zu posten, Wakelocks abzurufen und über dynamische Sensorverbindungen und -unterbrechungen zu informieren.
Sensorereignisse an die Multi-HAL-Implementierung posten
Anstatt Sensorereignisse über das FMQ zu senden, muss der Sub-HAL Sensorereignisse in die IHalProxyCallback
schreiben, wenn Sensorereignisse verfügbar sind.
WAKE_UP-Ereignisse
In HAL 2.0 der Sensoren kann der HAL den Wakelock für seine Implementierung verwalten. In Sensors Multi-HAL 2.0 ermöglichen die Sub-HALs der Multi-HAL-Implementierung die Verwaltung von Wakelocks und können durch Aufrufen von createScopedWakelock
das Abrufen eines Wakelocks anfordern.
Wenn Weck-Ereignisse an die Multi-HAL-Implementierung gesendet werden, muss eine gesperrte Wecksperre abgerufen und an postEvents
übergeben werden.
Dynamische Sensoren
Bei Sensors Multi-HAL 2.0 müssen onDynamicSensorsConnected
und onDynamicSensorsDisconnected
in IHalProxyCallback
aufgerufen werden, wenn sich dynamische Sensorverbindungen ändern. Diese Callbacks sind als Teil des IHalProxyCallback
-Zeigers verfügbar, der über die initialize()
-Funktion bereitgestellt wird.
Port von Sensors HAL 1.0
Wenn Sie von Sensors HAL 1.0 auf Sensors Multi-HAL 2.0 umstellen, muss die HAL-Implementierung die folgenden Anforderungen erfüllen.
HAL initialisieren
Die Funktion initialize()
muss unterstützt werden, um den Callback zwischen dem Sub-HAL und der Multi-HAL-Implementierung einzurichten.
Verfügbare Sensoren freigeben
In Sensors Multi-HAL 2.0 muss die Funktion getSensorsList()
bei einem einzelnen Gerätestart denselben Wert zurückgeben, auch bei HAL-Neustarts von Sensoren. So kann das Framework versuchen, Sensorverbindungen wiederherzustellen, wenn der Systemserver neu gestartet wird. Der von getSensorsList()
zurückgegebene Wert kann sich nach einem Neustart des Geräts ändern.
Sensorereignisse an die Multi-HAL-Implementierung senden
In HAL 2.0 von Sensoren muss der Sub-HAL nicht auf den Aufruf von poll()
warten, sondern proaktiv Sensorereignisse in IHalProxyCallback
schreiben, wenn Sensorereignisse verfügbar sind.
WAKE_UP-Ereignisse
In HAL 1.0 der Sensoren kann der HAL den Wakelock für seine Implementierung verwalten. In Sensors Multi-HAL 2.0 können die untergeordneten HALs die Multi-HAL-Implementierung zum Verwalten von Wakelocks verwenden und durch Aufrufen von createScopedWakelock
ein Wakelock anfordern.
Ein gesperrter Wakelock muss abgerufen und an postEvents
übergeben werden, wenn Wakeup-Ereignisse an die Multi-HAL-Implementierung gesendet werden.
Dynamische Sensoren
In Sensors HAL 1.0 werden dynamische Sensoren über die Funktion poll()
zurückgegeben.
Für Sensoren mit Multi-HAL 2.0 müssen onDynamicSensorsConnected
und onDynamicSensorsDisconnected
in IHalProxyCallback
aufgerufen werden, wenn sich dynamische Sensorverbindungen ändern. Diese Callbacks sind als Teil des IHalProxyCallback
-Zeigers verfügbar, der über die initialize()
-Funktion bereitgestellt wird.
Port von Sensors Multi-HAL 1.0
So portieren Sie eine vorhandene Implementierung von Sensors Multi-HAL 1.0:
- Die HAL-Konfiguration der Sensoren muss sich unter
/vendor/etc/sensors/hals.conf
befinden. Dazu kann auch gehören, dass die Datei unter/system/etc/sensors/hals.conf
verschoben wird. - Entfernen Sie alle Verweise auf
hardware/hardware.h
undhardware/sensors.h
, da diese für HAL 2.0 nicht unterstützt werden. - Portieren Sie untergeordnete HALs wie unter Porting von Sensors HAL 1.0 beschrieben.
- Legen Sie Sensors Multi-HAL 2.0 als die angegebene HAL fest. Folgen Sie dazu den Schritten 3 und 4 im Abschnitt Implementing Sensors Mutli-HAL 2.0 (Implementierung von Sensors Multi-HAL 2.0).
Zertifizierungsstufe
VTS ausführen
Wenn Sie eine oder mehrere untergeordnete HALs in Sensors Multi-HAL 2.1 eingebunden haben, verwenden Sie die Vendor Test Suite (VTS), um sicherzustellen, dass Ihre untergeordneten HAL-Implementierungen alle Anforderungen der Sensors HAL-Schnittstelle erfüllen.
Wenn Sie nur die VTS-Tests für Sensoren ausführen möchten, wenn VTS auf einem Hostcomputer eingerichtet ist, führen Sie die folgenden Befehle aus:
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
Wenn Sie die AIDL Multi-HAL-Shim-Ebene ausführen, führen Sie VtsAidlHalSensorsTargetTest
aus.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Einheitentests ausführen
Die Einheitentests in HalProxy_test.cpp
testen HalProxy
mit falschen Unter-HALs, die im Einheitentest instanziiert und nicht dynamisch geladen werden. Beim Erstellen einer neuen untergeordneten HAL sollten diese Tests als Leitfaden dienen, um Unit-Tests hinzuzufügen, mit denen die ordnungsgemäße Implementierung der neuen untergeordneten HAL überprüft wird.
Führen Sie die folgenden Befehle aus, um die Tests auszuführen:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Mit falschen Sub-HALs testen
Die gefälschten untergeordneten HALs sind Dummy-Implementierungen der ISensorsSubHal
-Schnittstelle.
Die untergeordneten HALs stellen unterschiedliche Listen von Sensoren bereit. Wenn die Sensoren aktiviert sind, senden sie basierend auf den in einer bestimmten Sensoranfrage angegebenen Intervallen regelmäßig automatisch generierte Sensorereignisse an HalProxy
.
Mit den gefälschten Sub-HALs kann getestet werden, wie der vollständige Multi-HAL-Code mit anderen Sub-HALs funktioniert, die in das System geladen werden, und verschiedene Aspekte des Multi-HAL-Codes der Sensoren beansprucht werden.
Unter hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
sind zwei gefälschte untergeordnete HALs verfügbar.
So erstellen Sie die gefälschten Sub-HALs und schieben sie auf ein Gerät:
Führen Sie die folgenden Befehle aus, um die drei verschiedenen gefälschten Sub-HALs zu erstellen und auf das Gerät zu übertragen:
$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
Aktualisieren Sie die HAL-Konfiguration für Sensoren unter
/vendor/etc/sensors/hals.conf
mit den Pfaden zu den gefälschten untergeordneten HALs./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
Starten Sie
HalProxy
neu und laden Sie die neuen untergeordneten HALs, die in der Konfiguration aufgeführt sind.adb shell stop
adb shell start
Fehlerbehebung
Entwickler können das Framework mit dem Befehl lshal
debuggen. Führen Sie den folgenden Befehl aus, um die Debugausgabe der Sensors HAL anzufordern:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Informationen zum aktuellen Status von HalProxy
und seinen untergeordneten HALs werden dann im Terminal ausgegeben. Unten sehen Sie ein Beispiel für die Befehlsausgabe für das HalProxy
-Objekt und die gefälschten untergeordneten HALs.
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
Wenn die für # of events on pending write queue
angegebene Zahl eine große Zahl (1.000 oder mehr) ist, weist dies darauf hin, dass viele Ereignisse noch nicht in das Sensoren-Framework geschrieben werden müssen. Dies weist darauf hin, dass der Sensordienst gesperrt ist, abgestürzt ist und keine Sensorereignisse verarbeitet, oder dass vor Kurzem ein großer Batch von Sensorereignissen von einem Sub-HAL gesendet wurde.
Wenn die Anzahl der Wakelock-Referenzen größer als 0
ist, hat HalProxy
ein Wakelock erworben. Dieser Wert sollte nur dann größer als 0
sein, wenn eine ScopedWakelock
absichtlich gehalten wird oder wenn Weck-Ereignisse an HalProxy
gesendet und nicht vom Sensor-Framework verarbeitet wurden.
Der Dateideskriptor, der an die Debug-Methode von HalProxy
übergeben wird, wird an jede untergeordnete HAL übergeben. Entwickler müssen die Debug-Methode daher als Teil der ISensorsSubHal
-Schnittstelle implementieren.