Tipos de dados

Dado um arquivo de interface HIDL, o back-end Java HIDL gera interfaces Java, código Stub e Proxy. Ele é compatível com todos os tipos escalares de HIDL ([u]int{8,16,32,64}_t, float, double, e enums), além de strings, interfaces, tipos safe_union, tipos struct, matrizes e vetores de tipos HIDL compatíveis. O back-end Java HIDL NÃO oferece suporte a tipos de união ou tipos fmq. O Android 11 adiciona suporte aos tipos memory e handle.

Como o ambiente de execução Java não oferece suporte ao conceito de números inteiros sem sinal de forma nativa, todos os tipos sem sinal (e enums baseados neles) são tratados silenciosamente como seus equivalentes com sinal. Por exemplo, uint32_t se torna um int na interface Java. Nenhuma conversão de valor é realizada. O implementador no lado Java precisa usar os valores assinados como se fossem não assinados.

Enumerações

As enumerações não geram classes de enumeração Java, mas são traduzidas em classes internas que contêm uma definição de constante estática para cada caso de enumeração. Se a classe de tipo enumerado derivar de outra classe de tipo enumerado, ela vai herdar o tipo de armazenamento dessa classe. As enumerações baseadas em um tipo de número inteiro sem sinal são reescritas para o equivalente com sinal. Como o tipo subjacente é primitivo, o valor padrão para campos/variáveis de enumeração é zero, mesmo quando não há um enumerador zero.

Por exemplo, um SomeBaseEnum com um tipo de uint8_t:

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

… se torna:

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

… é reescrito como:

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

Strings

String em Java é utf-8 ou utf-16, mas é convertido para utf-8 como o tipo HIDL comum quando transportado. Além disso, String não pode ser nulo quando transmitido para o HIDL.

Handle e memória

O Android 11 introduz suporte a Java para os tipos handle e memory. Elas são traduzidas para android.os.NativeHandle e android.os.HidlMemory, respectivamente. Um identificador nulo é considerado válido, mas uma memória nula não é.

No código servidor gerado, os argumentos de memória e de manipulação recebidos são válidos apenas no escopo da invocação do método. Se a implementação do servidor quiser estender a vida útil, ela precisará ser duplicada usando os métodos dup() respectivos. A instância retornada pode ser usada além da invocação do método e precisa ser fechada corretamente quando o uso terminar.

No código cliente gerado, os manipuladores e as instâncias de memória que são enviados como argumentos de entrada do método chamado não precisam ser duplicados nem mantidos válidos após o retorno do método. No entanto, os identificadores e as instâncias de memória que são recebidos como argumentos de saída são duplicados automaticamente pelo código autogerado e precisam ser fechados corretamente quando não forem mais usados. Isso é válido se esses argumentos de retorno aparecem como valores de retorno do método (no caso de um único valor de retorno) ou usando o estilo de callback síncrono (usado no caso de vários valores de retorno).

Para mais informações sobre duplicação e fechamento, consulte a documentação das classes Java.

Matrizes e vetores

As matrizes são traduzidas em matrizes Java, e os vetores são traduzidos em ArrayList<T>, em que T é o tipo de objeto apropriado, possivelmente encapsulando tipos escalares, como vec<int32_t> => ArrayList<Integer>. Por exemplo:

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

… se torna:

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

Estruturas

As estruturas são traduzidas em classes Java com um layout semelhante. Por exemplo:

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

… se torna:

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

Tipos declarados

Cada tipo de nível superior declarado em types.hal recebe seu próprio arquivo de saída .java (conforme exigido pelo Java). Por exemplo, o arquivo types.hal a seguir resulta na criação de dois arquivos extras (Foo.java e Bar.java):

struct Foo {
 ...
};

struct Bar {
 ...

 struct Baz {
 };

 ...
};

A definição de Baz fica em uma classe interna estática de Bar (em Bar.java).