Types de données

Étant donné un fichier d'interface HIDL, le backend Java HIDL génère des interfaces Java, un code Stub et un code Proxy. Il est compatible avec tous les types HIDL scalaires ([u]int{8,16,32,64}_t, float, double, et enums), ainsi qu'avec les chaînes, les interfaces, les types safe_union, les types struct types, les tableaux et les vecteurs de types HIDL compatibles. Le backend Java HIDL n'est PAS compatible avec les types union ni les types fmq. Android 11 est compatible avec les types memory et handle.

Comme l'environnement d'exécution Java n'est pas compatible avec le concept d'entiers non signés de manière native, tous les types non signés (et les enums basés sur ceux-ci) sont traités de manière silencieuse comme leurs équivalents signés. Par exemple, uint32_t devient un int dans l'interface Java. Aucune conversion de valeur n'est effectuée. L'implémenteur côté Java doit utiliser les valeurs signées comme si elles n'étaient pas signées.

Enums

Les enums ne génèrent pas de classes enum Java, mais sont plutôt traduits en classes internes contenant une définition de constante statique pour chaque cas d'enum. Si la classe enum dérive d'une autre classe enum, elle hérite du type de stockage de cette classe. Les énumérations basées sur un type d'entier non signé sont réécrites dans leur équivalent signé. Étant donné que le type sous-jacent est primitif, la valeur par défaut des champs/variables enum est zéro, même lorsqu'il n'y a pas d'énumérateur zéro.

Par exemple, un SomeBaseEnum de type uint8_t :

enum SomeBaseEnum : uint8_t { foo = 3 };
enum SomeEnum : SomeBaseEnum {
    quux = 33,
    goober = 127
};

… devient :

public final class SomeBaseEnum { public static final byte foo = 3; }
public final class SomeEnum {
    public static final byte foo = 3;
    public static final byte quux = 33;
    public static final byte goober = 127;
}

Et :

enum SomeEnum : uint8_t {
    FIRST_CASE = 10,
    SECOND_CASE = 192
};

… est réécrit comme suit :

public final class SomeEnum {
    static public final byte FIRST_CASE  = 10;  // no change
    static public final byte SECOND_CASE = -64;
}

Chaînes

String en Java est au format UTF-8 ou UTF-16, mais est converti au format UTF-8 en tant que type HIDL commun lors du transport. De plus, String ne doit pas être nul lorsqu'il est transmis à HIDL.

Handle et mémoire

Android 11 est compatible avec les types handle et memory en Java. Ils sont traduits respectivement en android.os.NativeHandle et android.os.HidlMemory. Un handle nul est considéré comme valide, contrairement à une mémoire nulle.

Dans le code serveur généré, les arguments de mémoire et de handle reçus ne sont valides que dans le champ d'application de l'appel de méthode. Si l'implémentation du serveur souhaite prolonger leur durée de vie, elle doit être dupliquée à l'aide de ses méthodes dup() respectives. L'instance renvoyée peut être utilisée au-delà de l'appel de méthode et doit être correctement fermée une fois qu'elle n'est plus nécessaire.

Dans le code client généré, les instances de handles et de mémoire qui sont envoyées en tant qu'arguments d'entrée de la méthode appelée n'ont pas besoin d'être dupliquées ni conservées comme valides après le retour de la méthode. Toutefois, les instances de handles et de mémoire qui sont reçues en tant qu'arguments de sortie sont automatiquement dupliquées par le code généré automatiquement et doivent être correctement fermées une fois qu'elles ne sont plus nécessaires. Cela est vrai que ces arguments de retour apparaissent comme des valeurs de retour de la méthode (dans le cas d'une seule valeur de retour) ou en utilisant le style de rappel synchrone (utilisé dans le cas de plusieurs valeurs de retour).

Pour en savoir plus sur la duplication et la fermeture, consultez la documentation des classes Java.

Tableaux et vecteurs

Les tableaux sont traduits en tableaux Java et les vecteurs sont traduits en ArrayList<T> où T est le type d'objet approprié, en encapsulant éventuellement des types scalaires tels que vec<int32_t> => ArrayList<Integer>). Exemple :

takeAnArray(int32_t[3] array);
returnAVector() generates (vec<int32_t> result);

… devient :

void takeAnArray(int[] array);
ArrayList<Integer> returnAVector();

Structures

Les structures sont traduites en classes Java avec une mise en page similaire. Exemple :

struct Bar {
 vec<bool> someBools;
};
struct Foo {
 int32_t a;
 int8_t b;
 float[10] c;
 Bar d;
};

… devient :

class Bar {
 public final ArrayList<Boolean> someBools = new ArrayList();
};
class Foo {
 public int a;
 public byte b;
 public final float[] c = new float[10];
 public final Bar d = new Bar();
}

Types déclarés

Chaque type de premier niveau déclaré dans types.hal obtient son propre fichier de sortie .java (comme l'exige Java). Par exemple, le fichier types.hal suivant entraîne la création de deux fichiers supplémentaires (Foo.java et Bar.java) :

struct Foo {
 ...
};

struct Bar {
 ...

 struct Baz {
 };

 ...
};

La définition de Baz réside dans une classe interne statique de Bar (dans Bar.java).