Advanced AOSP Subsystems
4 min read

Sensor HAL Deep Dive

Introduction to the Sensor HAL

The Hardware Abstraction Layer (HAL) for sensors is the critical bridge between the Android framework (SensorService) and the device-specific kernel drivers. It standardizes how Android queries capabilities, configures sampling rates, and reads data from diverse hardware sensors like accelerometers, gyroscopes, and ambient light sensors.

The ISensors AIDL Interface

Historically defined using HIDL, modern Android versions define the Sensor HAL using AIDL (Android Interface Definition Language). The ISensors interface defines the exact contract that vendors must implement.

Core Methods

The interface revolves around a few fundamental operations:

  • getSensorsList(): Returns an array of SensorInfo structures, detailing the available sensors, their ranges, resolutions, and power consumption.
  • setOperationMode(): Configures whether the HAL operates in normal, data injection, or other special modes.
  • activate(): Turns a specific sensor on or off.
  • batch(): Sets the sampling period and maximum reporting latency (for hardware FIFO batching).
  • flush(): Forces the HAL to immediately report all buffered events.
// hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl
package android.hardware.sensors;

@VintfStability
interface ISensors {
    SensorInfo[] getSensorsList();
    void setOperationMode(in OperationMode mode);
    void activate(in int sensorHandle, in boolean enabled);
    void batch(in int sensorHandle, in long samplingPeriodNs, in long maxReportLatencyNs);
    void flush(in int sensorHandle);
}

Sensor HAL 2.1 Multihal

The multihal architecture allows device manufacturers to integrate sensors from different vendors seamlessly. Instead of a single monolithic HAL implementation, a shim library (sensors.multihal) loads multiple sub-HALs.

Architecture

  1. Framework (SensorService): Communicates with the top-level ISensors interface.
  2. Multihal Service: Acts as an aggregator. It intercepts calls from the framework and routes them to the appropriate sub-HAL based on the sensor handle.
  3. Sub-HALs: Vendor-specific libraries (e.g., Qualcomm, STMicroelectronics) that implement the actual hardware interaction.

This design simplifies updates. If a manufacturer changes the proximity sensor vendor, they only need to drop in a new sub-HAL without touching the accelerometer implementation.

Sensor Event FIFO

To optimize power consumption, the Sensor HAL heavily relies on hardware FIFOs located on the Sensor Hub (a low-power coprocessor).

Batching Mechanics

When batch() is called with a maxReportLatencyNs greater than zero, the Sensor Hub is instructed to store events locally.

  • Continuous Operation: The Application Processor (AP) goes to sleep. The Sensor Hub fills its FIFO.
  • Wakeup Threshold: When the FIFO is full, or the maxReportLatencyNs timer expires, the Sensor Hub triggers a hardware interrupt.
  • Data Flush: The AP wakes up, and SensorService reads the entire batch of events via the HAL's Event Message Queue (FMQ).
// Example of reading events via Fast Message Queue (FMQ)
bool readEvents() {
    size_t availableToRead = mEventQueue->availableToRead();
    if (availableToRead > 0) {
        std::vector<Event> events(availableToRead);
        if (mEventQueue->read(events.data(), availableToRead)) {
            processEvents(events);
            return true;
        }
    }
    return false;
}

Direct Channel Mode

For high-performance applications like Virtual Reality (VR) or advanced camera stabilization, the standard Binder/BitTube pipeline introduces too much latency. To address this, Android introduced Direct Channel Mode.

Shared Memory Bypassing

Direct Channel Mode bypasses SensorService entirely for data delivery.

  1. Memory Allocation: The application allocates a chunk of shared memory (e.g., Ashmem or HardwareBuffer).
  2. Registration: The application registers this memory region with the Sensor HAL via SensorService.
  3. Direct Writing: The Sensor Hub or Kernel driver writes sensor events directly into the shared memory buffer.
// Struct representing a Direct Channel configuration
struct SharedMemInfo {
    SharedMemType type; // e.g., ASHMEM, GRALLOC
    NativeHandle memoryHandle;
    int size;
};

This zero-copy architecture reduces end-to-end latency to absolute minimums, typically under a few milliseconds, which is critical for motion-to-photon latency in VR headsets.

Inspecting HAL State

Developers can inspect the state of the Sensor HAL using dumpsys:

adb shell dumpsys android.hardware.sensors.ISensors/default

This command provides a wealth of information regarding registered direct channels, active sub-HALs, and hardware FIFO utilization.