Langue AIDL

Le langage AIDL est vaguement basé sur le langage Java. Les fichiers spécifient un contrat d'interface et divers types de données et constantes utilisés dans ce contrat.

Emballer

Chaque fichier AIDL commence par un package facultatif qui correspond aux noms de packages dans différents backends. Une déclaration de package ressemble à ceci :

    package my.package;

Semblable à Java, les fichiers AIDL doivent se trouver dans une structure de dossiers correspondant à leur package. Les fichiers avec le package my.package doivent se trouver dans le dossier my/package/ .

Les types

Dans les fichiers AIDL, il existe de nombreux endroits où les types peuvent être spécifiés. Pour une liste exacte des types pris en charge dans le langage AIDL, consultez Types de backends AIDL .

Annotations

Plusieurs parties du langage AIDL prennent en charge les annotations. Pour obtenir la liste des annotations et savoir où elles peuvent être appliquées, consultez Annotations AIDL .

Importations

Pour utiliser des types définis dans d'autres interfaces, vous devez d'abord ajouter des dépendances dans le système de build. Dans les modules cc_* et java_* Soong, où les fichiers .aidl sont utilisés directement sous srcs dans les versions de la plateforme Android, vous pouvez ajouter des répertoires en utilisant le champ aidl: { include_dirs: ... } . Pour les importations utilisant aidl_interface , voir ici .

Une importation ressemble à ceci :

    import some.package.Foo;  // explicit import

Lors de l’importation d’un type dans le même package, le package peut être omis. Cependant, l'omission du package peut conduire à des erreurs d'importation ambiguës lorsque les types sont spécifiés sans package et placés dans l'espace de noms global (en général, tous les types doivent être dans un espace de noms) :

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

Définir des types

Les fichiers AIDL définissent généralement des types qui sont utilisés comme interface.

Interfaces

Voici un exemple d'interface AIDL :

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

Une interface définit un objet avec une série de méthodes. Les méthodes peuvent être oneway ( oneway void doFoo() ) ou synchrones. Si une interface est définie comme oneway ( oneway interface ITeleport {...} ), alors toutes les méthodes qu'elle contient sont implicitement oneway . Les méthodes Oneway sont distribuées de manière asynchrone et ne peuvent pas renvoyer de résultat. Les méthodes unidirectionnelles du même thread vers le même classeur sont également garanties de s'exécuter en série (bien que potentiellement sur des threads différents). Pour une discussion sur la façon de configurer les threads, consultez Gestion des threads du backend AIDL .

Les méthodes peuvent avoir zéro ou plusieurs arguments. Les arguments des méthodes peuvent être in , out ou inout . Pour une discussion sur la façon dont cela affecte les types d'arguments, voir Directionnalité des backends AIDL .

Colisables

Pour une description de la façon de créer des colisables spécifiques au back-end, AIDL back-ends colisables personnalisés .

Android 10 et versions ultérieures prennent en charge les définitions parcellaires directement dans AIDL. Ce type de colisable est appelé colisable structuré. Pour plus d'informations sur la relation entre AIDL structuré et stable dans le compilateur AIDL et notre système de construction, voir AIDL structuré et stable .

Par exemple:

    package my.package;

    import my.package.Boo;

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

Les syndicats

Android 12 et versions ultérieures prennent en charge les déclarations syndicales. Par exemple:

    package my.package;

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

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

Énumérations

Android 11 et versions ultérieures prennent en charge les déclarations d'énumération. Par exemple:

    package my.package;

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

Déclarations de type imbriquées

Android 13 et versions ultérieures prennent en charge les déclarations de type imbriquées. Par exemple:

    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

Les interfaces AIDL personnalisées, les parcelles et les unions peuvent également contenir des constantes entières et de chaîne, telles que :

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

Expressions constantes

Les constantes AIDL, les tailles de tableau et les énumérateurs peuvent être spécifiés à l'aide d'expressions constantes. Les expressions peuvent utiliser des parenthèses pour imbriquer des opérations. Les valeurs d'expression constante peuvent être utilisées avec des valeurs entières ou flottantes.

les littéraux true et false représentent des valeurs booléennes. Valeurs avec un . mais sans suffixe, comme 3.8 , sont considérés comme des valeurs doubles. Les valeurs flottantes ont le suffixe f , tel que 2.4f . Une valeur entière avec le suffixe l ou L indique une valeur de 64 bits. Sinon, les valeurs intégrales obtiennent le plus petit type signé préservant la valeur entre 8 bits (octet), 32 bits (int) et 64 bits (long). Ainsi, 256 est considéré comme un int , mais 255 + 1 déborde pour être l' byte 0 . Les valeurs hexadécimales, telles que 0x3 , sont d'abord interprétées comme le plus petit type non signé préservant la valeur entre 32 bits et 64 bits, puis réinterprétées comme des valeurs non signées. Ainsi, 0xffffffff a la valeur int -1 . À partir d'Android 13, le suffixe u8 peut être ajouté aux constantes, telles que 3u8 , pour représenter une valeur byte . Ce suffixe est important pour qu'un calcul, tel que 0xffu8 * 3 , soit interprété comme -3 avec le type byte alors que 0xff * 3 vaut 765 avec le type int .

Les opérateurs pris en charge ont une sémantique C++ et Java. Dans l'ordre de priorité la plus basse à la plus élevée, les opérateurs binaires sont || && | ^ & == != < > <= >= << >> + - * / % . Les opérateurs unaires sont + - ! ~ .