AOSP Framework & Internals
2 min read

Stable AIDL

Learn about Stable AIDL.

Introduction

In the past, AIDL interfaces inside the Android framework were notoriously unstable. If Google added a method to an interface, the transaction IDs would shift, breaking any compiled client trying to communicate with that service. With Project Treble, Android established a strict boundary between the OS framework and vendor implementations. To allow AIDL to cross this boundary safely, Stable AIDL was introduced.

Why Stable AIDL - Across Treble Boundary Versioning

Stable AIDL guarantees that the binary layout and transaction IDs of an interface will never change once locked. This allows a vendor partition built for Android 11 to safely communicate with a system partition running Android 14. Stable AIDL is mandatory for all new HALs (Hardware Abstraction Layers) and any IPC that crosses the system-vendor boundary.

Versioned AIDL Interfaces

A stable AIDL interface explicitly defines versions. When a developer needs to add functionality, they append the new method to the end of the interface, bump the version, and freeze the API. Existing clients interacting with the older version will continue to work without knowing the new method exists.

// IFoo.aidl
package android.hardware.foo;

@VintfStability
interface IFoo {
    // Version 1 method
    void doFoo();
    
    // Version 2 method added later
    void doBar();
}

aidl_interface Module in Android.bp

To use Stable AIDL, you define an aidl_interface module in your Android.bp. This build rule generates bindings for Java, C++, and Rust simultaneously, while enforcing stability rules.

aidl_interface {
    name: "android.hardware.foo",
    vendor_available: true,
    srcs: [
        "android/hardware/foo/IFoo.aidl",
    ],
    stability: "vintf",
    backend: {
        java: {
            sdk_version: "module_current",
        },
        cpp: {
            enabled: true,
        },
        ndk: {
            enabled: true,
        },
    },
}

The stability: "vintf" tag is crucial. It tells the build system that this interface is used across the Treble boundary.

Compatibility Hash and Freeze

When an aidl_interface is updated, the build system generates an API dump in an api/ directory. When an Android release is finalized, the API is "frozen". The build system computes a hash of the .aidl files. Any subsequent changes to that versioned interface will cause a build failure due to a hash mismatch.

# Command to update the current API dump
m android.hardware.foo-update-api

# Command to freeze an API version
m android.hardware.foo-freeze-api

If you modify a frozen API, the compiler explicitly rejects the change, forcing you to create a new version of the interface instead.