Die Sensors Multi-HAL ist ein Framework, mit dem Sensors-HALs zusammen mit anderen Sensor-HALs ausgeführt werden können. Die Sensors Multi-HAL lädt dynamisch Sensors-Sub-HALs, die als dynamische Bibliotheken auf der Anbieterpartition gespeichert sind, und gibt ihnen ein Callback-Objekt, mit dem Ereignisse gepostet und der Wakelock erworben und freigegeben werden kann. Eine Sensors-Sub-HAL ist eine Sensors-HAL, die in ein gemeinsam genutztes Objekt auf der Anbieterpartition eingebunden ist und vom Multi-HAL-Framework verwendet wird. Diese Sub-HALs sind nicht voneinander oder vom Multi-HAL-Code abhängig, der die Hauptfunktion für den Prozess enthält.
Sensors Multi-HAL 2.1 ist auf Geräten mit Android 11 oder höher verfügbar und eine Weiterentwicklung von Sensors Multi-HAL 2.0. Sie unterstützt das Laden von Sub-HALs, die den Sensor für den Scharnierwinkel verfügbar machen können. Um diesen Sensortyp zu unterstützen, müssen Sub-HALs die im 2.1 SubHal-Header definierten Sub-HAL-APIs verwenden.
Auf Geräten mit Android 13 oder höher, die die Sensors AIDL HAL verwenden, können Sie die Multi-HAL-Shim-Schicht verwenden, um die Multi-HAL-Funktion zu ermöglichen. Implementierungsdetails finden Sie unter siehe 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 führt mehrere Abstraktionen über Sensors HAL
2 ein, um die Interaktion mit HAL-APIs zu vereinfachen. Sensors Multi-HAL 2 führt die
HalProxy
Klasse ein, um die Implementierung der Sensors HAL 2-Schnittstelle und der
V2_1/SubHal
(oder
V2_0/SubHal)
Schnittstelle zu verarbeiten, damit HalProxy mit Sub-HALs interagieren kann.
Die Schnittstelle ISensorsSubHal unterscheidet sich in folgenden Punkten von der
2.1/ISensors.hal
(oder
2.0/ISensors.hal)
Schnittstelle:
- Die Methode „initialize“ übergibt eine
IHalProxyCallback-Klasse anstelle von zwei FMQs undISensorsCallback. - Sub-HALs müssen eine Debug-Funktion implementieren, um Debugging-Informationen in Fehlerberichten bereitzustellen.
- Sub-HALs müssen eine Namensfunktion implementieren, damit die geladene Sub-HAL von anderen Sub-HALs unterschieden werden kann.
Der Hauptunterschied zwischen Sensors Multi-HAL 2 und Sensors HAL 2 liegt in den Initialisierungsfunktionen. Anstelle von FMQs bietet die Schnittstelle IHalProxyCallback zwei Methoden: eine zum Posten von Sensorereignissen an das Sensor-Framework und eine zum Erstellen von Aktivierungssperren. Im Hintergrund verwaltet die Sensors Multi-HAL alle Interaktionen mit den FMQs, um die rechtzeitige Bereitstellung von Sensorereignissen für alle Sub-HALs zu gewährleisten. Es wird dringend empfohlen, dass Sub-HALs die Methode createScopedWakelock verwenden, um die Aufgabe, Wakelocks zu beenden, an die Sensors Multi-HAL zu delegieren und die Verwendung von Wakelocks auf eine gemeinsame Wakelock für die gesamte Sensors Multi-HAL zu zentralisieren. Dadurch werden Sperr- und Entsperraufrufe minimiert.
Sensors Multi-HAL 2 bietet auch einige integrierte Sicherheitsfunktionen. Sie verarbeitet Situationen, in denen die Sensor-FMQ voll ist oder das Android-Sensor-Framework neu gestartet wird und der Sensorstatus zurückgesetzt werden muss. Wenn außerdem Ereignisse in der Klasse HalProxy gepostet werden, das Sensor-Framework die Ereignisse aber nicht sofort akzeptieren kann, kann die Sensors Multi-HAL die Ereignisse in einen Hintergrundthread verschieben, damit die Arbeit in allen Sub-HALs fortgesetzt werden kann, während auf das Posten der Ereignisse gewartet wird.
Quellcode und Referenzimplementierung
Der gesamte Sensors Multi-HAL-Code ist unter
hardware/interfaces/sensors/common/default/2.X/multihal/ verfügbar.
Hier finden Sie Links zu einigen Ressourcen.
HalProxy.h: DasHalProxy-Objekt wird von Sensors Multi-HAL instanziiert und verarbeitet die Übergabe von Daten von den Sub-HALs an das Sensor-Framework.HalProxy.cpp: Die Implementierung vonHalProxyenthält die gesamte Logik, die für das Multiplexen der Kommunikation zwischen Sub-HALs und dem Sensor-Framework erforderlich ist.SubHal.h: Die SchnittstelleISensorsSubHaldefiniert die Schnittstelle, die Sub-HALs einhalten müssen, um mitHalProxykompatibel zu sein. Die Sub-HAL implementiert die Methode „initialize“, damit dasHalProxyCallback-Objekt fürpostEventsundcreateScopedWakelockverwendet werden kann.Verwenden Sie für Multi-HAL 2.0-Implementierungen die Version 2.0 von
SubHal.h.hardware/interfaces/sensors/common/default/2.X/multihal/tests/: Diese Einheitentests überprüfen dieHalProxy-Implementierung.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: Diese Beispielimplementierung der Sub-HAL verwendet gefälschte Sensoren, um gefälschte Daten zu generieren. Sie ist nützlich, um zu testen, wie mehrere Sub-HALs auf einem Gerät interagieren.
Implementierung
In diesem Abschnitt wird beschrieben, wie Sie Sensors Multi-HAL in den folgenden Situationen implementieren:
- Sensors Multi-HAL mit der Sensors AIDL HAL verwenden
- Sensors Multi-HAL 2.1 implementieren
- Von Sensors Multi-HAL 2.0 zu Multi-HAL 2.1 portieren
- Von Sensors HAL 2.0 portieren
- Von Sensors HAL 1.0 portieren
- Von Sensors Multi-HAL 1.0 portieren
Sensors Multi-HAL mit der Sensors AIDL HAL verwenden
Wenn Sie die Multi-HAL-Funktion mit der Sensors AIDL HAL verwenden möchten, importieren Sie das AIDL Multi-HAL-Shim-Schichtmodul, das sich unter „hardware/interfaces/sensors/aidl/default/multihal/“ befindet. Das Modul verarbeitet die Konvertierung zwischen AIDL- und HIDL-Sensors-HAL-Definitionstypen und definiert einen Wrapper um die Multi-HAL-Schnittstelle, die unter Sensors Multi-HAL 2.1 implementieren beschrieben wird. Die AIDL Multi-HAL-Shim-Schicht ist mit Geräten kompatibel, die Sensors Multi-HAL 2.1 implementieren.
Mit der AIDL Multi-HAL-Shim-Schicht können Sie die Sensortypen „Head Tracker“ und „IMU mit begrenzter Achse“ in der Sensors AIDL HAL verfügbar machen. Wenn Sie diese Sensortypen verwenden möchten, die von der AIDL-HAL-Schnittstelle definiert werden, legen Sie das Feld type in der Struktur SensorInfo in der Implementierung getSensorsList_2_1() fest. Das ist sicher, da sich die ganzzahligen Sensor-Typfelder der AIDL- und HIDL-Sensors-HAL nicht überschneiden.
Sensors Multi-HAL 2.1 implementieren
So implementieren Sie Sensors Multi-HAL 2.1 auf einem neuen Gerät:
- Implementieren Sie die
ISensorsSubHalSchnittstelle wie inSubHal.hbeschrieben. - Implementieren Sie die
sensorsHalGetSubHal_2_1Methode inSubHal.h. Fügen Sie ein
cc_library_shared-Ziel hinzu, um die neu implementierte Sub-HAL zu erstellen. So fügen Sie das Ziel hinzu:- Achten Sie darauf, dass das Ziel an einen Ort auf der Anbieterpartition des Geräts übertragen wird.
- Fügen Sie in der Konfigurationsdatei unter
/vendor/etc/sensors/hals.confden Pfad zur Bibliothek in einer neuen Zeile hinzu. Erstellen Sie bei Bedarf die Dateihals.conf.
Ein Beispiel für einen
Android.bpEintrag zum Erstellen einer Sub-HAL-Bibliothek finden Sie unterhardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.Entfernen Sie alle
android.hardware.sensors-Einträge aus dermanifest.xmlDatei, die die Liste der unterstützten HALs auf dem Gerät enthält.Entfernen Sie alle
android.hardware.sensors-Dienst- undservice.rc-Dateien aus derdevice.mk-Datei und fügen Sieandroid.hardware.sensors@2.1-service.multihalundandroid.hardware.sensors@2.1-service.multihal.rczuPRODUCT_PACKAGEShinzu.
Beim Booten wird HalProxy gestartet, sucht nach der neu implementierten Sub-HAL und
initialisiert sie durch Aufrufen von
sensorsHalGetSubHal_2_1.
Von Sensors Multi-HAL 2.0 zu Multi-HAL 2.1 portieren
Wenn Sie von Multi-HAL 2.0 zu Multi-HAL 2.1 portieren möchten, implementieren Sie die
SubHal
Schnittstelle und kompilieren Sie Ihre Sub-HAL neu.
Das sind die Unterschiede zwischen den Schnittstellen SubHal 2.0 und 2.1:
IHalProxyCallbackverwendet die in Version 2.1 der SpezifikationISensors.halerstellten Typen.- Die Funktion
initialize()übergibt ein neuesIHalProxyCallbackanstelle des aus der SchnittstelleSubHal2.0. - Sub-HALs müssen
getSensorsList_2_1undinjectSensorData_2_1anstelle vongetSensorsListundinjectSensorDataimplementieren, da diese Methoden die neuen Typen verwenden, die in Version 2.1 der SpezifikationISensors.halhinzugefügt wurden. - Sub-HALs müssen
sensorsHalGetSubHal_2_1anstelle vonsensorsHalGetSubHalverfügbar machen, damit sie von der Multi-HAL als Sub-HALs der Version 2.1 behandelt werden.
Von Sensors HAL 2.0 portieren
Wenn Sie von Sensors HAL 2.0 auf Sensors Multi-HAL 2.0 aktualisieren, muss die HAL Implementierung die folgenden Anforderungen erfüllen.
HAL initialisieren
Sensors HAL 2.0 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, Aktivierungssperren zu erhalten und über dynamische Sensorverbindungen und -trennungen zu benachrichtigen.
Sensorereignisse an die Multi-HAL-Implementierung posten
Anstatt Sensorereignisse über die FMQ zu posten, muss die Sub-HAL Sensorereignisse in die schreiben, wenn Sensorereignisse verfügbar sind.IHalProxyCallback
WAKE_UP-Ereignisse
In Sensors HAL 2.0 kann die HAL den Wakelock für ihre Implementierung verwalten. In Sensors Multi-HAL 2.0 ermöglichen die Sub-HALs der Multi-HAL-Implementierung, Wakelocks zu verwalten, und können eine Aktivierungssperre anfordern, indem sie createScopedWakelock aufrufen.
Eine gesperrte Aktivierungssperre muss erworben und an postEvents übergeben werden, wenn Aktivierungsereignisse an die Multi-HAL-Implementierung gepostet werden.
Dynamische Sensoren
Sensors Multi-HAL 2.0 erfordert, dass 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 Funktion initialize() bereitgestellt wird.
Von Sensors HAL 1.0 portieren
Wenn Sie von Sensors HAL 1.0 auf Sensors Multi-HAL 2.0 aktualisieren, muss die HAL Implementierung die folgenden Anforderungen erfüllen.
HAL initialisieren
Die Funktion initialize() muss unterstützt werden, um den Callback zwischen der Sub-HAL und der Multi-HAL-Implementierung herzustellen.
Verfügbare Sensoren verfügbar machen
In Sensors Multi-HAL 2.0 muss die Funktion getSensorsList() während eines einzelnen Geräteboots denselben Wert zurückgeben, auch bei Neustarts der Sensors-HAL. So kann das Framework versuchen, Sensorverbindungen wiederherzustellen, wenn der Systemserver neu gestartet wird. Der von getSensorsList() zurückgegebene Wert kann sich ändern, nachdem das Gerät neu gestartet wurde.
Sensorereignisse an die Multi-HAL-Implementierung posten
In Sensors HAL 2.0 muss die Sub-HAL anstatt auf den Aufruf von poll() zu warten, proaktiv Sensorereignisse in
IHalProxyCallback
schreiben, wenn Sensorereignisse verfügbar sind.
WAKE_UP-Ereignisse
In Sensors HAL 1.0 kann die HAL den Wakelock für ihre Implementierung verwalten. In Sensors Multi-HAL 2.0 ermöglichen die Sub-HALs der Multi-HAL-Implementierung, Wakelocks zu verwalten, und können eine Wakelock anfordern, indem sie createScopedWakelock aufrufen.
Eine gesperrte Aktivierungssperre muss erworben und an postEvents übergeben werden, wenn Aktivierungsereignisse an die Multi-HAL-Implementierung gepostet werden.
Dynamische Sensoren
In Sensors HAL 1.0 werden dynamische Sensoren über die Funktion poll() zurückgegeben.
Sensors Multi-HAL 2.0 erfordert, dass 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 Funktion initialize() bereitgestellt wird.
Von Sensors Multi-HAL 1.0 portieren
So portieren Sie eine vorhandene Implementierung von Sensors Multi-HAL 1.0, gehen Sie wie folgt vor.
- Achten Sie darauf, dass sich die Sensors-HAL-Konfiguration unter
/vendor/etc/sensors/hals.confbefindet. Dazu müssen Sie möglicherweise die Datei unter/system/etc/sensors/hals.confverschieben. - Entfernen Sie alle Verweise auf
hardware/hardware.hundhardware/sensors.h, da diese für HAL 2.0 nicht unterstützt werden. - Portieren Sie Sub-HALs wie unter Von Sensors HAL 1.0 portieren beschrieben.
- Legen Sie Sensors Multi-HAL 2.0 als designierte HAL fest. Folgen Sie dazu den Schritten 3 und 4 im Abschnitt Sensors Multi-HAL 2.0 implementieren.
Validierung
VTS ausführen
Wenn Sie eine oder mehrere Sub-HALs in Sensors Multi-HAL 2.1 integriert haben, verwenden Sie die Vendor Test Suite (VTS), um sicherzustellen, dass Ihre Sub-HAL Implementierungen alle Anforderungen der Sensors-HAL-Schnittstelle erfüllen.
Wenn VTS auf einem Hostcomputer eingerichtet ist und Sie nur die Sensors-VTS-Tests ausführen möchten, 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-Schicht verwenden, 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 gefälschten Sub-HALs, die
im Einheitentest instanziiert und nicht dynamisch geladen werden. Wenn Sie eine neue Sub-HAL erstellen, sollten diese Tests als Leitfaden dienen, wie Sie Einheitentests hinzufügen, mit denen überprüft wird, ob die neue Sub-HAL ordnungsgemäß implementiert ist.
Führen Sie die folgenden Befehle aus, um die Tests auszuführen:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/testsatest
Mit den gefälschten Sub-HALs testen
Die gefälschten Sub-HALs sind Dummy-Implementierungen der Schnittstelle ISensorsSubHal.
Die Sub-HALs machen verschiedene Sensorlisten verfügbar. Wenn die Sensoren aktiviert sind, posten sie in regelmäßigen Abständen automatisch generierte Sensorereignisse an HalProxy, basierend auf den in einer bestimmten Sensoranfrage angegebenen Intervallen.
Mit den gefälschten Sub-HALs können Sie testen, wie der vollständige Multi-HAL-Code mit anderen Sub-HALs funktioniert, die in das System geladen wurden, und verschiedene Aspekte des Sensors Multi-HAL-Codes testen.
Zwei gefälschte Sub-HALs sind unter
hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ verfügbar.
So erstellen Sie die gefälschten Sub-HALs und übertragen 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/mmaadb 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.soadb 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.soadb 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.soAktualisieren Sie die Sensors-HAL-Konfiguration unter
/vendor/etc/sensors/hals.confmit den Pfaden für die gefälschten Sub-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.soStarten Sie
HalProxyneu und laden Sie die neuen Sub-HALs, die in der Konfiguration aufgeführt sind.adb shell stopadb shell start
Debugging
Entwickler können das Framework mit dem Befehl lshal debuggen. Führen Sie den folgenden Befehl aus, um die Debug-Ausgabe der Sensors-HAL anzufordern:
adb rootadb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Informationen zum aktuellen Status von HalProxy und seinen Sub-HALs werden dann im Terminal ausgegeben. Unten sehen Sie ein Beispiel für die Befehlsausgabe für das HalProxy-Objekt und gefälschte Sub-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 groß ist (1.000 oder mehr), bedeutet das, dass viele Ereignisse noch in das Sensor-Framework geschrieben werden müssen. Das weist darauf hin, dass der Sensordienst blockiert ist oder abgestürzt ist und keine Sensorereignisse verarbeitet oder dass kürzlich ein großer Batch von Sensorereignissen von einer Sub-HAL gepostet wurde.
Wenn die Referenzanzahl des Wakelocks größer als 0 ist, bedeutet das, dass HalProxy einen Wakelock erworben hat. Dieser Wert sollte nur größer als 0 sein, wenn eine ScopedWakelock absichtlich gehalten wird oder wenn Aktivierungsereignisse an HalProxy gesendet wurden und noch nicht vom Sensor-Framework verarbeitet wurden.
Der an die Debug-Methode von HalProxy übergebene Dateideskriptor wird an jede Sub-HAL übergeben. Entwickler müssen die Debug-Methode daher als Teil der Schnittstelle ISensorsSubHal implementieren.