Sensores Multi-HAL

O Sensors Multi-HAL é uma estrutura que permite que HALs de sensores funcionem ao lado de outros HALs de sensores. O Sensors Multi-HAL carrega dinamicamente os sub-HALs dos sensores armazenados como bibliotecas dinâmicas na partição do fornecedor e fornece a eles um objeto de retorno de chamada que pode manipular a postagem de eventos e a aquisição e liberação do wake lock. Um sub-HAL de sensores é um HAL de sensores que é construído em um objeto compartilhado na partição do fornecedor e é usado pela estrutura multi-HAL. Esses sub-HALs não dependem uns dos outros ou do código multi-HAL que contém a função principal do processo.

Sensores Multi-HAL 2.1, disponível em dispositivos com Android 11 ou superior, é uma iteração do Sensors Multi-HAL 2.0 que suporta o carregamento de sub-HALs que podem expor o tipo de sensor de ângulo de dobradiça . Para suportar este tipo de sensor, os sub-HALs devem usar as APIs sub-HAL definidas no cabeçalho 2.1 SubHal .

Para dispositivos com Android 13 ou superior que usam Sensores AIDL HAL , você pode usar a camada de calço multi-HAL para permitir o recurso multi-HAL. Para detalhes de implementação, consulte Usando os Sensores Multi-HAL com os Sensores AIDL HAL .

Diferença entre Sensores Multi-HAL 2 e Sensores HAL 2

Sensores Multi-HAL 2, disponível em dispositivos com Android 10 ou superior, introduz várias abstrações sobre os Sensores HAL 2 para facilitar a interação com APIs HAL. Sensores Multi-HAL 2 introduz a classe HalProxy para lidar com a implementação da interface Sensors HAL 2 e a interface V2_1/SubHal (ou V2_0/SubHal ) para permitir que HalProxy interaja com sub-HALs.

A interface ISensorsSubHal é diferente da interface 2.1/ISensors.hal (ou 2.0/ISensors.hal ) das seguintes maneiras:

  • O método de inicialização passa uma classe IHalProxyCallback em vez de dois FMQs e ISensorsCallback .
  • Sub-HALs devem implementar uma função de depuração para fornecer informações de depuração em relatórios de bugs.
  • Os sub-HALs devem implementar uma função de nome para que o sub-HAL carregado possa ser distinguido de outros sub-HALs.

A principal diferença entre os Sensores Multi-HAL 2 e Sensores HAL 2 está nas funções de inicialização. Em vez de fornecer FMQs, a interface IHalProxyCallback fornece dois métodos, um método para postar eventos de sensor na estrutura de sensores e um método para criar wake locks. Sob o capô, o Sensors Multi-HAL gerencia todas as interações com os FMQs para garantir a entrega oportuna de eventos do sensor para todos os sub-HALs. É altamente recomendável que os sub-HALs usem o método createScopedWakelock para delegar o ônus do tempo limite dos wake locks aos Sensores Multi-HAL e centralizar o uso do wake lock em um wake lock comum para todo o Sensors Multi-HAL, o que minimiza o bloqueio e o desbloqueio chamadas.

Sensores O Multi-HAL 2 também possui alguns recursos de segurança integrados. Ele lida com situações em que o FMQ do sensor está cheio ou em que a estrutura do sensor do Android é reiniciada e o estado do sensor precisa ser redefinido. Além disso, quando os eventos são postados na classe HalProxy , mas a estrutura do sensor não consegue aceitar os eventos imediatamente, o Sensors Multi-HAL pode mover os eventos para um thread em segundo plano para permitir que o trabalho continue em todos os sub-HALs enquanto aguarda os eventos Para ser postado.

Código-fonte e implementação de referência

Todos os sensores Multi-HAL estão disponíveis em hardware/interfaces/sensors/common/default/2.X/multihal/ . Aqui estão os ponteiros para alguns recursos.

  • HalProxy.h : O objeto HalProxy é instanciado por Sensores multi-HAL e trata da passagem de dados dos sub-HALs para a estrutura do sensor.
  • HalProxy.cpp : A implementação de HalProxy contém toda a lógica necessária para comunicação multiplex entre sub-HALs e a estrutura do sensor.
  • SubHal.h : A interface ISensorsSubHal define a interface que os sub-HALs devem seguir para serem compatíveis com HalProxy . O sub-HAL implementa o método de inicialização para que o objeto HalProxyCallback possa ser usado para postEvents e createScopedWakelock .

    Para implementações Multi-HAL 2.0, use a versão 2.0 do SubHal.h .

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/ : Esses testes de unidade verificam a implementação do HalProxy .

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ : Este exemplo de implementação de sub-HAL usa sensores falsos para gerar dados falsos. Útil para testar como vários sub-HALs interagem em um dispositivo.

Implementação

Esta seção descreve como implementar Sensores Multi-HAL nas seguintes situações:

Usando os Sensores Multi-HAL com os Sensores AIDL HAL

Para permitir a capacidade multi-HAL com os Sensores AIDL HAL, importe o módulo de camada de calço AIDL Multi-HAL, que se encontra em hardware/interfaces/sensors/aidl/default/multihal/ . O módulo trata da conversão entre os tipos de definição HAL dos sensores AIDL e HIDL e define um wrapper em torno da interface multi-HAL descrita em Implementando Sensores Multi-HAL 2.1 . A camada de calço AIDL multi-HAL é compatível com dispositivos que implementam Sensores Multi-HAL 2.1.

A camada de calço AIDL multi-HAL permite que você exponha o rastreador de cabeça e os tipos de sensor IMU de eixo limitado nos Sensores AIDL HAL. Para usar esses tipos de sensores definidos pela interface AIDL HAL, defina o campo type na estrutura SensorInfo na implementação getSensorsList_2_1() . Isso é seguro porque os campos do tipo de sensor com base em número inteiro dos sensores HAL AIDL e HIDL não se sobrepõem.

Implementando Sensores Multi-HAL 2.1

Para implementar os Sensores Multi-HAL 2.1 em um novo dispositivo, siga estas etapas:

  1. Implemente a interface ISensorsSubHal conforme descrito em SubHal.h .
  2. Implemente o método SubHal.h sensorsHalGetSubHal_2_1
  3. Adicione um destino cc_library_shared para construir o sub-HAL recém-implementado. Ao adicionar o destino:

    1. Certifique-se de que o destino seja enviado para algum lugar na partição do fornecedor do dispositivo.
    2. No arquivo de configuração localizado em /vendor/etc/sensors/hals.conf , adicione o caminho para a biblioteca em uma nova linha. Se necessário, crie o arquivo hals.conf .

    Para obter um exemplo de entrada Android.bp para criar uma biblioteca sub-HAL, consulte hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp .

  4. Remova todas as entradas android.hardware.sensors do arquivo manifest.xml , que contém a lista de HALs compatíveis no dispositivo.

  5. Remova todos os arquivos android.hardware.sensors service e service.rc do arquivo device.mk e adicione android.hardware.sensors@2.1-service.multihal e android.hardware.sensors@2.1-service.multihal.rc a PRODUCT_PACKAGES .

Na inicialização, o HalProxy iniciado, procura o sub-HAL recém-implementado e o inicializa chamando sensorsHalGetSubHal_2_1 .

Portabilidade de Sensores Multi-HAL 2.0 para Multi-HAL 2.1

Para portar do Multi-HAL 2.0 para o Multi-HAL 2.1, implemente a interface SubHal e recompile seu sub-HAL.

Estas são as diferenças entre as interfaces 2.0 e 2.1 SubHal :

  • IHalProxyCallback usa os tipos criados na versão 2.1 da ISensors.hal .
  • A função initialize() passa um novo IHalProxyCallback em vez do da interface 2.0 SubHal
  • Sub-HALs devem implementar getSensorsList_2_1 e injectSensorData_2_1 em vez de getSensorsList e injectSensorData , pois esses métodos usam os novos tipos adicionados na versão 2.1 da especificação ISensors.hal .
  • Sub-HALs devem expor sensorsHalGetSubHal_2_1 em vez de sensorsHalGetSubHal para que o Multi-HAL os trate como sub-HALs da versão 2.1.

Portabilidade de Sensores HAL 2.0

Ao atualizar para Sensores Multi-HAL 2.0 a partir de Sensores HAL 2.0 , certifique-se de que a implementação de HAL atenda aos seguintes requisitos.

Inicializando o HAL

Sensores HAL 2.0 tem uma função de inicialização que permite que o serviço de sensor passe FMQs e um retorno de chamada de sensor dinâmico. No Sensors Multi-HAL 2.0, a função initialize() passa um único retorno de chamada que deve ser usado para postar eventos do sensor, obter wake locks e notificar sobre conexões e desconexões dinâmicas do sensor.

Postar eventos do sensor na implementação do Multi-HAL

Em vez de postar eventos do sensor por meio do FMQ, o sub-HAL deve gravar eventos do sensor no IHalProxyCallback quando os eventos do sensor estiverem disponíveis.

Eventos WAKE_UP

Nos Sensores HAL 2.0, o HAL pode gerenciar o wake lock para sua implementação. Nos Sensores Multi-HAL 2.0, os sub-HALs permitem que a implementação do Multi-HAL gerencie wake locks e pode solicitar que um wake lock seja adquirido invocando createScopedWakelock . Um wake lock com escopo bloqueado deve ser adquirido e passado para postEvents ao postar eventos de ativação para a implementação Multi-HAL.

Sensores dinâmicos

Sensores O Multi-HAL 2.0 requer que onDynamicSensorsConnected e onDynamicSensorsDisconnected em IHalProxyCallback sejam chamados sempre que as conexões do sensor dinâmico forem alteradas. Esses retornos de chamada estão disponíveis como parte do ponteiro IHalProxyCallback fornecido por meio da função initialize() .

Portabilidade de Sensores HAL 1.0

Ao atualizar para Sensores Multi-HAL 2.0 a partir de Sensores HAL 1.0 , certifique-se de que a implementação de HAL atenda aos seguintes requisitos.

Inicializando o HAL

A função initialize() deve ser suportada para estabelecer o retorno de chamada entre a implementação sub-HAL e Multi-HAL.

Expondo os sensores disponíveis

No Sensors Multi-HAL 2.0, a função getSensorsList() deve retornar o mesmo valor durante a inicialização de um único dispositivo, mesmo nas reinicializações de sensores HAL. Isso permite que a estrutura tente restabelecer as conexões do sensor se o servidor do sistema for reiniciado. O valor retornado por getSensorsList() pode mudar depois que o dispositivo executa uma reinicialização.

Postar eventos do sensor na implementação do Multi-HAL

No Sensors HAL 2.0, em vez de esperar que poll() seja chamado, o sub-HAL deve gravar eventos de sensor proativamente em IHalProxyCallback sempre que eventos de sensor estiverem disponíveis.

Eventos WAKE_UP

Nos Sensores HAL 1.0, o HAL pode gerenciar o wake lock para sua implementação. Nos Sensores Multi-HAL 2.0, os sub-HALs permitem que a implementação do Multi-HAL gerencie wake locks e pode solicitar que um wake lock seja adquirido invocando createScopedWakelock . Um wake lock com escopo bloqueado deve ser adquirido e passado para postEvents ao postar eventos de ativação para a implementação Multi-HAL.

Sensores dinâmicos

No Sensors HAL 1.0, os sensores dinâmicos são retornados através da função poll() . Sensores O Multi-HAL 2.0 requer que onDynamicSensorsConnected e onDynamicSensorsDisconnected em IHalProxyCallback sejam chamados sempre que as conexões do sensor dinâmico forem alteradas. Esses retornos de chamada estão disponíveis como parte do ponteiro IHalProxyCallback fornecido por meio da função initialize() .

Portabilidade de Sensores Multi-HAL 1.0

Para portar uma implementação existente do Sensors Multi-HAL 1.0 , siga estas etapas.

  1. Certifique-se de que a configuração HAL dos sensores esteja localizada em /vendor/etc/sensors/hals.conf. Isso pode envolver mover o arquivo localizado em /system/etc/sensors/hals.conf .
  2. Remova quaisquer referências a hardware/hardware.h hardware/sensors.h , pois eles não são compatíveis com HAL 2.0.
  3. Porta sub-HALs conforme descrito em Portabilidade de Sensores Hal 1.0 .
  4. Defina os Sensores Multi-HAL 2.0 como o HAL designado seguindo as etapas 3 e 4 na seção Implementando Sensores Mutli-HAL 2.0 .

Validação

Executando VTS

Ao integrar um ou mais sub-HALs com Sensores Multi-Hal 2.1, use o Vendor Test Suite (VTS) para garantir que suas implementações de sub-HAL atendam a todos os requisitos definidos pela interface Sensors HAL.

Para executar apenas os testes de sensores VTS quando o VTS estiver configurado em uma máquina host, execute os seguintes comandos:

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_0Target && \
  vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_1Target

Se você estiver executando a camada de correção AIDL Multi-HAL, execute VtsAidlHalSensorsTargetTest .

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

Executando testes de unidade

Os testes de unidade em HalProxy_test.cpp testam HalProxy usando sub-HALs falsos que são instanciados no teste de unidade e não são carregados dinamicamente. Ao criar um novo sub-HAL, esses testes devem servir como um guia sobre como adicionar testes de unidade que verificam se o novo sub-HAL foi implementado corretamente.

Para executar os testes, execute os seguintes comandos:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

Testando com os sub-HALs falsos

Os sub-HALs falsos são implementações fictícias da interface ISensorsSubHal . As sub-HALs expõem diferentes listas de sensores. Quando os sensores são ativados, eles postam periodicamente eventos de sensor gerados automaticamente para HalProxy com base nos intervalos especificados em uma determinada solicitação de sensor.

Os sub-HALs falsos podem ser usados ​​para testar como o código Multi-HAL completo funciona com outros sub-HALs carregados no sistema e para enfatizar vários aspectos do código Multi-HAL dos Sensores.

Dois sub-HALs falsos estão disponíveis em hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ .

Para construir e enviar os sub-HALs falsos para um dispositivo, execute as seguintes etapas:

  1. Execute os seguintes comandos para compilar e enviar os três sub-HALs falsos diferentes para o dispositivo:

    $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
    mma
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  2. Atualize a configuração HAL dos sensores em /vendor/etc/sensors/hals.conf com os caminhos para os sub-HALs falsos.

    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  3. Reinicie o HalProxy e carregue os novos sub-HALs listados no arquivo config.

    adb shell stop
    adb shell start
    

Depuração

Os desenvolvedores podem depurar a estrutura usando o comando lshal . Para solicitar a saída de depuração dos Sensores HAL, execute o seguinte comando:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

As informações sobre o estado atual do HalProxy e seus sub-HALs são enviadas para o terminal. Abaixo é mostrado um exemplo da saída do comando para o objeto HalProxy e sub-HALs falsos.

Internal values:
  Threads are running: true
  Wakelock timeout start time: 200 ms ago
  Wakelock timeout reset time: 73208 ms ago
  Wakelock ref count: 0
  # of events on pending write queue: 0
  # of non-dynamic sensors across all subhals: 8
  # of dynamic sensors across all subhals: 0
SubHals (2):
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2

Se o número especificado para # of events on pending write queue for um número grande (1000 ou mais), isso indica que há muitos eventos pendentes para serem gravados na estrutura de sensores. Isso indica que o serviço do sensor está travado ou travou e não está processando eventos do sensor, ou que um grande lote de eventos do sensor foi postado recentemente de um sub-HAL.

Se a contagem de referências de wake lock for maior que 0 , isso significa que HalProxy adquiriu um wake lock. Isso só deve ser maior que 0 se um ScopedWakelock estiver sendo mantido intencionalmente ou se os eventos de ativação foram enviados para HalProxy e não foram processados ​​pela estrutura do sensor.

O descritor de arquivo passado para o método de depuração de HalProxy é passado para cada sub-HAL, de modo que os desenvolvedores devem implementar o método de depuração como parte da interface ISensorsSubHal .