Sensores Multi-HAL

O Sensors Multi-HAL é um framework que permite que as HALs de sensores sejam executadas junto com outras HALs de sensores. O Sensors Multi-HAL carrega dinamicamente as sub-HALs de sensores armazenadas como bibliotecas dinâmicas na partição do fornecedor e oferece a elas um objeto de callback que pode processar a postagem de eventos e a aquisição e liberação do wake lock. Uma sub-HAL de sensores é uma HAL de sensores integrada a um objeto compartilhado na partição do fornecedor e usada pelo framework Multi-HAL. Essas sub-HALs não dependem umas das outras nem do código Multi-HAL que contém a função principal do processo.

Os Sensores Multi-HAL 2.1, disponíveis em dispositivos com o Android 11 ou mais recente, são uma iteração dos Sensores Multi-HAL 2.0, que oferecem suporte ao carregamento de sub-HALs que podem expor o tipo de sensor do ângulo de dobradiça. Para oferecer suporte a este tipo de sensor, os sub-HALs precisam usar as APIs sub-HAL definidas no cabeçalho SubHal 2.1.

Para dispositivos com o Android 13 ou mais recente que usam a HAL de sensores AIDL, é possível usar a camada de shim Multi-HAL para permitir a capacidade Multi-HAL. Para detalhes da implementação, consulte Como usar o Sensors Multi-HAL com a HAL de sensores AIDL.

Diferença entre o Sensors Multi-HAL 2 e o Sensors HAL 2

O Sensors Multi-HAL 2, disponível em dispositivos com o Android 10 ou mais recente, introduz várias abstrações sobre o Sensors HAL 2 para facilitar a interação com as APIs HAL. O Sensors Multi-HAL 2 introduz a classe HalProxy para processar a implementação da interface Sensors HAL 2 e a V2_1/SubHal (ou V2_0/SubHal) interface 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 transmite uma classe IHalProxyCallback em vez de duas FMQs e ISensorsCallback.
  • As sub-HALs precisam implementar uma função de depuração para fornecer informações de depuração em relatórios de bugs.
  • As sub-HALs precisam implementar uma função de nome para que a sub-HAL carregada possa ser distinguida de outras sub-HALs.

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

O Sensors Multi-HAL 2 também tem alguns recursos de segurança integrados. Ele processa situações em que a FMQ do sensor está cheia ou em que o framework de sensor do Android é reiniciado e o estado do sensor precisa ser redefinido. Além disso, quando os eventos são postados na classe HalProxy, mas o framework de sensor não consegue aceitar os eventos imediatamente, o Sensors Multi-HAL pode mover os eventos para uma linha de execução em segundo plano para permitir que o trabalho continue em todas as sub-HALs enquanto aguarda a postagem dos eventos.

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

Todo o código do Sensors Multi-HAL está disponível em hardware/interfaces/sensors/common/default/2.X/multihal/. Confira a seguir alguns links para recursos.

  • HalProxy.h: O objeto HalProxy é instanciado pelo Sensors Multi-HAL e processa a transmissão de dados das sub-HALs para o framework de sensor.
  • HalProxy.cpp: A implementação de HalProxy contém toda a lógica necessária para multiplexar a comunicação entre sub-HALs e o framework de sensor.
  • SubHal.h: a interface ISensorsSubHal define a interface que as sub-HALs precisam seguir para serem compatíveis com HalProxy. A sub-HAL implementa o método de inicialização para que o objeto HalProxyCallback possa ser usado para postEvents e createScopedWakelock.

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

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

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

Implementação

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

Como usar o Sensors Multi-HAL com a HAL de sensores AIDL

Para permitir a capacidade Multi-HAL com a HAL de sensores AIDL, importe o módulo de camada de shim AIDL Multi-HAL, que está em hardware/interfaces/sensors/aidl/default/multihal/. O módulo processa a conversão entre os tipos de definição de HAL de sensores AIDL e HIDL e define um wrapper em torno da interface Multi-HAL descrita em Implementar o Sensors Multi-HAL 2.1. A camada de shim AIDL Multi-HAL é compatível com dispositivos que implementam o Sensors Multi-HAL 2.1.

A camada de shim AIDL Multi-HAL permite expor os tipos de sensor principal e o rastreador de IMU de eixo limitado na HAL de sensores AIDL. Para usar esses tipos de sensor definidos pela interface AIDL HAL, defina o campo type na estrutura SensorInfo na implementação getSensorsList_2_1(). Isso é seguro porque os campos de tipo de sensor com suporte a números inteiros das HALs de sensores AIDL e HIDL não se sobrepõem.

Implementar o Sensors Multi-HAL 2.1

Para implementar o Sensors Multi-HAL 2.1 em um novo dispositivo, siga estas etapas:

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

    1. Verifique se o destino foi 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 conferir um exemplo de entrada Android.bp para criar uma biblioteca de sub-HAL, consulte hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.

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

  5. Remova todos os arquivos de serviço android.hardware.sensors 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, HalProxy é iniciado, procura a sub-HAL recém-implementada e a inicializa chamando sensorsHalGetSubHal_2_1.

Como migrar do Sensors Multi-HAL 2.0 para o Multi-HAL 2.1

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

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

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

Como migrar do Sensors HAL 2.0

Ao fazer upgrade para o Sensors Multi-HAL 2.0 do Sensors HAL 2.0, verifique se a implementação da HAL atende aos requisitos a seguir.

Inicializar a HAL

O Sensors HAL 2.0 tem uma função de inicialização que permite que o serviço de sensor transmita FMQs e um callback de sensor dinâmico. No Sensors Multi-HAL 2.0, a função initialize() transmite um único callback que precisa ser usado para postar eventos de sensor, receber wake locks e notificar a conexão e desconexão de sensores dinâmicos.

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

Em vez de postar eventos de sensor pela FMQ, a sub-HAL precisa gravar eventos de sensor no IHalProxyCallback quando os eventos de sensor estão disponíveis.

Eventos WAKE_UP

No Sensors HAL 2.0, a HAL pode gerenciar o wake lock para a implementação. No Sensors Multi-HAL 2.0, as sub-HALs permitem que a implementação do Multi-HAL gerencie wake locks e podem solicitar que um wake lock seja adquirido invocando createScopedWakelock. Um wake lock com escopo bloqueado precisa ser adquirido e transmitido para postEvents ao postar eventos de ativação na implementação do Multi-HAL.

Sensores dinâmicos

O Sensors Multi-HAL 2.0 exige que onDynamicSensorsConnected e onDynamicSensorsDisconnected em IHalProxyCallback sejam chamados sempre que as conexões de sensores dinâmicos mudarem. Esses callbacks estão disponíveis como parte do ponteiro IHalProxyCallback fornecido pela função initialize().

Como migrar do Sensors HAL 1.0

Ao fazer upgrade para o Sensors Multi-HAL 2.0 do Sensors HAL 1.0, verifique se a implementação da HAL atende aos requisitos a seguir.

Inicializar a HAL

A função initialize() precisa ter suporte para estabelecer o callback entre a sub-HAL e a implementação do Multi-HAL.

Expor sensores disponíveis

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

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

No Sensors HAL 2.0, em vez de aguardar poll()a chamada, a sub-HAL precisa gravar proativamente eventos de sensor em IHalProxyCallback sempre que os eventos de sensor estiverem disponíveis.

Eventos WAKE_UP

No Sensors HAL 1.0, a HAL pode gerenciar o wake lock para a implementação. No Sensors Multi-HAL 2.0, as sub-HALs permitem que a implementação do Multi-HAL gerencie wake locks e podem solicitar que um wake lock seja adquirido invocando createScopedWakelock. Um wake lock com escopo bloqueado precisa ser adquirido e transmitido para postEvents ao postar eventos de ativação na implementação do Multi-HAL.

Sensores dinâmicos

No Sensors HAL 1.0, os sensores dinâmicos são retornados pela função poll(). O Sensors Multi-HAL 2.0 exige que onDynamicSensorsConnected e onDynamicSensorsDisconnected em IHalProxyCallback sejam chamados sempre que as conexões de sensores dinâmicos mudarem. Esses callbacks estão disponíveis como parte do ponteiro IHalProxyCallback fornecido pela função initialize().

Como migrar do Sensors Multi-HAL 1.0

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

  1. Verifique se a configuração da HAL de sensores está localizada em /vendor/etc/sensors/hals.conf. Isso pode envolver a movimentação do arquivo localizado em /system/etc/sensors/hals.conf.
  2. Remova todas as referências a hardware/hardware.h e hardware/sensors.h , já que elas não têm suporte para a HAL 2.0.
  3. Migre as sub-HALs conforme descrito em Como migrar do Sensors Hal 1.0.
  4. Defina o Sensors Multi-HAL 2.0 como a HAL designada seguindo as etapas 3 e 4 na seção Implementar o Sensors Multi-HAL 2.0.

Validação

Executar o VTS

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

Para executar apenas os testes do VTS de sensores 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 shim AIDL Multi-HAL, execute VtsAidlHalSensorsTargetTest.

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

Executar testes de unidade

Os testes de unidade em HalProxy_test.cpp testam HalProxy usando sub-HALs falsas que são instanciadas no teste de unidade e não são carregadas dinamicamente. Ao criar uma nova sub-HAL, esses testes devem servir como um guia sobre como adicionar testes de unidade que verifiquem se a nova sub-HAL foi implementada corretamente.

Para executar os testes, execute os seguintes comandos:

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

Testar com as sub-HALs falsas

As sub-HALs falsas 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 no HalProxy com base nos intervalos especificados em uma determinada solicitação de sensor.

As sub-HALs falsas podem ser usadas para testar como o código Multi-HAL completo funciona com outras sub-HALs carregadas no sistema e para enfatizar vários aspectos do código Sensors Multi-HAL.

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

Para criar e enviar as sub-HALs falsas para um dispositivo, siga estas etapas:

  1. Execute os seguintes comandos para criar e enviar as três sub-HALs falsas 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 da HAL de sensores em /vendor/etc/sensors/hals.conf com os caminhos para as sub-HALs falsas.

    /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 as novas sub-HALs listadas na configuração.

    adb shell stop
    adb shell start

Depuração

Os desenvolvedores podem depurar o framework usando o comando lshal. Para solicitar a saída de depuração da HAL de sensores, 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 das sub-HALs são geradas no terminal. Confira abaixo um exemplo da resposta ao comando para o objeto HalProxy e sub-HALs falsas.

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 (1.000 ou mais), isso indica que há muitos eventos pendentes para serem gravados no framework de sensores. Isso indica que o serviço de sensor está em deadlock ou falhou e não está processando eventos de sensor, ou que um grande lote de eventos de sensor foi postado recentemente de uma sub-HAL.

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

O descritor do arquivo transmitido ao método de depuração do HalProxy é transmitido a cada sub-HAL. Portanto, os desenvolvedores precisam implementar o método de depuração como parte da interface ISensorsSubHal.