Tipi di dati

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

Poiché il runtime Java non supporta il concetto di numeri interi non firmati in modo nativo, tutti i tipi non firmati (e gli enum basati su di essi) vengono trattati in silenzio come i loro equivalenti firmati, ovvero uint32_t diventa int nell'interfaccia Java. Non viene eseguita alcuna conversione del valore. L'implementatore sul lato Java deve utilizzare i valori firmati come se non fossero firmati.

Enumerazionis

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

Ad esempio, un SomeBaseEnum di tipo 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 nullo 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 handle e memoria ricevuti sono validi solo nell'ambito dell'invocazione del metodo. Se l'implementazione del server vuole estendere la propria durata, deve essere duplicata utilizzando i rispettivi metodi dup(). L'istanza restituita può essere utilizzata oltre l'invocazione del metodo e deve essere chiusa correttamente al termine.

Nel codice client generato, gli handle e le istanze di memoria che vengono inviati come argomenti di input del metodo chiamato non devono essere duplicati né mantenuti validi dopo il ritorno 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. Questo vale se gli argomenti di ritorno vengono visualizzati come valori restituiti del metodo (nel caso di un singolo valore restituito) o utilizzando lo stile di callback sincrono (utilizzato nel caso di più valori restituiti).

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 in ArrayList<T>, dove T è il tipo di oggetto appropriato, eventualmente con wrapping di 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. Per 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 types.hal file genera 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).