Die Sensors Hardware Abstraction Layer (HAL) ist die Schnittstelle zwischen dem Android-Sensor-Framework und den Sensoren eines Geräts, z. B. einem Beschleunigungsmesser oder Gyroskop. Die Sensors HAL definiert die Funktionen, die implementiert werden müssen, damit das Framework die Sensoren steuern kann.
Die Sensors AIDL HAL ist in Android 13 und höher für neue und aktualisierte Geräte verfügbar. Die Sensors AIDL HAL, die auf Sensors HAL 2.1 basiert, verwendet die AIDL HAL-Schnittstelle und stellt die Sensortypen „Head Tracker“ und „IMU mit begrenzter Achse“ bereit.
AIDL HAL-Schnittstelle
Die Hauptquelle für die Dokumentation der Sensors AIDL HAL befindet sich in der HAL-Definition unter hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl.
Die Sensoren-AIDL HAL implementieren
Um die Sensors AIDL HAL zu implementieren, muss ein Objekt die ISensors
-Schnittstelle erweitern und alle Funktionen implementieren, die in hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl definiert sind.
HAL initialisieren
Die Sensors HAL muss vom Android-Sensor-Framework initialisiert werden, bevor sie verwendet werden kann. Das Framework ruft die initialize()
-Funktion auf, um der Sensors HAL drei Parameter zur Verfügung zu stellen: zwei FMQ-Beschreibungen und einen Verweis auf ein ISensorsCallback
-Objekt.
Die HAL verwendet den ersten Descriptor, um die Ereignis-FMQ zu erstellen, mit der Sensorereignisse in das Framework geschrieben werden. Der HAL verwendet den zweiten Deskriptor, um die Wakelock-FMQ-Funktion zu erstellen, die zur Synchronisierung verwendet wird, wenn der HAL seinen Wakelock für WAKE_UP
-Sensorereignisse freigibt. Die HAL muss einen Verweis auf das ISensorsCallback
-Objekt speichern, damit alle erforderlichen Callback-Funktionen aufgerufen werden können.
Die Funktion initialize()
muss die erste Funktion sein, die bei der Initialisierung der Sensors HAL aufgerufen wird.
Verfügbare Sensoren bereitstellen
Mit der Funktion getSensorsList()
können Sie eine Liste aller verfügbaren statischen Sensoren auf dem Gerät abrufen. Diese Funktion gibt eine Liste von Sensoren zurück, die jeweils durch ihren eindeutigen Handle identifiziert werden. Der Handle für einen bestimmten Sensor darf sich nicht ändern, wenn der Prozess, der die Sensors HAL hostet, neu gestartet wird. Aliasse können sich nach einem Neustart des Geräts oder des Systemservers ändern.
Wenn mehrere Sensoren denselben Sensortyp und dieselbe Weckeigenschaft haben, wird der erste Sensor in der Liste als Standardsensor bezeichnet und an Apps zurückgegeben, die die Funktion getDefaultSensor(int sensorType, bool wakeUp)
verwenden.
Stabilität der Liste der Sensoren
Wenn nach einem Neustart der HAL für Sensoren die von getSensorsList()
zurückgegebenen Daten eine erhebliche Änderung im Vergleich zur Sensorliste anzeigen, die vor dem Neustart abgerufen wurde, löst das Framework einen Neustart der Android-Laufzeit aus. Zu den wesentlichen Änderungen an der Sensorliste gehören Fälle, in denen ein Sensor mit einem bestimmten Handle fehlt oder seine Attribute geändert wurden, oder in denen neue Sensoren eingeführt werden. Der Neustart der Android-Laufzeit hat zwar eine Störung für den Nutzer, ist aber erforderlich, weil das Android-Framework den Android API-Vertrag nicht mehr erfüllen kann, sodass sich statische (nicht dynamische) Sensoren während der Lebensdauer einer App nicht ändern. Dadurch kann das Framework unter Umständen auch keine aktiven Sensoranfragen von Apps neu einrichten. Daher wird HAL-Anbietern empfohlen, vermeidbare Änderungen an der Sensorliste zu vermeiden.
Um stabile Sensorgriffe zu gewährleisten, muss der HAL einen bestimmten physischen Sensor im Gerät deterministisch seinem Griff zuordnen. Die HAL-Schnittstelle für Sensoren schreibt zwar keine bestimmte Implementierung vor, Entwickler haben aber eine Reihe von Möglichkeiten, diese Anforderung zu erfüllen.
Die Sensorliste kann beispielsweise anhand einer Kombination der festen Attribute der einzelnen Sensoren wie Anbieter, Modell und Sensortyp sortiert werden. Eine weitere Option basiert darauf, dass die statischen Sensoren des Geräts in der Hardware festgelegt sind. Daher muss die HAL wissen, wann die Initialisierung aller erwarteten Sensoren abgeschlossen ist, bevor sie von getSensorsList()
zurückkehrt. Diese Liste der erwarteten Sensoren kann in die HAL-Binärdatei kompiliert oder in einer Konfigurationsdatei im Dateisystem gespeichert werden. Anhand der Reihenfolge der Erscheinung können stabile Handles abgeleitet werden. Die beste Lösung hängt von den spezifischen Implementierungsdetails Ihrer HAL ab. Die Hauptanforderung besteht jedoch darin, dass sich die Sensor-Handle bei HAL-Neustarts nicht ändern.
Sensoren konfigurieren
Bevor ein Sensor aktiviert wird, muss er mithilfe der Funktion batch()
mit einer Stichprobendauer und einer maximalen Berichtslatenz konfiguriert werden.
Ein Sensor muss ohne den Verlust von Sensordaten jederzeit mit batch()
neu konfiguriert werden können.
Stichprobenzeiträume
Die Bedeutung des Messzeitraums hängt vom konfigurierten Sensortyp ab:
- Kontinuierlich: Sensorereignisse werden kontinuierlich generiert.
- Bei Änderung: Ereignisse werden nicht schneller als in der Stichprobenzeit generiert. Wenn sich der Messwert nicht ändert, kann die Rate auch langsamer sein.
- Einmalig: Der Stichprobenzeitraum wird ignoriert.
- Speziell: Weitere Informationen finden Sie unter Sensortypen.
Weitere Informationen zur Interaktion zwischen einem Messzeitraum und den Berichtsmodi eines Sensors finden Sie unter Berichtsmodi.
Maximale Berichtslatenz
Die maximale Berichtslatenz legt die maximale Zeit in Nanosekunden fest, die Ereignisse verzögert und im Hardware-FIFO gespeichert werden können, bevor sie über den HAL in den Ereignis-FMQ geschrieben werden, während der SoC aktiv ist.
Ein Wert von null bedeutet, dass die Ereignisse sobald sie gemessen werden, gemeldet werden müssen. Dabei wird der FIFO entweder komplett übersprungen oder geleert, sobald ein Ereignis vom Sensor im FIFO vorhanden ist.
Ein Beschleunigungsmesser, der mit 50 Hz aktiviert ist und eine maximale Berichtslatenz von null hat, löst beispielsweise 50 Mal pro Sekunde Unterbrechungen aus, wenn das SoC aktiv ist.
Wenn die maximale Berichtslatenz größer als null ist, müssen Sensorereignisse nicht sofort gemeldet werden, wenn sie erkannt werden. Ereignisse können vorübergehend im Hardware-FIFO gespeichert und in Batches gemeldet werden, solange kein Ereignis um mehr als die maximale Berichtslatenz verzögert wird. Alle Ereignisse seit dem letzten Batch werden auf einmal erfasst und zurückgegeben. Dadurch werden weniger Unterbrechungen an das SoC gesendet und das SoC kann in einen Modus mit geringerer Leistung wechseln, während der Sensor Daten erfasst und in Batches aufnimmt.
Jedem Ereignis ist ein Zeitstempel zugeordnet. Eine Verzögerung bei der Meldung eines Ereignisses darf sich nicht auf den Zeitstempel des Ereignisses auswirken. Der Zeitstempel muss korrekt sein und dem Zeitpunkt entsprechen, zu dem das Ereignis tatsächlich aufgetreten ist, nicht dem Zeitpunkt, zu dem es gemeldet wurde.
Weitere Informationen und Anforderungen zum Melden von Sensorereignissen mit einer nicht nullwertigen maximalen Meldelatenz finden Sie unter Batchverarbeitung.
Sensoren aktivieren
Das Framework aktiviert und deaktiviert Sensoren mithilfe der Funktion activate()
.
Bevor ein Sensor aktiviert werden kann, muss das Framework ihn zuerst mit batch()
konfigurieren.
Nachdem ein Sensor deaktiviert wurde, dürfen keine weiteren Sensorereignisse von diesem Sensor in die Ereignis-FMQ geschrieben werden.
Spülsensoren
Wenn ein Sensor für Batch-Sensordaten konfiguriert ist, kann das Framework durch Aufrufen von flush()
ein sofortiges Ausgeben der Batch-Sensorereignisse erzwingen. Dadurch werden die gebatchten Sensorereignisse für den angegebenen Sensor-Handle sofort in die Ereignis-FMQ geschrieben. Die Sensors HAL muss am Ende der Sensorereignisse, die als Ergebnis eines Aufrufs von flush()
geschrieben werden, ein Ereignis vom Typ „Flush complete“ anhängen.
Das Leeren erfolgt asynchron. Das bedeutet, dass diese Funktion sofort zurückgeben muss. Wenn in der Implementierung ein einzelner FIFO für mehrere Sensoren verwendet wird, wird dieser FIFO geleert und das Ereignis „Flush complete“ wird nur für den angegebenen Sensor hinzugefügt.
Wenn der angegebene Sensor keinen FIFO hat (keine Pufferung möglich) oder der FIFO zum Zeitpunkt des Aufrufs leer war, muss flush()
trotzdem erfolgreich sein und ein Ereignis vom Typ „Flush complete“ für diesen Sensor senden. Dies gilt für alle Sensoren mit Ausnahme von One-Shot-Sensoren.
Wenn flush()
für einen Einmalsensor aufgerufen wird, muss flush()
BAD_VALUE
zurückgeben und kein Ereignis vom Typ „Flush complete“ generieren.
Sensorereignisse in die FMQ schreiben
Die Ereignis-FMQ wird vom Sensors-HAL verwendet, um Sensorereignisse in das Android-Sensor-Framework zu übertragen.
Das Ereignis-FMQ ist ein synchronisiertes FMQ. Das bedeutet, dass jeder Versuch, mehr Ereignisse in das FMQ zu schreiben, als der verfügbare Speicherplatz zulässt, zu einem fehlgeschlagenen Schreibvorgang führt. In diesem Fall sollte der HAL bestimmen, ob die aktuelle Gruppe von Ereignissen als zwei kleinere Ereignisgruppen geschrieben werden soll oder ob alle Ereignisse zusammen geschrieben werden sollen, wenn genügend Platz verfügbar ist.
Wenn die Sensors HAL die gewünschte Anzahl von Sensorereignissen in die Ereignis-FMQ geschrieben hat, muss sie das Framework darüber informieren, dass Ereignisse verfügbar sind, indem sie das EventQueueFlagBits::READ_AND_PROCESS
-Bit in die EventFlag::wake
-Funktion der Ereignis-FMQ schreibt. Das EventFlag kann aus dem Ereignis-FMQ mit EventFlag::createEventFlag
und der Funktion getEventFlagWord()
des Ereignis-FMQ erstellt werden.
Die Sensors AIDL HAL unterstützt sowohl write
als auch writeBlocking
im Ereignis-FMQ.
Die Standardimplementierung bietet eine Referenz zur Verwendung von write
. Wenn die Funktion writeBlocking
verwendet wird, muss das Flag readNotification
auf EventQueueFlagBits::EVENTS_READ
gesetzt sein. Dieses wird vom Framework festgelegt, wenn es Ereignisse aus dem Ereignis-FMQ liest. Das Flag für die Schreibbenachrichtigung muss auf EventQueueFlagBits::READ_AND_PROCESS
gesetzt sein. Dadurch wird das Framework benachrichtigt, dass Ereignisse in die Ereignis-FMQ geschrieben wurden.
WAKE_UP-Ereignisse
WAKE_UP
-Ereignisse sind Sensorereignisse, die dazu führen, dass der Anwendungsprozessor (AP) aktiviert wird und das Ereignis sofort verarbeitet. Wenn ein WAKE_UP
-Ereignis in die Ereignis-FMQ geschrieben wird, muss der Sensor-HAL einen Wakelock sichern, damit das System aktiv bleibt, bis das Framework das Ereignis verarbeiten kann. Wenn ein WAKE_UP
-Ereignis empfangen wird, sichert das Framework seine eigene Wake-Lock, sodass die Sensors HAL ihre Wake-Lock freigeben kann. Verwenden Sie die Wake Lock FMQ, um zu synchronisieren, wenn der Sensors-HAL seinen Wakelock freigibt.
Die Sensors HAL muss die Wake Lock-FMQ lesen, um die Anzahl der WAKE_UP
-Ereignisse zu ermitteln, die vom Framework verarbeitet wurden. Die HAL sollte die Wake-Locks für WAKE_UP
-Ereignisse nur dann freigeben, wenn die Gesamtzahl der nicht verarbeiteten WAKE_UP
-Ereignisse null ist.
Nach der Verarbeitung von Sensorereignissen zählt das Framework die Anzahl der Ereignisse, die als WAKE_UP
-Ereignisse gekennzeichnet sind, und schreibt diese Zahl zurück in das Wake Lock-FMQ.
Das Framework setzt die WakeLockQueueFlagBits::DATA_WRITTEN
-Schreibbenachrichtigung im Wake Lock-FMQ, wenn es Daten in das Wake Lock-FMQ schreibt.
Dynamische Sensoren
Dynamische Sensoren sind Sensoren, die nicht physisch zum Gerät gehören, aber als Eingabe für das Gerät verwendet werden können, z. B. ein Gamepad mit einem Beschleunigungsmesser.
Wenn ein dynamischer Sensor verbunden ist, muss die Funktion onDynamicSensorConnected
in ISensorsCallback
aus dem Sensoren-HAL aufgerufen werden. Dadurch wird das Framework über den neuen dynamischen Sensor informiert und der Sensor kann über das Framework gesteuert und die Ereignisse des Sensors von Clients genutzt werden.
Wenn ein dynamischer Sensor getrennt wird, muss die Funktion onDynamicSensorDisconnected
in ISensorsCallback
aufgerufen werden, damit das Framework alle nicht mehr verfügbaren Sensoren entfernen kann.
Direkter Kanal
Der direkte Kanal ist eine Betriebsmethode, bei der Sensorereignisse in einen bestimmten Speicher geschrieben werden und nicht in die Ereignis-FMQ, die das Android Sensors Framework umgeht. Ein Client, der einen direkten Kanal registriert, muss die Sensorereignisse direkt aus dem Arbeitsspeicher lesen, der zum Erstellen des direkten Kanals verwendet wurde. Er erhält die Sensorereignisse nicht über das Framework. Die Funktion configDirectReport()
ähnelt der Funktion batch()
für den normalen Betrieb und konfiguriert den direkten Meldekanal.
Mit den Funktionen registerDirectChannel()
und unregisterDirectChannel()
können Sie einen neuen Direktkanal erstellen oder löschen.
Betriebsmodi
Mit der Funktion setOperationMode()
kann das Framework einen Sensor konfigurieren, sodass das Framework Sensordaten in den Sensor einfügen kann. Dies ist nützlich für Tests, insbesondere bei Algorithmen, die unter dem Framework vorhanden sind.
Die Funktion injectSensorData()
wird normalerweise verwendet, um Betriebsparameter in die Sensors HAL zu übergeben. Die Funktion kann auch verwendet werden, um Sensorereignisse in einen bestimmten Sensor zu injizieren.
Zertifizierungsstufe
Führen Sie die CTS- und VTS-Tests für Sensoren aus, um Ihre Implementierung der Sensors HAL zu validieren.
CTS-Tests
Sensor-CTS-Tests gibt es sowohl in automatisierten CTS-Tests als auch in der manuellen CTS Verifier App.
Die automatisierten Tests befinden sich unter cts/tests/sensor/src/android/hardware/cts. Mit diesen Tests wird die Standardfunktionalität von Sensoren überprüft, z. B. Aktivierung von Sensoren, Batchverarbeitung und Sensorereignisraten.
Die CTS Verifier-Tests befinden sich unter cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Diese Tests erfordern eine manuelle Eingabe durch den Testoperator und sorgen dafür, dass die Sensoren korrekte Werte melden.
Das Bestehen der CTS-Tests ist entscheidend, um sicherzustellen, dass das getestete Gerät alle CDD-Anforderungen erfüllt.
VTS-Tests
VTS-Tests für die Sensors AIDL HAL befinden sich unter hardware/interfaces/sensors/aidl/vts/.
Mit diesen Tests wird sichergestellt, dass die Sensors HAL richtig implementiert ist und alle Anforderungen in ISensors.aidl
und ISensorsCallback.aidl
erfüllt werden.
HAL initialisieren
Die Funktion initialize()
muss unterstützt werden, um FMQs zwischen dem Framework und HAL einzurichten.
Verfügbare Sensoren bereitstellen
In der Sensors AIDL HAL muss die Funktion getSensorsList()
während eines einzelnen Gerätestarts denselben Wert zurückgeben, auch bei Neustarts der Sensors HAL. Eine neue Anforderung der Funktion getSensorsList()
besteht darin, dass sie bei einem einzelnen Gerätestart denselben Wert zurückgeben muss, auch bei HAL-Neustarts von Sensoren. So 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 in die FMQ schreiben
Anstatt auf die Aufrufung von poll()
zu warten, muss die Sensors HAL in der Sensors AIDL HAL proaktiv Sensorereignisse in die Ereignis-FMQ schreiben, sobald Sensorereignisse verfügbar sind. Die HAL ist auch dafür verantwortlich, die richtigen Bits in EventFlag
zu schreiben, um eine FMQ-Lesevorgänge im Framework auszulösen.
WAKE_UP-Ereignisse
In Sensors HAL 1.0 konnte die HAL bei jedem nachfolgenden Aufruf von poll()
nach dem Posten eines WAKE_UP
-Ereignisses an poll()
die Wake-Lock für jedes WAKE_UP
-Ereignis freigeben, da dies darauf hindeutete, dass das Framework alle Sensorereignisse verarbeitet und bei Bedarf eine Wake-Lock erhalten hatte. Da die HAL in der Sensors AIDL nicht mehr benachrichtigt wird, wenn das Framework Ereignisse verarbeitet hat, die in die FMQ geschrieben wurden, ermöglicht die Wake Lock-FMQ dem Framework, mit der HAL zu kommunizieren, wenn WAKE_UP
-Ereignisse verarbeitet wurden.
In der Sensors AIDL HAL muss die Wake-Lock, die von der Sensors HAL für WAKE_UP
-Ereignisse gesichert wird, mit SensorsHAL_WAKEUP
beginnen.
Dynamische Sensoren
Dynamische Sensoren wurden in Sensors HAL 1.0 mit der Funktion poll()
zurückgegeben.
Die AIDL HAL-Sensoren erfordern, dass onDynamicSensorsConnected
und onDynamicSensorsDisconnected
in ISensorsCallback
aufgerufen werden, wenn sich die Verbindungen dynamischer Sensoren ändern. Diese Callbacks sind als Teil des ISensorsCallback
-Zeigers verfügbar, der über die initialize()
-Funktion bereitgestellt wird.
Betriebsmodi
Der DATA_INJECTION
-Modus für WAKE_UP
-Sensoren muss unterstützt werden.
Multi-HAL-Unterstützung
Die Sensors AIDL HAL unterstützt mehrere HALs mit dem Sensors Multi-HAL Framework. Implementierungsdetails finden Sie unter Portierung von Sensors HAL 2.1.