Das Sensors Multi-HAL ist ein Framework, mit dem Sensor-HALs parallel zu anderen Sensor-HALs ausgeführt werden können. Das Sensors Multi-HAL lädt dynamisch Sensor-Sub-HALs, die als dynamische Bibliotheken auf der Anbieterpartition gespeichert sind, und stellt ihnen ein Callback-Objekt zur Verfügung, mit dem Ereignisse gepostet und das Wake Lock abgerufen und freigegeben werden kann. Ein Sensors-Sub-HAL ist ein Sensors-HAL, das 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. Es unterstützt das Laden von Sub-HALs, die den Sensortyp Scharnierwinkel verfügbar machen können. Um diesen Sensortyp zu unterstützen, müssen Sub-HALs die in 2.1 SubHal-Header definierten Sub-HAL-APIs verwenden.
Auf Geräten mit Android 13 oder höher, die den Sensors AIDL HAL verwenden, können Sie die Multi-HAL-Shim-Ebene verwenden, um die Multi-HAL-Funktion zu ermöglichen. 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 für Sensors HAL 2, um die Interaktion mit HAL-APIs zu vereinfachen. Sensors Multi-HAL 2 führt die Klasse HalProxy ein, um die Implementierung der Sensors HAL 2-Schnittstelle und der V2_1/SubHal
-Schnittstelle (oder V2_0/SubHal
-Schnittstelle) zu ermöglichen, damit HalProxy
mit Sub-HALs interagieren kann.
Die ISensorsSubHal
-Schnittstelle unterscheidet sich in folgenden Punkten von der 2.1/ISensors.hal
-Schnittstelle (oder 2.0/ISensors.hal
-Schnittstelle):
- Die Methode „initialize“ übergibt eine
IHalProxyCallback
-Klasse anstelle von zwei FMQs undISensorsCallback
. - Unter-HALs müssen eine Debug-Funktion implementieren, um Debugging-Informationen in Fehlerberichten bereitzustellen.
- Unter-HALs müssen eine Namensfunktion implementieren, damit das geladene Unter-HAL von anderen Unter-HALs unterschieden werden kann.
Der Hauptunterschied zwischen Sensors Multi-HAL 2 und Sensors HAL 2 liegt in den Initialisierungsfunktionen. Anstelle von FMQs bietet die IHalProxyCallback
-Schnittstelle zwei Methoden: eine zum Senden von Sensorereignissen an das Sensor-Framework und eine zum Erstellen von Wake Locks. Im Hintergrund verwaltet der Sensors Multi-HAL alle Interaktionen mit den FMQs, um eine rechtzeitige Übermittlung von Sensorereignissen für alle Sub-HALs zu gewährleisten. Es wird dringend empfohlen, dass untergeordnete HALs die Methode createScopedWakelock
verwenden, um die Aufgabe, Zeitüberschreitungen für Wake Locks zu verarbeiten, an das Sensors Multi-HAL zu delegieren und die Verwendung von Wake Locks auf ein gemeinsames Wake Lock für das gesamte Sensors Multi-HAL zu zentralisieren. Dadurch werden Sperr- und Entsperrvorgänge minimiert.
Sensors Multi-HAL 2 bietet auch einige integrierte Sicherheitsfunktionen. Es werden Situationen behandelt, in denen die FMQ des Sensors voll ist oder das Android-Sensor-Framework neu gestartet wird und der Sensorstatus zurückgesetzt werden muss. Wenn Ereignisse in die HalProxy
-Klasse gepostet werden, das Sensor-Framework die Ereignisse aber nicht sofort annehmen kann, kann das 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 Multi-HAL-Code für Sensoren ist unter hardware/interfaces/sensors/common/default/2.X/multihal/
verfügbar.
Hier finden Sie einige 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 vonHalProxy
enthält die gesamte Logik, die zum Multiplexen der Kommunikation zwischen Sub-HALs und dem Sensor-Framework erforderlich ist.SubHal.h
: DieISensorsSubHal
-Schnittstelle definiert die Schnittstelle, die Sub-HALs einhalten müssen, um mitHalProxy
kompatibel zu sein. Die Sub-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 Einheitentests wird dieHalProxy
-Implementierung überprüft.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: In dieser Beispiel-Sub-HAL-Implementierung werden gefälschte Sensoren verwendet, um gefälschte Daten zu generieren. 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 Sensors AIDL HAL verwenden
Wenn Sie die Multi-HAL-Funktion mit der Sensors AIDL HAL zulassen möchten, importieren Sie das AIDL-Multi-HAL-Shim-Layer-Modul, das sich unter hardware/interfaces/sensors/aidl/default/multihal/ befindet. Das Modul übernimmt die Konvertierung zwischen AIDL- und HIDL-Sensoren-HAL-Definitionstypen und definiert einen Wrapper für die Multi-HAL-Schnittstelle, die in 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-Ebene können Sie die Sensortypen „Head Tracker“ und „IMU mit eingeschränkter 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 getSensorsList_2_1()
-Implementierung fest. Das ist sicher, da sich die Felder für den sensortypbasierten Integer der AIDL- und HIDL-Sensoren 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
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 das neu implementierte Sub-HAL zu erstellen. Beim Hinzufügen des Ziels:- Das Ziel muss auf der Anbieterpartition des Geräts platziert werden.
- 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 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 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 Starten wird HalProxy
gestartet, sucht nach dem neu implementierten Sub-HAL und initialisiert es durch Aufrufen von sensorsHalGetSubHal_2_1
.
Portierung von Sensors Multi-HAL 2.0 zu Multi-HAL 2.1
Wenn Sie von Multi-HAL 2.0 zu Multi-HAL 2.1 portieren möchten, implementieren Sie die Schnittstelle SubHal
und kompilieren Sie Ihre Sub-HAL neu.
Das sind die Unterschiede zwischen den SubHal
-Schnittstellen 2.0 und 2.1:
IHalProxyCallback
verwendet die Typen, die in Version 2.1 derISensors.hal
-Spezifikation erstellt wurden.- Die Funktion
initialize()
übergibt ein neuesIHalProxyCallback
anstelle desIHalProxyCallback
aus der 2.0-SchnittstelleSubHal
. - Unter-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. - Unter-HALs müssen
sensorsHalGetSubHal_2_1
anstelle vonsensorsHalGetSubHal
verfügbar machen, damit sie vom Multi-HAL als Unter-HALs der Version 2.1 behandelt werden.
Port von Sensors HAL 2.0
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 zum Posten von Sensorereignissen, zum Abrufen von Wake Locks und zum Benachrichtigen über dynamische Sensorverbindungen und ‑trennungen verwendet werden muss.
Sensorereignisse an die Multi-HAL-Implementierung senden
Anstatt Sensorereignisse über die FMQ zu posten, muss die Sub-HAL Sensorereignisse in die IHalProxyCallback
schreiben, wenn Sensorereignisse verfügbar sind.
WAKE_UP-Ereignisse
In Sensors HAL 2.0 kann die HAL das Wake Lock für ihre Implementierung verwalten. In Sensors Multi-HAL 2.0 können die Sub-HALs die Multi-HAL-Implementierung verwalten und einen Wakelock anfordern, indem sie createScopedWakelock
aufrufen.
Eine gesperrte Wake Lock mit Bereich muss abgerufen und an postEvents
übergeben werden, wenn Weckereignisse an die Multi-HAL-Implementierung gesendet 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.
Port von Sensors HAL 1.0
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 bereitstellen
In Sensors Multi-HAL 2.0 muss die Funktion getSensorsList()
während eines einzelnen Gerätestarts denselben Wert zurückgeben, auch bei Neustarts des Sensors HAL. Dadurch 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 Sensors HAL 2.0 muss das Sub-HAL Sensorereignisse proaktiv in IHalProxyCallback
schreiben, sobald sie verfügbar sind, anstatt auf den Aufruf von poll()
zu warten.
WAKE_UP-Ereignisse
In Sensors HAL 1.0 kann die HAL das Wake Lock für ihre Implementierung verwalten. In Sensors Multi-HAL 2.0 können die Sub-HALs Wakelocks verwalten und einen Wakelock anfordern, indem sie createScopedWakelock
aufrufen.
Eine gesperrte Wake Lock mit Bereich muss abgerufen und an postEvents
übergeben werden, wenn Weckereignisse an die Multi-HAL-Implementierung gesendet 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.
Port von Sensors Multi-HAL 1.0
So portieren Sie eine vorhandene Implementierung von Sensors Multi-HAL 1.0:
- Prüfen Sie, ob sich die HAL-Konfiguration der Sensoren unter
/vendor/etc/sensors/hals.conf
befindet. Dazu müssen Sie möglicherweise die Datei unter/system/etc/sensors/hals.conf
verschieben. - Entfernen Sie alle Verweise auf
hardware/hardware.h
undhardware/sensors.h
, da diese für HAL 2.0 nicht unterstützt werden. - Portieren Sie die Sub-HALs wie unter Von Sensors HAL 1.0 portieren beschrieben.
- Legen Sie Sensors Multi-HAL 2.0 als die vorgesehene HAL fest, indem Sie die Schritte 3 und 4 im Abschnitt Sensors Multi-HAL 2.0 implementieren ausführen.
Zertifizierungsstufe
VTS ausführen
Wenn Sie ein 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 VTS-Tests für Sensoren 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 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 Unittests in HalProxy_test.cpp
testen HalProxy
mit gefälschten Sub-HALs, die im Unittest instanziiert und nicht dynamisch geladen werden. Beim Erstellen eines neuen Sub-HAL sollten diese Tests als Leitfaden dafür dienen, wie Unittests hinzugefügt werden, die überprüfen, ob das neue Sub-HAL richtig implementiert ist.
Führen Sie die Tests mit folgenden Befehlen aus:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Mit den gefälschten untergeordneten HALs testen
Die gefälschten Sub-HALs sind Dummy-Implementierungen der ISensorsSubHal
-Schnittstelle.
Die untergeordneten HALs stellen verschiedene Sensorlisten zur Verfügung. Wenn die Sensoren aktiviert sind, werden automatisch generierte Sensorereignisse in regelmäßigen Abständen an HalProxy
gesendet. Die Intervalle werden in einer bestimmten Sensoranfrage angegeben.
Mit den gefälschten Sub-HALs kann getestet werden, wie der vollständige Multi-HAL-Code mit anderen im System geladenen Sub-HALs funktioniert, und verschiedene Aspekte des Sensors Multi-HAL-Codes können getestet werden.
Unter hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
sind zwei gefälschte Sub-HALs verfügbar.
So erstellen und übertragen Sie die gefälschten Sub-HALs auf ein Gerät:
Führen Sie die folgenden Befehle aus, um die drei verschiedenen Fake-Sub-HALs zu erstellen und per Push 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 Sensors HAL-Konfiguration unter
/vendor/etc/sensors/hals.conf
mit 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.so
Starten Sie
HalProxy
neu und laden Sie die neuen Sub-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 Debug-Ausgabe 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 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 darauf warten, in das Sensors-Framework geschrieben zu werden. Dies weist darauf hin, dass der Sensordienst blockiert ist oder 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 Wake Locks größer als 0
ist, hat HalProxy
einen Wake Lock erhalten. Dieser Wert sollte nur größer als 0
sein, wenn ein ScopedWakelock
absichtlich zurückgehalten wird oder wenn Weckereignisse an HalProxy
gesendet wurden und nicht vom Sensor-Framework verarbeitet wurden.
Der an die Debug-Methode von HalProxy
übergebene Dateideskriptor wird an jede untergeordnete HAL übergeben. Entwickler müssen die Debug-Methode daher als Teil der ISensorsSubHal
-Schnittstelle implementieren.