Idioma AIDL

El lenguaje AIDL se basa libremente en el lenguaje Java. Los archivos especifican un contrato de interfaz y varios tipos de datos y constantes utilizados en este contrato.

Paquete

Cada archivo AIDL comienza con un paquete opcional que corresponde a los nombres de los paquetes en varios servidores. Una declaración de paquete se ve así:

    package my.package;

Al igual que en 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 donde se pueden especificar tipos. Para obtener una lista exacta de los tipos admitidos en el lenguaje AIDL, consulte Tipos de backends AIDL .

Anotaciones

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

Importaciones

Para utilizar tipos definidos en otras interfaces, primero debe agregar dependencias en el sistema de compilación. En los módulos cc_* y java_* Soong, donde los archivos .aidl se usan directamente bajo srcs en las compilaciones de la plataforma Android, puede agregar directorios usando el campo aidl: { include_dirs: ... } . Para importaciones utilizando aidl_interface , consulte aquí .

Una importación se ve así:

    import some.package.Foo;  // explicit import

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

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

Definición de tipos

Los archivos AIDL generalmente definen tipos que se utilizan como interfaz.

Interfaces

Aquí hay un ejemplo de interfaz 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 sincrónicos. Si una interfaz se define como oneway ( oneway interface ITeleport {...} ), entonces todos los métodos que contiene son implícitamente oneway . Los métodos unidireccionales se envían de forma asincrónica y no pueden devolver un resultado. También se garantiza que los métodos unidireccionales del mismo subproceso al mismo cuaderno se ejecuten en serie (aunque potencialmente en subprocesos diferentes). Para obtener información sobre cómo configurar subprocesos, consulte Gestión de subprocesos de backends de AIDL .

Los métodos pueden tener cero o más argumentos. Los argumentos de los métodos pueden ser in , out o inout . Para obtener una explicación sobre cómo esto afecta los tipos de argumentos, consulte Direccionalidad de los backends de AIDL .

Parcelables

Para obtener una descripción de cómo crear parcelables específicos de backend, AIDL backends parcelables personalizados .

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

Por ejemplo:

    package my.package;

    import my.package.Boo;

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

Sindicatos

Android 12 y versiones posteriores admiten declaraciones sindicales. Por ejemplo:

    package my.package;

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

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

Enumeraciones

Android 11 y versiones posteriores admiten declaraciones de enumeración. Por ejemplo:

    package my.package;

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

Declaraciones de tipo anidadas

Android 13 y 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, parcelables y uniones AIDL personalizadas también pueden contener constantes enteras y de cadena, como por ejemplo:

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

Expresiones constantes

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

Los literales true y false representan valores booleanos. 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 de 64 bits de longitud. De lo contrario, los valores integrales obtienen el tipo con signo más pequeño que conserva el valor entre 8 bits (byte), 32 bits (int) y 64 bits (long). Entonces, 256 se considera un int , pero 255 + 1 se desborda y es el byte 0 . Los valores hexadecimales, como 0x3 , se interpretan primero como el tipo sin signo que conserva el valor más pequeño entre 32 y 64 bits y luego se reinterpretan como valores sin signo. Entonces, 0xffffffff tiene el valor int -1 . A partir de Android 13, el sufijo u8 se puede agregar 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 tipo byte mientras que 0xff * 3 es 765 con tipo int .

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