Datentypen

Bei einer gegebenen HIDL-Schnittstellendatei generiert das Java HIDL-Backend Java-Schnittstellen, Stub- und Proxy-Code. Es unterstützt alle skalaren HIDL-Typen ([ u ] int { 8,16,32,64}_t, float, double, und enum s) sowie Strings, Schnittstellen, Safe_Union-Typen, Strukturtypen sowie Arrays und Vektoren der unterstützten HIDL-Typen. Das Java HIDL-Backend unterstützt KEINE Union-Typen oder FMQ-Typen . Android 11 fügt Unterstützung für die memory und handle Typen hinzu.

Da die Java-Laufzeit das Konzept vorzeichenloser Ganzzahlen nicht nativ unterstützt, werden alle vorzeichenlosen Typen (und darauf basierende Aufzählungen) stillschweigend als ihre vorzeichenbehafteten Äquivalente behandelt, d. h. uint32_t wird in der Java-Schnittstelle zu einem int . Es erfolgt keine Wertumrechnung; Der Implementierer auf der Java-Seite muss die vorzeichenbehafteten Werte so verwenden, als wären sie ohne Vorzeichen.

Aufzählungen

Aufzählungen generieren keine Java-Aufzählungsklassen, sondern werden stattdessen in innere Klassen übersetzt, die eine statische Konstantendefinition für jeden Aufzählungsfall enthalten. Wenn die Enum-Klasse von einer anderen Enum-Klasse abgeleitet ist, erbt sie den Speichertyp dieser Klasse. Aufzählungen, die auf einem vorzeichenlosen Ganzzahltyp basieren, werden in ihr vorzeichenbehaftetes Äquivalent umgeschrieben. Da der zugrunde liegende Typ ein Grundtyp ist, ist der Standardwert für Aufzählungsfelder/-variablen Null, auch wenn kein Null-Enumerator vorhanden ist.

Zum Beispiel ein SomeBaseEnum mit dem Typ uint8_t :

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

… wird:

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

Und:

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

… wird umgeschrieben als:

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

Saiten

String in Java sind utf-8 oder utf-16, werden jedoch beim Transport in utf-8 als allgemeinen HIDL-Typ konvertiert. Darüber hinaus darf ein String bei der Übergabe an HIDL nicht null sein.

Griff und Erinnerung

Android 11 führt Java-Unterstützung für die handle und memory ein. Sie werden in android.os.NativeHandle bzw. android.os.HidlMemory übersetzt. Ein Null-Handle gilt als gültig, ein Null-Speicher hingegen nicht.

Im generierten Servercode sind empfangene Speicher- und Handle-Argumente nur im Rahmen des Methodenaufrufs gültig. Wenn die Serverimplementierung ihre Lebensdauer verlängern möchte, müssen sie mit ihren jeweiligen dup() Methoden dupliziert werden. Die zurückgegebene Instanz kann über den Methodenaufruf hinaus verwendet werden und sollte anschließend ordnungsgemäß geschlossen werden.

Im generierten Clientcode müssen Handles und Speicherinstanzen, die als Eingabeargumente der aufgerufenen Methode gesendet werden, weder dupliziert noch nach der Rückkehr der Methode gültig gehalten werden. Allerdings werden Handles und Speicherinstanzen, die als Ausgabeargumente empfangen werden, durch den automatisch generierten Code automatisch dupliziert und müssen anschließend ordnungsgemäß geschlossen werden. Dies gilt unabhängig davon, ob diese Rückgabeargumente als Rückgabewerte der Methode erscheinen (im Fall eines einzelnen Rückgabewerts) oder den synchronen Rückrufstil verwenden (verwendet im Fall mehrerer Rückgabewerte).

Weitere Informationen zum Duplizieren und Schließen finden Sie in der Dokumentation der Java-Klassen.

Arrays und Vektoren

Arrays werden in Java-Arrays und Vektoren in ArrayList<T> übersetzt, wobei T der entsprechende Objekttyp ist und möglicherweise Skalartypen wie vec<int32_t> => ArrayList<Integer> umschließt. Zum Beispiel:

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

… wird:

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

Strukturen

Strukturen werden in Java-Klassen mit einem ähnlichen Layout übersetzt. Zum Beispiel:

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

… wird:

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

Deklarierte Typen

Jeder in types.hal deklarierte Typ der obersten Ebene erhält eine eigene .java-Ausgabedatei (wie von Java gefordert). Beispielsweise führt die folgende Datei types.hal dazu, dass zwei zusätzliche Dateien erstellt werden (Foo.java und Bar.java):

struct Foo {
 ...
};

struct Bar {
 ...

 struct Baz {
 };

 ...
};

Die Definition von Baz lebt in einer statischen inneren Klasse von Bar (in Bar.java).