Idioma AIDL

A linguagem AIDL é vagamente baseada na linguagem Java. Os arquivos especificam um contrato de interface e vários tipos de dados e constantes usados ​​neste contrato.

Pacote

Cada arquivo AIDL começa com um pacote opcional que corresponde aos nomes dos pacotes em vários backends. Uma declaração de pacote se parece com isto:

    package my.package;

Semelhante ao Java, os arquivos AIDL devem estar em uma estrutura de pastas correspondente ao seu pacote. Arquivos com pacote my.package devem estar na pasta my/package/ .

Tipos

Nos arquivos AIDL, há muitos locais onde os tipos podem ser especificados. Para obter uma lista exata de tipos suportados na linguagem AIDL, consulte Tipos de back-end AIDL .

Anotações

Várias partes da linguagem AIDL suportam anotações. Para obter uma lista de anotações e onde elas podem ser aplicadas, consulte Anotações AIDL .

Importações

Para usar tipos definidos em outras interfaces, você deve primeiro adicionar dependências no sistema de compilação. Nos módulos cc_* e java_* Soong, onde os arquivos .aidl são usados ​​diretamente em srcs nas compilações da plataforma Android, você pode adicionar diretórios usando o campo aidl: { include_dirs: ... } . Para importações usando aidl_interface , veja aqui .

Uma importação fica assim:

    import some.package.Foo;  // explicit import

Ao importar um tipo no mesmo pacote, o pacote pode ser omitido. Porém, a omissão do pacote pode levar a erros de importação ambíguos quando os tipos são especificados sem um pacote e colocados no namespace global (geralmente todos os tipos devem ter namespace):

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

Definindo Tipos

Os arquivos AIDL geralmente definem tipos que são usados ​​como interface.

Interfaces

Aqui está um exemplo de interface AIDL:

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

Uma interface define um objeto com uma série de métodos. Os métodos podem ser oneway ( oneway void doFoo() ) ou síncronos. Se uma interface for definida como oneway ( oneway interface ITeleport {...} ), todos os métodos nela serão implicitamente oneway . Os métodos unidirecionais são despachados de forma assíncrona e não podem retornar um resultado. Métodos unidirecionais do mesmo thread para o mesmo fichário também têm garantia de execução serial (embora potencialmente em threads diferentes). Para uma discussão sobre como configurar threads, consulte Gerenciamento de threads de back-end AIDL .

Os métodos podem ter zero ou mais argumentos. Os argumentos para métodos podem ser in , out ou inout . Para uma discussão sobre como isso afeta os tipos de argumentos, consulte Direcionalidade de backends AIDL .

Parceláveis

Para obter uma descrição de como criar parcelables específicos de back-end, AIDL back-end parcelables personalizados .

O Android 10 e versões superiores suportam definições parceladas diretamente no AIDL. Este tipo de parcelamento é chamado de parcelamento estruturado. Para obter mais informações sobre como AIDL estruturado e estável estão relacionados no compilador AIDL e em nosso sistema de compilação, consulte AIDL estruturado versus estável .

Por exemplo:

    package my.package;

    import my.package.Boo;

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

Sindicatos

O Android 12 e versões superiores oferecem suporte a declarações sindicais. Por exemplo:

    package my.package;

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

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

Enums

O Android 11 e versões superiores oferecem suporte a declarações de enum. Por exemplo:

    package my.package;

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

Declarações de tipo aninhadas

O Android 13 e versões posteriores oferecem suporte a declarações de tipo aninhadas. Por exemplo:

    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

Interfaces AIDL personalizadas, parcelables e uniões também podem conter constantes inteiras e de string, como:

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

Expressões Constantes

Constantes AIDL, tamanhos de array e enumeradores podem ser especificados usando expressões constantes. As expressões podem usar parênteses para aninhar operações. Valores de expressão constante podem ser usados ​​com valores integrais ou flutuantes.

literais true e false representam valores booleanos. Valores com . mas sem sufixo, como 3.8 , são considerados valores duplos. Valores flutuantes têm o sufixo f , como 2.4f . Um valor integral com o sufixo l ou L indica um valor longo de 64 bits. Caso contrário, os valores integrais obtêm o menor tipo de sinal com preservação de valor entre 8 bits (byte), 32 bits (int) e 64 bits (longo). Portanto, 256 é considerado um int , mas 255 + 1 transborda para ser o byte 0 . Valores hexadecimais, como 0x3 , são primeiro interpretados como o menor tipo não assinado com preservação de valor entre 32 bits e 64 bits e depois reinterpretados como valores não assinados. Então, 0xffffffff tem o valor int -1 . A partir do Android 13, o sufixo u8 pode ser adicionado a constantes, como 3u8 , para representar um valor byte . Este sufixo é importante para que um cálculo, como 0xffu8 * 3 , seja interpretado como -3 com tipo byte enquanto 0xff * 3 é 765 com tipo int .

Os operadores suportados têm semântica C++ e Java. Em ordem de precedência mais baixa para a mais alta, os operadores binários são || && | ^ & == != < > <= >= << >> + - * / % . Os operadores unários são + - ! ~ .