Idioma del AIDL

El lenguaje AIDL se basa en líneas generales en el lenguaje Java. Los archivos especifican un contrato de interfaz y varios tipos de datos y constantes que se usan en este contrato.

Presentación

Cada archivo AIDL comienza con un paquete opcional que corresponde a los nombres del paquete en varios backends. Una declaración de paquete se ve de la siguiente manera:

    package my.package;

Al igual que Java, los archivos AIDL deben estar en una estructura de carpetas que coincida con su paquete. Los archivos con el paquete my.package deben estar en la carpeta my/package/.

Tipos

En los archivos AIDL, hay muchos lugares en los que se pueden especificar tipos. Para obtener una lista exacta de los tipos compatibles con el lenguaje de AIDL, consulta Tipos de backends de AIDL.

Anotaciones

Varias partes del lenguaje de AIDL admiten anotaciones. Para obtener una lista de anotaciones y dónde se pueden aplicar, consulta Anotaciones del AIDL.

Importaciones

Para usar tipos definidos en otras interfaces, primero debes agregar dependencias en el sistema de compilación. En los módulos de Soong cc_* y java_*, en los que los archivos .aidl se usan directamente en srcs en las compilaciones de la plataforma de Android, puedes agregar directorios con el campo aidl: { include_dirs: ... }. Para obtener información sobre importaciones con aidl_interface, consulta aquí.

Una importación se ve de la siguiente manera:

    import some.package.Foo;  // explicit import

Cuando importas un tipo en el mismo paquete, se puede omitir el paquete. Sin embargo, omitir el paquete puede generar errores de importación ambiguos cuando se especifican tipos sin un paquete y se colocan en el espacio de nombres global (por lo general, todos los tipos deben tener espacios de nombres):

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

Definir tipos

Por lo general, los archivos AIDL definen tipos que se usan como interfaz.

Interfaces

Este es un ejemplo de interfaz de AIDL:

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

Una interfaz define un objeto con una serie de métodos. Los métodos pueden ser oneway (oneway void doFoo()) o síncronos. Si una interfaz se define como oneway (oneway interface ITeleport {...}), todos los métodos que contiene son oneway de forma implícita. Los métodos unidireccionales se despachan de forma asíncrona y no pueden mostrar un resultado. Los métodos unidireccionales del mismo subproceso al mismo Binder también se ejecutan en serie (aunque posiblemente en subprocesos diferentes). Si quieres ver un análisis de cómo configurar subprocesos, consulta Administración de subprocesos de backends de AIDL.

Los métodos pueden tener cero o más argumentos. Los argumentos para los métodos pueden ser in, out o inout. Para obtener un análisis sobre cómo esto afecta los tipos de argumentos, consulta Dacionalidad de backends de AIDL.

Objetos parcelables

Si deseas obtener una descripción de cómo crear objetos parcelables específicos del backend, consulta backends de AIDL personalizados en objetos parcelables.

Android 10 y las versiones posteriores admiten definiciones parcelables directamente en AIDL. Este tipo de objeto parcelable se denomina elemento parcelable estructurado. Para obtener más información sobre cómo se relacionan el AIDL estructurado y estable en el compilador de AIDL y nuestro sistema de compilación, consulta AIDL estructurado y estable.

Por ejemplo:

    package my.package;

    import my.package.Boo;

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

Uniones

Android 12 y las versiones posteriores admiten declaraciones de unión. Por ejemplo:

    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 y las versiones posteriores admiten declaraciones de enumeración. Por ejemplo:

    package my.package;

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

Declaraciones de tipos anidados

Android 13 y las versiones posteriores admiten declaraciones de tipos anidados. Por ejemplo:

    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
    }

Constantes

Las interfaces, los objetos parcelables y las uniones personalizados del AIDL también pueden contener constantes de números enteros y cadenas, como:

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

Expresiones constantes

Las constantes del AIDL, los tamaños de los arreglos y los enumeradores se pueden especificar usando expresiones constantes. Las expresiones pueden usar paréntesis para anidar operaciones. Los valores de expresión constante se pueden usar con valores integrales o flotantes.

Los literales true y false representan valores booleanos. Los valores con ., pero sin sufijo, como 3.8, se consideran valores dobles. Los valores flotantes tienen el sufijo f, como 2.4f. Un valor integral con el sufijo l o L indica un valor largo de 64 bits. De lo contrario, los valores integrales obtienen el tipo de firma más pequeño que preserva el valor entre 8 bits (byte), 32 bits (int) y 64 bits (largo). Por lo tanto, 256 se considera un int, pero 255 + 1 se desborda y es el 0 de byte. Los valores hexadecimales, como 0x3, primero se interpretan como el tipo sin firma más pequeño que preserva el valor entre 32 y 64 bits y, luego, se interpretan como valores sin firma. Por lo tanto, 0xffffffff tiene el valor int -1. A partir de Android 13, se puede agregar el sufijo u8 a constantes, como 3u8, para representar un valor byte. Este sufijo es importante para que un cálculo, como 0xffu8 * 3, se interprete como -3 con el tipo byte, mientras que 0xff * 3 es 765 con el tipo int.

Los operadores compatibles tienen semántica de C++ y Java. En orden de menor a mayor prioridad, los operadores binarios son || && | ^ & == != < > <= >= << >> + - * / %. Los operadores unarios son + - ! ~.