Sensoren Multi-HAL

Das Sensors Multi-HAL ist ein Framework, das es Sensor-HALs ermöglicht, neben anderen Sensor-HALs zu laufen. Der Sensors Multi-HAL lädt dynamisch Sub-HALs von Sensoren, die als dynamische Bibliotheken auf der Herstellerpartition gespeichert sind, und gibt ihnen ein Callback-Objekt, das das Posten von Ereignissen sowie das Erlangen und Freigeben der Wake-Sperre verarbeiten kann. Ein Sensor-Sub-HAL ist ein Sensor-HAL, der in ein gemeinsames Objekt auf der Herstellerpartition integriert 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 Sub-HALs unterstützt, die den Scharnierwinkelsensortyp offenlegen können. Um diesen Sensortyp zu unterstützen, müssen Sub-HALs die im 2.1 SubHal-Header definierten Sub-HAL-APIs verwenden.

Für Geräte mit Android 13 oder höher, die die Sensoren AIDL HAL verwenden, können Sie die Multi-HAL-Shim-Schicht verwenden, um Multi-HAL-Fähigkeit zu ermöglichen. Einzelheiten zur Implementierung finden Sie unter Verwenden des Sensors Multi-HAL mit dem Sensors AIDL HAL .

Unterschied zwischen Sensoren Multi-HAL 2 und Sensoren HAL 2

Sensors Multi-HAL 2, verfügbar auf Geräten mit Android 10 oder höher, führt zusätzlich zu Sensors HAL 2 mehrere Abstraktionen ein, um die Interaktion mit HAL-APIs zu vereinfachen. Sensors Multi-HAL 2 führt die HalProxy- Klasse ein, die die Implementierung der Sensors HAL 2-Schnittstelle und der V2_1/SubHal Schnittstelle (oder V2_0/SubHal ) übernimmt, damit HalProxy mit Sub-HALs interagieren kann.

Die Schnittstelle ISensorsSubHal unterscheidet sich von der Schnittstelle 2.1/ISensors.hal (oder 2.0/ISensors.hal ) in folgenden Punkten:

  • Die Initialisierungsmethode übergibt eine IHalProxyCallback Klasse anstelle von zwei FMQs und ISensorsCallback .
  • 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. Anstatt FMQs bereitzustellen, bietet die IHalProxyCallback Schnittstelle zwei Methoden: eine Methode zum Senden von Sensorereignissen an das Sensor-Framework und eine Methode zum Erstellen von Wake-Locks. Unter der Haube verwaltet der Sensors Multi-HAL alle Interaktionen mit den FMQs, um eine rechtzeitige Bereitstellung von Sensorereignissen für alle Sub-HALs sicherzustellen. Es wird dringend empfohlen, dass Sub-HALs die Methode createScopedWakelock verwenden, um die Last der Zeitüberschreitung von Wake-Locks an den Sensors Multi-HAL zu delegieren und die Wake-Lock-Nutzung auf einen gemeinsamen Wake-Lock für den gesamten Sensors Multi-HAL zu zentralisieren, wodurch das Sperren und Entsperren minimiert wird Anrufe.

Sensoren Multi-HAL 2 verfügt außerdem über einige integrierte Sicherheitsfunktionen. Es behandelt Situationen, in denen der Sensor-FMQ voll ist oder das Android-Sensor-Framework neu startet und der Sensorstatus zurückgesetzt werden muss. Wenn außerdem Ereignisse in der HalProxy Klasse gepostet werden, das Sensor-Framework die Ereignisse jedoch nicht sofort akzeptieren kann, kann der Sensors Multi-HAL die Ereignisse in einen Hintergrundthread verschieben, damit die Arbeit über alle Sub-HALs hinweg fortgesetzt werden kann, während auf die Ereignisse gewartet wird gepostet werden.

Quellcode und Referenzimplementierung

Der Multi-HAL-Code für alle Sensoren ist unter hardware/interfaces/sensors/common/default/2.X/multihal/ verfügbar. Hier finden Sie Hinweise auf einige Ressourcen.

  • HalProxy.h : Das HalProxy Objekt wird vom Multi-HAL des Sensors instanziiert und übernimmt die Weitergabe von Daten von den Sub-HALs an das Sensor-Framework.
  • HalProxy.cpp : Die Implementierung von HalProxy enthält die gesamte Logik, die zum Multiplexen der Kommunikation zwischen Sub-HALs und dem Sensor-Framework erforderlich ist.
  • SubHal.h : Die ISensorsSubHal Schnittstelle definiert die Schnittstelle, der Sub-HALs folgen müssen, um mit HalProxy kompatibel zu sein. Die Sub-HAL implementiert die Methode initialize, sodass das HalProxyCallback Objekt für postEvents und createScopedWakelock 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/ : Diese Unit-Tests überprüfen die HalProxy Implementierung.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ : Diese beispielhafte Sub-HAL-Implementierung verwendet gefälschte Sensoren, um gefälschte Daten zu generieren. Nützlich zum 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:

Verwenden Sie die Sensoren Multi-HAL mit den Sensoren AIDL HAL

Um die Multi-HAL-Fähigkeit mit dem Sensors AIDL HAL zu ermöglichen, importieren Sie das AIDL Multi-HAL Shim-Layer-Modul, das sich in hardware/interfaces/sensors/aidl/default/multihal/ befindet. Das Modul übernimmt die Konvertierung zwischen den HAL-Definitionstypen von AIDL- und HIDL-Sensoren und definiert einen Wrapper um die Multi-HAL-Schnittstelle, die in Implementing Sensors Multi-HAL 2.1 beschrieben wird. Die AIDL-Multi-HAL-Shimschicht ist mit Geräten kompatibel, die Sensors Multi-HAL 2.1 implementieren.

Mit der AIDL-Multi-HAL-Shim-Schicht können Sie die Head-Tracker- und IMU-Sensortypen mit begrenzter Achse im Sensors AIDL HAL freilegen. Um diese von der AIDL-HAL-Schnittstelle definierten Sensortypen zu verwenden, legen Sie das type in der SensorInfo Struktur in der getSensorsList_2_1() Implementierung fest. Dies ist sicher, da sich die ganzzahligen Sensortypfelder der AIDL- und HIDL-Sensoren HAL nicht überlappen.

Implementieren Sie Sensoren Multi-HAL 2.1

Um Sensors Multi-HAL 2.1 auf einem neuen Gerät zu implementieren, befolgen Sie diese Schritte:

  1. Implementieren Sie die ISensorsSubHal Schnittstelle wie in SubHal.h beschrieben.
  2. Implementieren Sie die Methode sensorsHalGetSubHal_2_1 in SubHal.h .
  3. Fügen Sie ein cc_library_shared -Ziel hinzu, um die neu implementierte Sub-HAL zu erstellen. Beim Hinzufügen des Ziels:

    1. Stellen Sie sicher, dass das Ziel irgendwo auf der Herstellerpartition des Geräts verschoben wird.
    2. 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 Datei hals.conf .

    Einen Beispieleintrag für Android.bp zum Erstellen einer Sub-HAL-Bibliothek finden Sie hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp .

  4. Entfernen Sie alle android.hardware.sensors Einträge aus der Datei manifest.xml , die die Liste der unterstützten HALs auf dem Gerät enthält.

  5. Entfernen Sie alle Dateien android.hardware.sensors service und service.rc aus der Datei device.mk und fügen Sie android.hardware.sensors@2.1-service.multihal und android.hardware.sensors@2.1-service.multihal.rc zu PRODUCT_PACKAGES hinzu.

Beim Booten startet HalProxy , sucht nach dem neu implementierten Sub-HAL und initialisiert es durch Aufrufen von sensorsHalGetSubHal_2_1 .

Port von Sensors Multi-HAL 2.0 auf Multi-HAL 2.1

Um von Multi-HAL 2.0 auf Multi-HAL 2.1 zu portieren, implementieren Sie die SubHal Schnittstelle und kompilieren Sie Ihr Sub-HAL neu.

Dies sind die Unterschiede zwischen den SubHal Schnittstellen 2.0 und 2.1:

  • IHalProxyCallback verwendet die in Version 2.1 der ISensors.hal Spezifikation erstellten Typen.
  • Die Funktion initialize() übergibt einen neuen IHalProxyCallback anstelle des von der SubHal Schnittstelle 2.0
  • Sub-HALs müssen getSensorsList_2_1 und injectSensorData_2_1 anstelle von getSensorsList und injectSensorData implementieren, da diese Methoden die neuen Typen verwenden, die in Version 2.1 der ISensors.hal Spezifikation hinzugefügt wurden.
  • Sub-HALs müssen sensorsHalGetSubHal_2_1 “ und nicht sensorsHalGetSubHal verfügbar machen, damit die Multi-HAL sie als Sub-HALs der Version 2.1 behandelt.

Port von Sensors HAL 2.0

Stellen Sie beim Upgrade von Sensors HAL 2.0 auf Sensors Multi-HAL 2.0 sicher, dass die HAL-Implementierung die folgenden Anforderungen erfüllt.

Initialisieren Sie die HAL

Sensoren HAL 2.0 verfügt über eine Initialisierungsfunktion, die es dem Sensordienst ermöglicht, FMQs und einen dynamischen Sensorrückruf zu übergeben. In Sensors Multi-HAL 2.0 übergibt die Funktion initialize() einen einzelnen Rückruf, der verwendet werden muss, um Sensorereignisse zu veröffentlichen, Wakelocks zu erhalten und über dynamische Sensorverbindungen und -trennungen zu benachrichtigen.

Veröffentlichen Sie Sensorereignisse in der Multi-HAL-Implementierung

Anstatt Sensorereignisse über den FMQ zu veröffentlichen, muss der Sub-HAL Sensorereignisse in den IHalProxyCallback schreiben, wenn Sensorereignisse verfügbar sind.

WAKE_UP-Ereignisse

In Sensors HAL 2.0 kann der HAL die Wake-Sperre 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 den Erwerb eines Wakelocks anfordern. Beim Posten von Weckereignissen an die Multi-HAL-Implementierung muss eine gesperrte Wecksperre mit Gültigkeitsbereich erworben und an postEvents übergeben werden.

Dynamische Sensoren

Sensors Multi-HAL 2.0 erfordert, dass onDynamicSensorsConnected und onDynamicSensorsDisconnected in IHalProxyCallback immer dann aufgerufen werden, wenn sich dynamische Sensorverbindungen ändern. Diese Rückrufe sind als Teil des IHalProxyCallback -Zeigers verfügbar, der über die Funktion initialize() bereitgestellt wird.

Port von Sensoren HAL 1.0

Stellen Sie beim Upgrade von Sensors HAL 1.0 auf Sensors Multi-HAL 2.0 sicher, dass die HAL-Implementierung die folgenden Anforderungen erfüllt.

Initialisieren Sie die HAL

Die Funktion initialize() muss unterstützt werden, um den Rückruf zwischen der Sub-HAL- und der Multi-HAL-Implementierung einzurichten.

Verfügbare Sensoren freilegen

In Sensors Multi-HAL 2.0 muss die Funktion getSensorsList() während eines einzelnen Gerätestarts denselben Wert zurückgeben, auch bei HAL-Neustarts aller Sensoren. Dadurch kann das Framework versuchen, Sensorverbindungen wiederherzustellen, wenn der Systemserver neu startet. Der von getSensorsList() zurückgegebene Wert kann sich ändern, nachdem das Gerät einen Neustart durchführt.

Veröffentlichen Sie Sensorereignisse in der Multi-HAL-Implementierung

Anstatt auf den Aufruf von poll() zu warten, muss der Sub-HAL in Sensors HAL 2.0 Sensorereignisse proaktiv in IHalProxyCallback schreiben, wann immer Sensorereignisse verfügbar sind.

WAKE_UP-Ereignisse

In Sensors HAL 1.0 kann der HAL die Wake-Sperre 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 den Erwerb eines Wakelocks anfordern. Beim Posten von Weckereignissen an die Multi-HAL-Implementierung muss eine gesperrte Wecksperre mit Gültigkeitsbereich erworben und an postEvents übergeben 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 immer dann aufgerufen werden, wenn sich dynamische Sensorverbindungen ändern. Diese Rückrufe sind als Teil des IHalProxyCallback -Zeigers verfügbar, der über die Funktion initialize() bereitgestellt wird.

Port von Sensors Multi-HAL 1.0

Führen Sie die folgenden Schritte aus, um eine vorhandene Implementierung von Sensors Multi-HAL 1.0 zu portieren.

  1. Stellen Sie sicher, dass sich die HAL-Konfiguration des Sensors unter /vendor/etc/sensors/hals.conf. Dies erfordert möglicherweise das Verschieben der Datei unter /system/etc/sensors/hals.conf .
  2. Entfernen Sie alle Verweise auf hardware/hardware.h und hardware/sensors.h da diese für HAL 2.0 nicht unterstützt werden.
  3. Portieren Sie Sub-HALs wie unter „Portieren von Sensoren Hal 1.0“ beschrieben.
  4. Legen Sie Sensors Multi-HAL 2.0 als vorgesehenen HAL fest, indem Sie die Schritte 3 und 4 im Abschnitt „Implementieren von Sensors Mutli-HAL 2.0“ ausführen .

Validierung

Führen Sie VTS aus

Wenn Sie einen oder mehrere Sub-HALs mit Sensors Multi-Hal 2.1 integriert haben, verwenden Sie die Vendor Test Suite (VTS) , um sicherzustellen, dass Ihre Sub-HAL-Implementierungen alle von der Sensors HAL-Schnittstelle festgelegten Anforderungen erfüllen.

Um nur die VTS-Tests der Sensoren auszuführen, 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

Führen Sie Unit-Tests durch

Die Unit-Tests in HalProxy_test.cpp testen HalProxy mit gefälschten Sub-HALs, die im Unit-Test instanziiert und nicht dynamisch geladen werden. Beim Erstellen eines neuen Sub-HAL sollten diese Tests als Leitfaden für das Hinzufügen von Komponententests dienen, die überprüfen, ob das neue Sub-HAL ordnungsgemäß implementiert ist.

Um die Tests auszuführen, führen Sie die folgenden Befehle aus:

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

Testen Sie mit den gefälschten Sub-HALs

Die gefälschten Sub-HALs sind Dummy-Implementierungen der ISensorsSubHal Schnittstelle. Die Sub-HALs stellen unterschiedliche Listen von Sensoren bereit. Wenn die Sensoren aktiviert sind, senden sie basierend auf den in einer bestimmten Sensoranforderung angegebenen Intervallen regelmäßig automatisch generierte Sensorereignisse an HalProxy .

Die gefälschten Sub-HALs können verwendet werden, um zu testen, wie der vollständige Multi-HAL-Code mit anderen in das System geladenen Sub-HALs funktioniert, und um verschiedene Aspekte des Sensors Multi-HAL-Codes hervorzuheben.

Zwei gefälschte Sub-HALs sind unter hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ verfügbar.

Führen Sie die folgenden Schritte aus, um die gefälschten Sub-HALs zu erstellen und auf ein Gerät zu übertragen:

  1. 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
    
  2. Aktualisieren Sie die HAL-Konfiguration der Sensoren 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
    
  3. Starten Sie HalProxy neu und laden Sie die neuen Sub-HALs, die in der Konfiguration aufgeführt sind.

    adb shell stop
    adb shell start
    

Debuggen

Entwickler können das Framework mithilfe des Befehls lshal debuggen. Um die Debug-Ausgabe des Sensors HAL anzufordern, führen Sie den folgenden Befehl aus:

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

Anschließend werden Informationen über den aktuellen Zustand von HalProxy und seinen Sub-HALs an das 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 eine große Zahl ist (1000 oder mehr), weist dies darauf hin, dass viele Ereignisse darauf warten, in das Sensor-Framework geschrieben zu werden. Dies weist darauf hin, dass der Sensordienst blockiert ist oder abgestürzt ist und keine Sensorereignisse verarbeitet, oder dass kürzlich eine große Menge an Sensorereignissen von einem Sub-HAL gepostet wurde.

Wenn die Anzahl der Wake-Lock-Referenzen größer als 0 ist, bedeutet dies, dass HalProxy einen Wake-Lock erworben hat. Dieser sollte nur größer als 0 sein, wenn absichtlich ein ScopedWakelock gehalten wird oder wenn Wakeup-Ereignisse an HalProxy gesendet wurden und nicht vom Sensor-Framework verarbeitet wurden.

Der an die Debug-Methode von HalProxy übergebene Dateideskriptor wird an jeden Sub-HAL übergeben, sodass Entwickler die Debug-Methode als Teil der ISensorsSubHal Schnittstelle implementieren müssen.