Типы данных

При наличии файла интерфейса HIDL бэкенд Java HIDL генерирует интерфейсы Java, заглушки и прокси-код. Он поддерживает все скалярные типы HIDL ([ u ] int { 8,16,32,64}_t, float, double, и enum ), а также строки, интерфейсы, типы safe_union, типы структур, а также массивы и векторы поддерживаемых типов HIDL. Бэкенд Java HIDL НЕ поддерживает типы union и fmq . В Android 11 добавлена ​​поддержка типов memory и handle .

Поскольку среда выполнения Java изначально не поддерживает концепцию беззнаковых целых чисел, все беззнаковые типы (и основанные на них перечисления) автоматически обрабатываются как их знаковые эквиваленты, то есть uint32_t в интерфейсе Java становится int . Преобразование значений не выполняется; разработчик на стороне 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 не должна быть равна NULL при передаче в 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 ).