Sensoren – Multi-HAL

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 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. 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: Das HalProxy-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 von HalProxy enthält die gesamte Logik, die für das Multiplexen der Kommunikation zwischen Sub-HALs und dem Sensor-Framework erforderlich ist.
  • SubHal.h: Die Schnittstelle ISensorsSubHal definiert die Schnittstelle, die Sub-HALs einhalten müssen, um mit HalProxy kompatibel zu sein. Die Sub-HAL implementiert die Methode „initialize“, damit das HalProxyCallback-Objekt für postEvents und createScopedWakelock verwendet 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 die HalProxy-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

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:

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

    1. Achten Sie darauf, dass das Ziel an einen Ort auf der Anbieterpartition des Geräts übertragen 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.

    Ein Beispiel für einen Android.bp Eintrag zum Erstellen einer Sub-HAL-Bibliothek finden Sie unter hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.

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

  5. Entfernen Sie alle android.hardware.sensors-Dienst- und service.rc-Dateien aus der device.mk-Datei 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 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:

  • IHalProxyCallback verwendet die in Version 2.1 der Spezifikation ISensors.hal erstellten Typen.
  • Die Funktion initialize() übergibt ein neues IHalProxyCallback anstelle des aus der Schnittstelle SubHal 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 Spezifikation ISensors.hal hinzugefügt wurden.
  • Sub-HALs müssen sensorsHalGetSubHal_2_1 anstelle von sensorsHalGetSubHal verfü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.

  1. Achten Sie darauf, dass sich die Sensors-HAL-Konfiguration unter /vendor/etc/sensors/hals.conf befindet. Dazu müssen Sie möglicherweise die Datei unter /system/etc/sensors/hals.conf verschieben.
  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 Von Sensors HAL 1.0 portieren beschrieben.
  4. 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/tests
atest

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:

  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 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
    
  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

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 root
adb 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.