Sensoren Multi-HAL

Das Sensors Multi-HAL ist ein Framework, mit dem Sensoren-HALs zusammen mit anderen Sensor-HALs ausgeführt werden können. Sensors Multi-HAL lädt dynamisch Sensoren-Sub-HALs, die als dynamische Bibliotheken auf der Anbieterpartition gespeichert sind, und stellt ihnen ein Callback-Objekt zur Verfügung, das das Posten von Ereignissen verarbeiten und den Wakelock abrufen 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 Sub-HAL APIs verwenden, die im SubHal-Header 2.1 definiert sind.

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. Informationen zur Implementierung finden Sie unter Sensors Multi-HAL mit Sensors AIDL HAL verwenden.

Unterschied zwischen Sensoren Multi-HAL 2 und Sensoren HAL 2

Die Funktion „Sensors Multi-HAL 2“, die auf Geräten mit Android 10 oder höher verfügbar ist, bietet neben Sensors HAL 2 mehrere Abstraktionen, 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 „initialisieren“ übergibt eine IHalProxyCallback-Klasse anstelle von zwei FMQs und ISensorsCallback.
  • Sub-HALs müssen eine Fehlerbehebungsfunktion implementieren, um in Fehlerberichten Informationen zur Fehlerbehebung zur Verfügung zu stellen.
  • Sub-HALs müssen eine Namensfunktion implementieren, damit der geladene Sub-HAL von anderen untergeordneten HALs unterschieden werden kann.

Der Hauptunterschied zwischen den Sensoren Multi-HAL 2 und den Sensoren HAL 2 besteht in den Funktionen zum Initialisieren. 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. Intern verwaltet das Sensors Multi-HAL alle Interaktionen mit den FMQs, um die zeitnahe Bereitstellung von Sensorereignissen für alle Unter-HALs sicherzustellen. 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. Damit kommt es zu Situationen, in denen der Sensor-FMQ voll ist oder das Android-Sensor-Framework neu gestartet wird und der Sensorstatus zurückgesetzt werden muss. Wenn Ereignisse an die Klasse HalProxy gesendet werden, das Sensor-Framework die Ereignisse jedoch nicht sofort akzeptiert, kann das Sensors Multi-HAL die Ereignisse außerdem in einen Hintergrundthread verschieben, damit die Arbeit über alle Unter-HALs hinweg fortgesetzt werden kann, während auf das Senden 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 sind einige Ressourcen, die Sie interessieren könnten.

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

    Verwenden Sie für Implementierungen mit mehreren HAL 2.0 Version 2.0 von SubHal.h.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/: Mit diesen Einheitentests wird die Implementierung von HalProxy überprüft.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: In dieser Sub-HAL-Beispielimplementierung werden gefälschte Sensoren verwendet, um falsche 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

Um Multi-HAL-Funktionen mit der AIDL HAL-Sensoren zuzulassen, importieren Sie das AIDL-Multi-HAL-Shim-Layer-Modul, das sich in hardware/interfaces/sensors/aidl/default/multihal/ befindet. Das Modul verarbeitet die Konvertierung zwischen HAL-Definitionstypen der AIDL- und HIDL-Sensoren und definiert einen Wrapper um die Multi-HAL-Schnittstelle, wie unter Sensoren Multi-HAL 2.1 implementieren beschrieben. Die AIDL-Multi-HAL-Shimschicht 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. Um diese von der AIDL HAL-Schnittstelle definierten Sensortypen zu verwenden, legen Sie das Feld type in der Struktur SensorInfo in der getSensorsList_2_1()-Implementierung fest. Dies ist sicher, da sich die Sensortypfelder mit Ganzzahlunterstützung der AIDL- und HIDL-Sensoren HAL nicht überschneiden.

Sensoren implementieren Multi-HAL 2.1

So implementieren Sie die Sensoren Multi-HAL 2.1 auf einem neuen Gerät:

  1. Implementieren Sie die ISensorsSubHal-Schnittstelle wie unter 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 Unter-HAL zu erstellen. Gehen Sie beim Hinzufügen des Ziels so vor:

    1. Sorgen Sie dafür, dass das Ziel an eine beliebige Stelle in der Anbieterpartition des Geräts übertragen wird.
    2. Geben Sie in der Konfigurationsdatei unter /vendor/etc/sensors/hals.conf den Pfad zur Bibliothek in einer neuen Zeile ein. Erstellen Sie bei Bedarf die Datei hals.conf.

    Ein Beispiel für einen Android.bp-Eintrag zum Erstellen einer HAL-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 Datei manifest.xml, die die Liste der unterstützten HALs auf dem Gerät enthält.

  5. Entfernen Sie alle android.hardware.sensors-Dienstdateien und service.rc-Dateien 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 untergeordneten HAL und initialisiert es durch Aufrufen von sensorsHalGetSubHal_2_1.

Anschluss von Sensoren Multi-HAL 2.0 zu Multi-HAL 2.1

Für die Portierung von Multi-HAL 2.0 zu Multi-HAL 2.1 müssen Sie die Schnittstelle SubHal implementieren und Ihren Sub-HAL neu kompilieren.

Das sind die Unterschiede zwischen den SubHal-Oberflächen in Version 2.0 und 2.1:

  • IHalProxyCallback verwendet die in Version 2.1 der Spezifikation ISensors.hal erstellten Typen.
  • Die Funktion initialize() übergibt eine neue IHalProxyCallback anstelle derjenigen aus der 2.0-SubHal-Oberfläche.
  • 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 statt sensorsHalGetSubHal verfügbar machen, damit Multi-HAL sie als Unter-HALs der Version 2.1 behandeln können.

Anschluss von Sensoren HAL 2.0

Wenn Sie ein Upgrade von Sensors HAL 2.0 auf Sensors Multi-HAL 2.0 ausführen, 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 senden

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. Ein gesperrter Wakelock muss abgerufen und an postEvents übergeben werden, wenn Wakeup-Ereignisse an die Multi-HAL-Implementierung gesendet werden.

Dynamische Sensoren

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.

Anschluss von Sensoren HAL 1.0

Wenn Sie von Sensors HAL 1.0 auf Sensors Multi-HAL 2.0 upgraden, achten Sie darauf, dass die HAL-Implementierung die folgenden Anforderungen erfüllt.

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 getSensorsList()-Funktion bei einem einzelnen Gerätestart denselben Wert zurückgeben, auch bei HAL-Neustarts von Sensoren. Dadurch kann das Framework versuchen, die Sensorverbindungen bei einem Neustart des Systemservers wiederherzustellen. Der von getSensorsList() zurückgegebene Wert kann sich ändern, nachdem das Gerät neu gestartet wurde.

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 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. Ein gesperrter Wakelock muss abgerufen und an postEvents übergeben werden, wenn Wakeup-Ereignisse an die Multi-HAL-Implementierung gesendet werden.

Dynamische Sensoren

In Sensoren 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.

Anschluss von Sensoren Multi-HAL 1.0

Mit den folgenden Schritten kannst du eine vorhandene Implementierung von Sensors Multi-HAL 1.0 portieren.

  1. Die HAL-Konfiguration für die 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.
  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. Port-Sub-HALs, wie unter Porting von Sensoren Hal 1.0 beschrieben
  4. Legen Sie die Sensoren Multi-HAL 2.0 als gekennzeichneten HAL fest. Folgen Sie dazu den Schritten 3 und 4 im Abschnitt Sensoren Mutli-HAL 2.0 implementieren.

Zertifizierungsstufe

VTS ausführen

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 Anforderungen erfüllen, die von der Sensors-HAL-Schnittstelle festgelegt werden.

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 eines neuen untergeordneten HAL sollten diese Tests als Leitfaden zum Hinzufügen von Einheitentests dienen, mit denen geprüft wird, ob der neue untergeordnete HAL ordnungsgemäß implementiert wurde.

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 fiktiven Sub-HALs sind Dummy-Implementierungen der ISensorsSubHal-Schnittstelle. Die untergeordneten HALs bieten unterschiedliche Listen von Sensoren. Wenn die Sensoren aktiviert sind, senden sie auf der Grundlage der in einer bestimmten Sensoranfrage angegebenen Intervalle regelmäßig automatisch generierte Sensorereignisse an HalProxy.

Mit den fiktiven Sub-HALs können Sie testen, wie der vollständige Multi-HAL-Code mit anderen in das System geladenen untergeordneten HALs funktioniert, und verschiedene Aspekte des Multi-HAL-Codes der Sensoren belasten.

Unter hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ sind zwei gefälschte untergeordnete HALs verfügbar.

Führen Sie die folgenden Schritte aus, um gefälschte untergeordnete HALs zu erstellen und per Push auf ein Gerät zu übertragen:

  1. Führen Sie die folgenden Befehle aus, um die drei verschiedenen fiktiven 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
    
  2. Aktualisieren Sie die HAL-Konfiguration der Sensoren unter /vendor/etc/sensors/hals.conf mit den Pfaden für die fiktiven Unter-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 untergeordneten 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 des Sensoren-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 an das Terminal ausgegeben. Das folgende Beispiel zeigt die Befehlsausgabe für das Objekt HalProxy und fiktive Unter-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, bedeutet dies, dass HalProxy einen Wakelock abgerufen hat. Dieser Wert sollte nur größer als 0 sein, wenn ein ScopedWakelock bewusst gehalten wird oder wenn Aufwachereignisse an HalProxy gesendet und nicht vom Sensor-Framework verarbeitet wurden.

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