Типы данных

Учитывая файл интерфейса HIDL, серверная часть Java HIDL генерирует интерфейсы Java, код заглушки и прокси. Он поддерживает все скалярные типы HIDL ([ u ] int { 8,16,32,64}_t, float, double, и enum s), а также строки, интерфейсы, типы Safe_union, типы структур, а также массивы и векторы поддерживаемых HIDL-типы. Серверная часть Java HIDL НЕ поддерживает типы объединения или типы 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).