O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

HIDL Java

No Android 8.0, o sistema operacional Android foi reprojetado para definir interfaces claras entre a plataforma Android independente do dispositivo e o código específico do dispositivo e do fornecedor. Android já definido muitas dessas interfaces, sob a forma de interfaces de Hal, definidos como cabeçalhos C em hardware/libhardware . HIDL substituído essas interfaces de HAL com estáveis, interfaces de versão, que pode ser tanto em Java (descrito abaixo), ou interfaces de ser HIDL cliente-servidor e do lado em C ++ .

As interfaces HIDL devem ser usadas principalmente a partir de código nativo e, como resultado, o HIDL se concentra na geração automática de código eficiente em C ++. No entanto, as interfaces HIDL também devem estar disponíveis para uso diretamente do Java, pois alguns subsistemas Android (como telefonia) têm interfaces HIDL Java.

As páginas nesta seção descrevem o frontend Java para interfaces HIDL, detalham como criar, registrar e usar serviços e explicam como HALs e clientes HAL escritos em Java interagem com o sistema HIDL RPC.

Ser um cliente

Este é um exemplo de um cliente para uma interface IFoo no pacote android.hardware.foo@1.0 que está registrado como nome de serviço default e um serviço adicional com o costume nome do serviço second_impl .

Adicionar bibliotecas

Você precisa adicionar dependências na biblioteca stub HIDL correspondente se quiser usá-la. Normalmente, esta é uma biblioteca estática:

// in Android.bp
static_libs: [ "android.hardware.foo-V1.0-java", ],
// in Android.mk
LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java

Se você sabe que já está puxando dependências dessas bibliotecas, também pode usar a vinculação compartilhada:

// in Android.bp
libs: [ "android.hardware.foo-V1.0-java", ],
// in Android.mk
LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java

Considerações adicionais para adicionar bibliotecas no Android 10

Se você tiver um aplicativo de sistema ou fornecedor voltado para o Android 10 ou superior, poderá incluir essas bibliotecas estaticamente. Você também pode usar (apenas) as classes HIDL de JARs personalizado instalado no dispositivo com estáveis APIs Java disponibilizado utilizando o existentes uses-library mecanismo para aplicativos do sistema. A última abordagem economiza espaço no dispositivo. Para mais detalhes, consulte Implementação Java SDK Biblioteca . Para aplicativos mais antigos, o comportamento antigo é preservado.

A partir do Android 10, versões "superficiais" dessas bibliotecas também estão disponíveis. Isso inclui a classe em questão, mas não inclui nenhuma das classes dependentes. Por exemplo, android.hardware.foo-V1.0-java-shallow inclui classes no pacote tal, mas não incluem as classes em android.hidl.base-V1.0-java , que contém a classe de base de todos HIDL interfaces. Se estiver criando uma biblioteca que já possui as classes base da interface preferencial disponíveis como uma dependência, você pode usar o seguinte:

// in Android.bp
static_libs: [ "android.hardware.foo-V1.0-java-shallow", ],
// in Android.mk
LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java-shallow

As bibliotecas de base e gerenciador HIDL também não estão mais disponíveis no classpath de inicialização para aplicativos (anteriormente, às vezes eram usadas como API oculta, devido ao carregador de classe delegado primeiro do Android). Em vez disso, eles foram movidos para um novo namespace com jarjar e aplicativos que usam esses (aplicativos necessariamente priv) deve ter suas próprias cópias separadas. Módulos no classpath de inicialização usando HIDL deve usar o rasa variantes destas bibliotecas Java e adicionar jarjar_rules: ":framework-jarjar-rules" para a sua Android.bp usar a versão dessas bibliotecas que existe no classpath de inicialização.

Modificando sua fonte Java

Há apenas uma versão ( @1.0 ) deste serviço, assim que esta recupera código apenas essa versão. Ver extensões de interface para como lidar com várias versões diferentes do serviço.

import android.hardware.foo.V1_0.IFoo;
...
// retry to wait until the service starts up if it is in the manifest
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IFoo anotherServer = IFoo.getService("second_impl", true /* retry */);
server.doSomething(…);

Prestando um serviço

O código da estrutura em Java pode precisar servir interfaces para receber callbacks assíncronos de HALs.

Para o IFooCallback de interface na versão 1.0 do android.hardware.foo pacote, você pode implementar sua interface em Java usando os seguintes passos:

  1. Defina sua interface em HIDL.
  2. Abrir /tmp/android/hardware/foo/IFooCallback.java como uma referência.
  3. Crie um novo módulo para sua implementação Java.
  4. Examine a classe abstrata android.hardware.foo.V1_0.IFooCallback.Stub , em seguida, escrever uma nova classe de estendê-lo e implementar os métodos abstratos.

Visualizando arquivos gerados automaticamente

Para visualizar os arquivos gerados automaticamente, execute:

hidl-gen -o /tmp -Ljava \
  -randroid.hardware:hardware/interfaces \
  -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0

Estes comandos geram o diretório /tmp/android/hardware/foo/1.0 . Para o arquivo de hardware/interfaces/foo/1.0/IFooCallback.hal , isso gera o arquivo /tmp/android/hardware/foo/1.0/IFooCallback.java , que encapsula a interface Java, o código de proxy, e os topos (ambos procuração e os stubs estão em conformidade com a interface).

-Lmakefile gera as regras que executar este comando em tempo de compilação e permitem que você inclua android.hardware.foo-V1.0-java e ligação contra os arquivos apropriados. Um script que faz isso automaticamente para um projeto completo de interfaces pode ser encontrada em hardware/interfaces/update-makefiles.sh . Os caminhos neste exemplo são relativos; hardware / interfaces podem ser um diretório temporário em sua árvore de código para permitir que você desenvolva um HAL antes de publicá-lo.

Executando um serviço

O HAL fornece a IFoo interface, que deve fazer retornos de chamada assíncronos com o quadro sobre o IFooCallback interface. O IFooCallback interface não é registrada pelo nome, como um serviço de descoberta; em vez disso, IFoo deve conter um método tal como setFooCallback(IFooCallback x) .

Para configurar IFooCallback da versão 1.0 do android.hardware.foo pacote, adicione android.hardware.foo-V1.0-java para Android.mk . O código para executar o serviço é:

import android.hardware.foo.V1_0.IFoo;
import android.hardware.foo.V1_0.IFooCallback.Stub;
....
class FooCallback extends IFooCallback.Stub {
    // implement methods
}
....
// Get the service from which you will be receiving callbacks.
// This also starts the threadpool for your callback service.
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
....
// This must be a persistent instance variable, not local,
//   to avoid premature garbage collection.
FooCallback mFooCallback = new FooCallback();
....
// Do this once to create the callback service and tell the "foo-bar" service
server.setFooCallback(mFooCallback);

Extensões de interface

Assumindo um determinado implementos serviço do IFoo de interface em todos os dispositivos, é possível que em um dispositivo especial o serviço pode fornecer recursos adicionais implementadas na extensão de interface IBetterFoo , como segue:

interface IFoo {
   ...
};

interface IBetterFoo extends IFoo {
   ...
};

Código de ligação ciente da interface estendida pode usar o castFrom() método Java para lançar com segurança a interface base para a interface estendida:

IFoo baseService = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IBetterFoo extendedService = IBetterFoo.castFrom(baseService);
if (extendedService != null) {
  // The service implements the extended interface.
} else {
  // The service implements only the base interface.
}