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.
Implementieren Sie die Sensors AIDL HAL.
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. Die HAL verwendet den zweiten Deskriptor, um die Wake Lock-FMQ zu erstellen, die zum Synchronisieren verwendet wird, wenn die HAL die Wake Lock 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. Das Neustarten der Android-Laufzeit ist zwar für den Nutzer ärgerlich, aber erforderlich, da das Android-Framework nicht mehr den Android API-Vertrag einhalten kann, dass sich statische (nicht dynamische) Sensoren während der Lebensdauer einer App nicht ändern. Dies kann auch verhindern, dass das Framework aktive Sensoranfragen von Apps wiederherstellt. Daher wird HAL-Anbietern empfohlen, vermeidbare Änderungen an der Sensorliste zu vermeiden.
Um stabile Sensor-Handles zu gewährleisten, muss die HAL einen bestimmten physischen Sensor auf dem Gerät deterministisch seinem Handle 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 mit einer Stichprobenzeit und einer maximalen Berichtslatenz mithilfe der Funktion batch()
konfiguriert werden.
Ein Sensor muss jederzeit mit batch()
neu konfiguriert werden können, ohne dass Sensordaten verloren gehen.
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.
- Einzelmessung: Der Stichprobenzeitraum wird ignoriert.
- Speziell: Weitere Informationen finden Sie unter Sensortypen.
Informationen zur Interaktion zwischen einem Messzeitraum und den Berichtsmodi eines Sensors finden Sie unter Berichtsmodi.
Maximale Berichtslatenz
Mit der maximalen Berichtslatenz wird die maximale Zeit in Nanosekunden festgelegt, in der Ereignisse verzögert und im Hardware-FIFO gespeichert werden können, bevor sie über die HAL in die Ereignis-FMQ geschrieben werden, während das 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 nach der Erkennung gemeldet 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 wird die Anzahl der Unterbrechungen reduziert, die an das SoC gesendet werden, und das SoC kann in einen niedrigeren Energiesparmodus wechseln, während der Sensor Daten erfasst und bündelt.
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. Das gilt für alle Sensoren mit Ausnahme von Einmalsensoren.
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 Event-FMQ wird von der Sensors HAL verwendet, um Sensorereignisse an das Android-Sensor-Framework zu senden.
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 entscheiden, ob die aktuellen Ereignisse als zwei kleinere Ereignisgruppen oder alle Ereignisse zusammen geschrieben werden sollen, wenn genügend Speicherplatz verfügbar ist.
Wenn die Sensors HAL die gewünschte Anzahl von Sensorereignissen in die Ereignis-FMQ geschrieben hat, muss die Sensors HAL 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. Die EventFlag kann über die EventFlag::createEventFlag
-Funktion und die getEventFlagWord()
-Funktion der Event-FMQ erstellt werden.
Die Sensors AIDL HAL unterstützt sowohl write
als auch writeBlocking
im Ereignis-FMQ.
Die Standardimplementierung dient als Referenz für die 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. Jedes Mal, wenn ein WAKE_UP
-Ereignis in die Ereignis-FMQ geschrieben wird, muss die Sensors HAL eine Wake-Lock 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 den Wake Lock-FMQ, um zu synchronisieren, wenn die Sensors HAL die Wake-Sperre löst.
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 onDynamicSensorConnected
-Funktion in ISensorsCallback
von der Sensors 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
Ein direkter Kanal ist eine Betriebsmethode, bei der Sensorereignisse nicht in das Android Sensors Framework, sondern in einen bestimmten Speicher geschrieben werden. 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 so konfigurieren, dass es Sensordaten in den Sensor einschleusen kann. Das ist für Tests nützlich, insbesondere für Algorithmen, die unterhalb des Frameworks liegen.
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 einzuschleusen.
Zertifizierungsstufe
Führen Sie die CTS- und VTS-Tests für Sensoren aus, um Ihre Implementierung der Sensors HAL zu validieren.
CTS-Tests
CTS-Tests für Sensoren 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. Bei diesen Tests werden die Standardfunktionen von Sensoren überprüft, z. B. die Aktivierung von Sensoren, die Batchverarbeitung und die 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()
bei einem einzelnen Gerätestart denselben Wert zurückgeben, auch bei Neustarts der Sensors HAL. Eine neue Anforderung an die Funktion getSensorsList()
ist, dass sie beim Starten eines Geräts immer denselben Wert zurückgeben muss, auch bei Neustarts der HAL-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 in der Sensors AIDL HAL die HAL 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 Sensors AIDL HAL erfordert, dass onDynamicSensorsConnected
und onDynamicSensorsDisconnected
in ISensorsCallback
aufgerufen werden, wenn sich dynamische Sensorverbindungen ändern. Diese Callbacks sind über den ISensorsCallback
-Zeiger verfügbar, der über die initialize()
-Funktion bereitgestellt wird.
Betriebsmodi
Der DATA_INJECTION
-Modus für WAKE_UP
-Sensoren muss unterstützt werden.
Unterstützung mehrerer HALs
Die Sensors AIDL HAL unterstützt mehrere HALs mit dem Sensors Multi-HAL Framework. Implementierungsdetails finden Sie unter Portierung von Sensors HAL 2.1.