The Sensors Hardware Abstraction Layer (HAL) is the interface between the Android sensor framework and a device's sensors, such as an accelerometer or gyroscope. The Sensors HAL defines the functions that must be implemented to allow the framework to control the sensors.
The Sensors AIDL HAL is available in Android 13 and higher for new and upgraded devices. The Sensors AIDL HAL, which is based on Sensors HAL 2.1, uses the AIDL HAL interface and exposes the head tracker and limited-axis IMU sensor types.
AIDL HAL Interface
The main source of documentation for the Sensors AIDL HAL is within the HAL definition at hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl.
Implementing the Sensors AIDL HAL
To implement the Sensors AIDL HAL, an object must extend the
interface and implement all functions defined in
Initializing the HAL
The Sensors HAL must be initialized by the Android sensor framework before it
can be used. The framework calls the
initialize() function to provide three
parameters to the Sensors HAL: two FMQ descriptors and one pointer to an
The HAL uses the first descriptor to create the Event FMQ used to write sensor
events to the framework. The HAL uses the second descriptor to create the Wake
Lock FMQ used to synchronize when the HAL releases its wake lock for
sensor events. The HAL must save a pointer to the
ISensorsCallback object so
that any necessary callback functions may be invoked.
initialize() function must be the first function called when initializing
the Sensors HAL.
Exposing available sensors
To get a list of all of the available static sensors in the device, use the
getSensorsList() function. This function returns a list of sensors, each
uniquely identified by its handle. The handle for a given sensor must not change
when the process hosting the Sensors HAL restarts. Handles might change across
device reboots, and across system server restarts.
If several sensors share the same sensor type and wake-up property, then the
first sensor in the list is called the default sensor and is returned to
apps that utilize the
getDefaultSensor(int sensorType, bool wakeUp)
Stability of sensors list
After a Sensors HAL restart, if the data returned by
indicates a significant change compared to the sensor list retrieved before the
restart, the framework triggers a restart of the
Android runtime. Significant changes to the sensor list include cases where a
sensor with a given handle is missing or has changed attributes, or where new
sensors are introduced. Although restarting the Android runtime is disruptive
to the user, it's required because the Android framework can no longer meet the
Android API contract that static (nondynamic) sensors don't change during the
lifetime of an app. This may also prevent the framework from reestablishing
active sensor requests made by apps. Therefore, HAL vendors are advised to
prevent avoidable sensor list changes.
To ensure stable sensor handles, the HAL must deterministically map a given physical sensor in the device to its handle. Although no specific implementation is mandated by the Sensors HAL interface, developers have a number of options available to meet this requirement.
For example, the sensor list can be sorted using a combination of each sensor's
fixed attributes, such as vendor, model, and sensor type. Another option relies
on the fact that the device's set of static sensors is fixed in hardware, so the
HAL needs to know when all expected sensors have completed initialization before
getSensorsList(). This list of
expected sensors can be compiled into the HAL binary or stored in a
configuration file in the file system, and the order of appearance can be used
to derive stable handles. Although the best solution depends on your HAL's
specific implementation details, the key requirement is that sensor handles
don't change across HAL restarts.
Before a sensor is activated, the sensor must be configured with a sampling
period and maximum reporting latency using the
A sensor must be able to be reconfigured at any time using
batch() without the
loss of sensor data.
The sampling period has a different meaning based on the sensor type that's being configured:
- Continuous: Sensor events are generated at a continuous rate.
- On-change: Events are generated no faster than the sampling period and may be generated at a rate slower than the sampling period if the measured value doesn't change.
- One-shot: The sampling period is ignored.
- Special: For more details, see Sensor types.
To learn about the interaction between a sampling period and a sensor's reporting modes, see Reporting modes.
Maximum reporting latency
The maximum reporting latency sets the maximum time in nanoseconds that events can be delayed and stored in the hardware FIFO before being written to the Event FMQ through the HAL while the SoC is awake.
A value of zero signifies that the events must be reported as soon as they're measured, either skipping the FIFO altogether, or emptying the FIFO as soon as one event from the sensor is present in the FIFO.
For example, an accelerometer activated at 50 Hz with a maximum reporting latency of zero triggers interrupts 50 times per second when the SoC is awake.
When the maximum reporting latency is greater than zero, sensor events don't need to be reported as soon as they're detected. Events can be temporarily stored in the hardware FIFO and reported in batches, as long as no event is delayed by more than the maximum reporting latency. All events since the previous batch are recorded and returned at once. This reduces the number of interrupts sent to the SoC and allows the SoC to switch to a lower power mode while the sensor is capturing and batching data.
Each event has a timestamp associated with it. Delaying the time at which an event is reported must not impact the event timestamp. The timestamp must be accurate and correspond to the time at which the event physically happened, not the time it was reported.
For additional information and requirements on reporting sensor events with nonzero maximum reporting latency, see Batching.
The framework enables and disables sensors using the
Prior to activating a sensor, the framework must first configure the sensor
After a sensor is deactivated, additional sensor events from that sensor must not be written to the Event FMQ.
If a sensor is configured to batch sensor data, the framework can force
an immediate flush of batched sensor events by calling
flush(). This causes
the batched sensor events for the specified sensor handle to be immediately
written to the Event FMQ. The Sensors HAL must append a flush complete event
to the end of the sensor events that are written as a result of a call to
The flush happens asynchronously (that is, this function must return immediately). If the implementation uses a single FIFO for several sensors, that FIFO is flushed and the flush complete event is added only for the specified sensor.
If the specified sensor has no FIFO (no buffering possible), or if the FIFO was
empty at the time of the call,
flush() must still succeed and send a flush
complete event for that sensor. This applies to all sensors other than one-shot
flush() is called for a one-shot sensor, then
flush() must return
BAD_VALUE and not generate a flush complete event.
Writing sensor events to the FMQ
The Event FMQ is used by the Sensors HAL to push sensor events into the Android sensor framework.
The Event FMQ is a synchronized FMQ, which means that any attempt to write more events to the FMQ than the available space allows results in a failed write. In such case, the HAL should determine whether to write the current set of events as two smaller groups of events or to write all of the events together when enough space is available.
When the Sensors HAL has written the desired number of sensor events to the
Event FMQ, the Sensors HAL must notify the framework that events are ready by
EventQueueFlagBits::READ_AND_PROCESS bit to the Event FMQ's
EventFlag::wake function. The EventFlag can be created from the Event FMQ
EventFlag::createEventFlag and the Event FMQ's
The Sensors AIDL HAL supports both
writeBlocking on the Event FMQ.
The default implementation provides a reference for using
write. If the
writeBlocking function is used, the
readNotification flag must be set to
EventQueueFlagBits::EVENTS_READ, which is set by the framework when it reads
events from the Event FMQ. The write notification flag must be set to
EventQueueFlagBits::READ_AND_PROCESS, which notifies the framework that events
have been written to the Event FMQ.
WAKE_UP events are sensor events that cause the application processor (AP) to
wake up and handle the event immediately. Whenever a
WAKE_UP event is written
to the Event FMQ, the Sensors HAL must secure a wake lock to ensure that the
system stays awake until the framework can handle the event. Upon receiving a
WAKE_UP event, the framework secures its own wake lock, allowing for the
Sensors HAL to release its wake lock. To synchronize when the Sensors HAL
releases its wake lock, use the Wake Lock FMQ.
The Sensors HAL must read the Wake Lock FMQ to determine the number of
events that the framework has handled. The HAL should only release its wake lock
WAKE_UP events if the total number of unhandled
WAKE_UP events is zero.
After handling sensor events, the framework counts the number of events that are
WAKE_UP events and writes this number back to the Wake Lock FMQ.
The framework sets the
notification on the Wake Lock FMQ whenever it writes data to the Wake Lock FMQ.
Dynamic sensors are sensors that aren't physically a part of the device but can be used as input to the device, such as a gamepad with an accelerometer.
When a dynamic sensor is connected, the
onDynamicSensorConnected function in
ISensorsCallback must be called from the Sensors HAL. This notifies the
framework of the new dynamic sensor and allows the sensor to be controlled
through the framework and to have the sensor's events be consumed by clients.
Similarly, when a dynamic sensor is disconnected, the
onDynamicSensorDisconnected function in
ISensorsCallback must be called so
that the framework can remove any sensor that is no longer available.
Direct channel is a method of operation where sensor events are written to
specific memory instead of to the Event FMQ bypassing the Android Sensors
Framework. A client that registers a direct channel must read the sensor events
directly from the memory that was used to create the direct channel and won't
receive the sensor events through the framework. The
function is similar to
batch() for normal operation and configures the direct
unregisterDirectChannel() functions create
or destroy a new direct channel.
setOperationMode()function allows for the framework to configure a sensor
so that the framework can inject sensor data into the sensor. This is useful for
testing, especially for algorithms that exist below the framework.
injectSensorData() function is normally used to push operational
parameters into the Sensors HAL. The function can also be used to inject sensor
events into a specific sensor.
To validate your implementation of the Sensors HAL, run the sensor CTS and VTS tests.
Sensor CTS tests exist in both automated CTS tests and the manual CTS Verifier app.
The automated tests are located in cts/tests/sensor/src/android/hardware/cts. These tests verify standard functionality of sensors, such as activating sensors, batching, and sensor event rates.
The CTS Verifier tests are located in cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. These tests require manual input from the test operator and ensure that sensors report accurate values.
Passing the CTS tests is critical to ensuring that the device under test meets all CDD requirements.
VTS tests for the Sensors AIDL HAL are located in
These tests ensure that the Sensors HAL is implemented properly and that all
ISensorsCallback.aidl are properly met.
Initializing the HAL
initialize() function must be supported to establish FMQs between the
framework and HAL.
Exposing available sensors
In the Sensors AIDL HAL, the
getSensorsList() function must return the same value
during a single device boot, even across Sensors HAL restarts. A new requirement
getSensorsList() function is that it must return the same value during
a single device boot, even across Sensors HAL restarts. This allows for the
framework to attempt to reestablish sensor connections if the system server
restarts. The value returned by
getSensorsList() can change after the device
performs a reboot.
Writing sensor events to the FMQ
Instead of waiting for
poll() to be called, in the Sensors AIDL HAL, the Sensors
HAL must proactively write sensor events to the Event FMQ whenever sensor events
are available. The HAL is also responsible for writing the correct bits to
EventFlag to cause an FMQ read within the framework.
In Sensors HAL 1.0, the HAL was able to release its wake lock for any
event on any subsequent call to
poll() after a
WAKE_UP was posted to
poll() because this indicated that the framework had processed all sensor
events and had obtained a wake lock, if necessary. Because, in the Sensors AIDL
HAL, the HAL is no longer notified when the framework has processed events
written to the FMQ, the Wake Lock FMQ allows the framework to communicate to the
HAL when it has handled
In the Sensors AIDL HAL, the wake lock secured by the Sensors HAL for
events must start with
Dynamic sensors were returned using the
poll() function in Sensors HAL 1.0.
The Sensors AIDL HAL requires that
ISensorsCallback be called whenever dynamic
sensor connections change. These callbacks are available as part of the
ISensorsCallback pointer that is provided through the
DATA_INJECTION mode for
WAKE_UP sensors must be supported.
The Sensors AIDL HAL supports multi-HAL using the Sensors Multi-HAL framework. For implementation details, see Porting from Sensors HAL 2.1.