Tipi di dati

Dato un file di interfaccia HIDL, il backend Java HIDL genera interfacce Java, codice Stub e Proxy. Supporta tutti i tipi HIDL scalari ([u]int{8,16,32,64}_t, float, double, e enums), nonché stringhe, interfacce, tipi safe_union, tipi struct e array e vettori di tipi HIDL supportati. Il backend Java HIDL NON supporta i tipi union o i tipi fmq. Android 11 aggiunge il supporto per i tipi memory e handle.

Poiché il runtime Java non supporta il concetto di numeri interi senza segno in modo nativo, tutti i tipi senza segno (e le enum basate su di essi) vengono trattati in modo silenzioso come i loro equivalenti con segno, ad es. uint32_t diventa un int in nell'interfaccia Java. Non viene eseguita alcuna conversione di valori; l'implementatore sul lato Java deve utilizzare i valori con segno come se fossero senza segno.

Enum

Le enum non generano classi enum Java, ma vengono tradotte in classi interne contenenti una definizione di costante statica per ogni caso di enum. Se la classe enum deriva da un'altra classe enum, eredita il tipo di archiviazione di quella classe. Le enumerazioni basate su un tipo di numero intero senza segno vengono riscritte nel loro equivalente con segno. Poiché il tipo sottostante è un tipo primitivo, il valore predefinito per i campi/le variabili enum è zero anche quando non esiste un enumeratore zero.

Ad esempio, un SomeBaseEnum con un tipo di uint8_t:

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

… diventa:

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;
}

E:

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

… viene riscritto come:

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

Stringhe

String in Java è utf-8 o utf-16, ma viene convertito in utf-8 come tipo HIDL comune durante il trasporto. Inoltre, String non deve essere null quando viene passato a HIDL.

Handle e memoria

Android 11 introduce il supporto Java per i tipi handle e memory. Vengono tradotti rispettivamente in android.os.NativeHandle e android.os.HidlMemory. Un handle null è considerato valido, mentre una memoria null non lo è.

Nel codice server generato, gli argomenti di memoria e handle ricevuti sono validi solo nell'ambito della chiamata al metodo. Se l'implementazione del server vuole estenderne la durata, deve essere duplicata utilizzando i rispettivi metodi dup(). L'istanza restituita può essere utilizzata oltre la chiamata al metodo e deve essere chiusa correttamente al termine dell'utilizzo.

Nel codice client generato, gli handle e le istanze di memoria inviati come argomenti di input del metodo chiamato non devono essere duplicati né mantenuti validi dopo la restituzione del metodo. Tuttavia, gli handle e le istanze di memoria ricevuti come argomenti di output vengono duplicati automaticamente dal codice generato automaticamente e devono essere chiusi correttamente al termine dell'utilizzo. Questo vale sia che questi argomenti di restituzione vengano visualizzati come valori di restituzione del metodo (nel caso di un singolo valore di restituzione) sia utilizzando lo stile di callback sincrono (utilizzato nel caso di più valori di restituzione).

Per ulteriori informazioni sulla duplicazione e sulla chiusura, consulta la documentazione delle classi Java.

Array e vettori

Gli array vengono tradotti in array Java e i vettori vengono tradotti in ArrayList<T> dove T è il tipo di oggetto appropriato, che può includere tipi scalari come vec<int32_t> => ArrayList<Integer>). Ad esempio:

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

… diventa:

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

Strutture

Le strutture vengono tradotte in classi Java con un layout simile. Ad esempio:

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

… diventa:

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();
}

Tipi dichiarati

Ogni tipo di primo livello dichiarato in types.hal ha il proprio file di output .java (come richiesto da Java). Ad esempio, il seguente file types.hal comporta la creazione di due file aggiuntivi (Foo.java e Bar.java):

struct Foo {
 ...
};

struct Bar {
 ...

 struct Baz {
 };

 ...
};

La definizione di Baz si trova in una classe interna statica di Bar (in Bar.java).