Учитывая файл интерфейса HIDL, серверная часть Java HIDL генерирует интерфейсы Java, заглушку и прокси-код. Он поддерживает все скалярные типы HIDL ([ u ] int { 8,16,32,64}_t, float, double, и enum s), а также строки, интерфейсы, типы safe_union, типы структур, а также массивы и векторы поддерживаемых Типы HIDL. Серверная часть Java HIDL НЕ поддерживает типы union или fmq . В Android 11 добавлена поддержка типов memory и handle .
Поскольку среда выполнения Java изначально не поддерживает концепцию целых чисел без знака, все беззнаковые типы (и основанные на них перечисления) молча рассматриваются как их эквиваленты со знаком, т. е. uint32_t становится int в интерфейсе Java. Преобразование значений не выполняется; разработчик на стороне Java должен использовать знаковые значения, как если бы они были беззнаковыми.
перечисления
Перечисления не генерируют классы перечисления Java, а вместо этого транслируются во внутренние классы, содержащие определение статической константы для каждого случая перечисления. Если класс перечисления является производным от какого-либо другого класса перечисления, он наследует тип хранения этого класса. Перечисления, основанные на целочисленном типе без знака, переписываются в их эквиваленты со знаком. Поскольку базовый тип является примитивным, значение по умолчанию для полей/переменных перечисления равно нулю, даже если нет нулевого перечислителя.
Например, SomeBaseEnum с типом uint8_t :
enum SomeBaseEnum : uint8_t { foo = 3 };
enum SomeEnum : SomeBaseEnum {
quux = 33,
goober = 127
};
… становится:
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;
}
И:
enum SomeEnum : uint8_t {
FIRST_CASE = 10,
SECOND_CASE = 192
};
… переписывается как:
public final class SomeEnum {
static public final byte FIRST_CASE = 10; // no change
static public final byte SECOND_CASE = -64;
}
Струны
String в Java имеют формат utf-8 или utf-16, но при транспортировке преобразуются в utf-8 как общий тип HIDL. Кроме того, String не должна быть нулевой при передаче в HIDL.
Ручка и память
В Android 11 представлена поддержка Java для типов handle и memory . Они переводятся в android.os.NativeHandle и android.os.HidlMemory соответственно. Нулевой дескриптор считается действительным, а нулевая память — нет.
В сгенерированном коде сервера аргументы полученной памяти и дескриптора допустимы только в пределах области вызова метода. Если серверная реализация хочет продлить срок их службы, они должны быть продублированы с помощью соответствующих методов dup() . Возвращенный экземпляр может использоваться вне вызова метода и должен быть правильно закрыт, когда с ним покончено.
В сгенерированном клиентском коде дескрипторы и экземпляры памяти, которые отправляются в качестве входных аргументов вызываемого метода, не нужно дублировать или сохранять действительными после возврата метода. Однако дескрипторы и экземпляры памяти, полученные в качестве выходных аргументов, автоматически дублируются автоматически сгенерированным кодом и должны быть должным образом закрыты после завершения работы. Это верно независимо от того, отображаются ли эти возвращаемые аргументы как возвращаемые значения метода (в случае с одним возвращаемым значением) или с использованием стиля синхронного обратного вызова (используется в случае с несколькими возвращаемыми значениями).
Дополнительные сведения о дублировании и закрытии см. в документации по классам Java.
Массивы и векторы
Массивы транслируются в массивы Java, а векторы транслируются в ArrayList<T> , где T — соответствующий тип объекта, возможно, оборачивающий скалярные типы, такие как vec<int32_t> => ArrayList<Integer> ). Например:
takeAnArray(int32_t[3] array); returnAVector() generates (vec<int32_t> result);
… становится:
void takeAnArray(int[] array); ArrayList<Integer> returnAVector();
Структуры
Структуры переводятся в классы Java с аналогичной компоновкой. Например:
struct Bar {
vec<bool> someBools;
};
struct Foo {
int32_t a;
int8_t b;
float[10] c;
Bar d;
};
… становится:
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.hal получает свой собственный выходной файл .java (как того требует Java). Например, следующий файл types.hal приводит к созданию двух дополнительных файлов (Foo.java и Bar.java):
struct Foo {
...
};
struct Bar {
...
struct Baz {
};
...
};
Определение Baz находится в статическом внутреннем классе Bar (в Bar.java).