AIDL Language

The AIDL language is loosely based on the Java language. Files specify an interface contract and various data types and constants used in this contract.

Package

Every AIDL files starts with an optional package that corresponds to the package names in various backends. A package declaration looks like this:

    package my.package;

Similar to Java, AIDL files must be in a folder structure matching their package. Files with package my.package must be in the folder my/package/.

Types

In AIDL files, there are many places where types can be specified. For an exact list of types that are supported in the AIDL language, see AIDL backends types.

Annotations

Several parts of the AIDL language support annotations. For a list of annotations and where they can be applied, see AIDL annotations.

Imports

To use types defined in other interfaces, you must first add dependencies in the build system. In cc_* and java_* Soong modules, where .aidl files are used directly under srcs in Android platform builds, you can add directories using the field aidl: { include_dirs: ... }. For imports using aidl_interface, see here.

An import looks like this:

    import some.package.Foo;  // explicit import

When importing a type in the same package, the package can be omitted. Though, omitting the package can lead to ambiguous import errors when types are specified without a package and put in the global namespace (generally all types should be namespaced):

    import Foo;  // same as my.package.Foo

Defining Types

AIDL files generally define types which are used as an interface.

Interfaces

Here is an example AIDL interface:

    interface ITeleport {
        void teleport(Location baz, float speed);
        String getName();
    }

An interface defines an object with a series of methods. Methods can either be oneway (oneway void doFoo()) or synchronous. If an interface is defined as oneway (oneway interface ITeleport {...}), then all methods in it are implicitly oneway. Oneway methods are dispatched asynchronously and cannot return a result. Oneway methods from the same thread to the same binder are also guaranteed to execute serially (though potentially on different threads). For a discussion of how to setup threads, see AIDL backends thread management.

Methods can have zero or more arguments. Arguments to methods can be in, out, or inout. For a discussion of how this affects arguments types, see AIDL backends directionality.

Parcelables

For a description of how to create backend-specific parcelables, AIDL backends custom parcelables.

Android 10 and higher support parcelable declarations directly in AIDL. For example:

    package my.package;

    import my.package.Boo;

    parcelable Baz {
        @utf8InCpp String name = "baz";
        Boo boo;
    }

Unions

Android 12 and higher support union declarations. For example:

    package my.package;

    import my.package.FooSettings;
    import my.package.BarSettings;

    union Settings {
        FooSettings fooSettings;
        BarSettings barSettings;
        @utf8InCpp String str;
        int number;
    }

Enums

Android 11 and higher support enum declarations. For example:

    package my.package;

    enum Boo {
        A = 1 * 4,
        B = 3,
    }

Nested Type Declarations

Android T (AOSP experimental) and higher support nested type declarations. For example:

    package my.package;

    import my.package.Baz;

    interface IFoo {
        void doFoo(Baz.Nested nested);  // defined in my/package/Baz.aidl
        void doBar(Bar bar);            // defined below

        parcelable Bar { ... }          // nested type definition
    }

Constants

Custom AIDL interfaces, parcelables, and unions can also contain integer and string constants, such as:

    const @utf8InCpp String HAPPY = ":)";
    const String SAD = ":(";
    const byte BYTE_ME = 1;
    const int ANSWER = 6 * 7;

Constant Expressions

AIDL constants, array sizes, and enumerators can be specified using constant expressions. Expressions can use parentheses to nest operations. Constant expression values can be used with integral or float values.

true and false literals represent boolean values. Values with a . but without a suffix, such as 3.8, are considered to be double values. Float values have the f suffix, such as 2.4f. An integral value with the l or L suffix indicates a 64-bit long value. Otherwise, integrals values get the smallest value-preserving signed type between 8-bit (byte), 32-bit (int), and 64-bit (long). So 256 is considered to be an int, but 255 + 1 overflows to be the byte 0. Hex values, such as 0x3, are first interpreted as the smallest value-preserving unsigned type between 32-bit and 64-bit and then reinterpreted as unsigned values. So, 0xffffffff has the int value -1. Starting in Android T (AOSP experimental), the suffix u8 can be added to constants, such as 3u8, to represent a byte value. This suffix is important so that a calculation, such as 0xffu8 * 3, is interpreted as -3 with type byte whereas 0xff * 3 is 765 with type int.

Supported operators have C++ and Java semantics. In order from lowest to highest precedence, binary operators are || && | ^ & == != < > <= >= << >> + - * / %. Unary operators are + - ! ~.