O Sensors Multi-HAL é uma estrutura que permite que HALs de sensores sejam executados junto com outros HALs de sensores. O Sensors Multi-HAL carrega dinamicamente sub-HALs de sensores armazenados como bibliotecas dinâmicas na partição do fornecedor e fornece a eles um objeto de retorno de chamada que pode lidar com a postagem de eventos e a aquisição e liberação do wake lock. Um sub-HAL de sensores é um HAL de sensores integrado a um objeto compartilhado na partição do fornecedor e usado pela estrutura multi-HAL. Esses sub-HALs não dependem um do outro ou do código multi-HAL que contém a função principal do processo.
Sensors Multi-HAL 2.1, disponível em dispositivos com Android 11 ou superior, é uma iteração do Sensors Multi-HAL 2.0 que oferece suporte ao 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 Sensors AIDL HAL , você pode usar a camada de correção multi-HAL para permitir o recurso multi-HAL. Para obter detalhes de implementação, consulte Usando o Sensors Multi-HAL com o Sensors AIDL HAL .
Diferença entre Sensores Multi-HAL 2 e Sensores HAL 2
Sensors Multi-HAL 2, disponível em dispositivos com Android 10 ou superior, introduz diversas abstrações no Sensors HAL 2 para facilitar a interação com APIs HAL. Sensors 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 eISensorsCallback
. - Sub-HALs devem implementar uma função de depuração para fornecer informações de depuração em relatórios de erros.
- Os sub-HALs devem implementar uma função de nome para que o sub-HAL carregado possa ser diferenciado de outros sub-HALs.
A principal diferença entre os Sensores Multi-HAL 2 e os 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. Nos bastidores, o Sensors Multi-HAL gerencia todas as interações com os FMQs para garantir a entrega oportuna de eventos de sensor para todos os sub-HALs. É altamente recomendável que os sub-HALs usem o método createScopedWakelock
para delegar a carga de cronometrar os wake locks para o Sensors Multi-HAL e para 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.
O Sensors 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 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 aceitá-los 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
O código Multi-HAL de todos os sensores está disponível em hardware/interfaces/sensors/common/default/2.X/multihal/
. Aqui estão dicas para alguns recursos.
-
HalProxy.h
: O objetoHalProxy
é instanciado por Sensors multi-HAL e lida com a passagem de dados dos sub-HALs para a estrutura do sensor. -
HalProxy.cpp
: A implementação doHalProxy
contém toda a lógica necessária para multiplexar a comunicação entre sub-HALs e a estrutura do sensor. SubHal.h
: A interfaceISensorsSubHal
define a interface que os sub-HALs devem seguir para serem compatíveis comHalProxy
. O sub-HAL implementa o método de inicialização para que o objetoHalProxyCallback
possa ser usado parapostEvents
ecreateScopedWakelock
.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çãoHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: Este exemplo de implementação 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
- Implementando Sensores Multi-HAL 2.1
- Portando de Sensores Multi-HAL 2.0 para Multi-HAL 2.1
- Portando de Sensores HAL 2.0
- Portando de Sensores HAL 1.0
- Portando de Sensores Multi-HAL 1.0
Use os Sensores Multi-HAL com os Sensores AIDL HAL
Para permitir o recurso multi-HAL com o Sensors AIDL HAL, importe o módulo de camada de correção AIDL Multi-HAL, que é encontrado em hardware/interfaces/sensors/aidl/default/multihal/ . O módulo lida com a 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 expor o rastreador de cabeça e os tipos de sensores 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 apoiado por número inteiro dos sensores AIDL e HIDL HAL não se sobrepõem.
Implementar Sensores Multi-HAL 2.1
Para implementar Sensors Multi-HAL 2.1 em um novo dispositivo, siga estas etapas:
- Implemente a interface
ISensorsSubHal
conforme descrito emSubHal.h
. - Implemente o método
sensorsHalGetSubHal_2_1
emSubHal.h
. Adicione um destino
cc_library_shared
para construir o sub-HAL recém-implementado. Ao adicionar o alvo:- Certifique-se de que o destino seja enviado para algum lugar na partição do fornecedor do dispositivo.
- 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 arquivohals.conf
.
Para obter um exemplo de entrada
Android.bp
para construir uma biblioteca sub-HAL, consultehardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Remova todas as entradas
android.hardware.sensors
do arquivomanifest.xml
, que contém a lista de HALs suportados no dispositivo.Remova todos os arquivos
android.hardware.sensors
service eservice.rc
do arquivodevice.mk
e adicioneandroid.hardware.sensors@2.1-service.multihal
eandroid.hardware.sensors@2.1-service.multihal.rc
aPRODUCT_PACKAGES
.
Na inicialização, HalProxy
inicia, procura o sub-HAL recém-implementado e o inicializa chamando sensorsHalGetSubHal_2_1
.
Porta dos Sensores Multi-HAL 2.0 a Multi-HAL 2.1
Para migrar 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 especificaçãoISensors.hal
. - A função
initialize()
passa um novoIHalProxyCallback
em vez daquele da interface 2.0SubHal
- Sub-HALs devem implementar
getSensorsList_2_1
einjectSensorData_2_1
em vez degetSensorsList
einjectSensorData
, pois esses métodos usam os novos tipos adicionados na versão 2.1 da especificaçãoISensors.hal
. - Os sub-HALs devem expor
sensorsHalGetSubHal_2_1
em vez desensorsHalGetSubHal
para que o Multi-HAL os trate como sub-HALs da versão 2.1.
Porta dos Sensores HAL 2.0
Ao atualizar para Sensors Multi-HAL 2.0 a partir de Sensors HAL 2.0 , certifique-se de que a implementação HAL atenda aos seguintes requisitos.
Inicialize o HAL
Sensores HAL 2.0 possui uma função de inicialização que permite que o serviço do sensor passe FMQs e um retorno de chamada dinâmico do sensor. No Sensors Multi-HAL 2.0, a função initialize()
passa um único retorno de chamada que deve ser usado para postar eventos de sensor, obter wake locks e notificar sobre conexões e desconexões de sensores dinâmicos.
Pós eventos de sensor para a implementação Multi-HAL
Em vez de postar eventos de sensor por meio do FMQ, o sub-HAL deve gravar eventos de sensor no IHalProxyCallback
quando eventos de sensor estiverem disponíveis.
Eventos WAKE_UP
Nos Sensores HAL 2.0, o HAL pode gerenciar o wake lock para sua implementação. No Sensors Multi-HAL 2.0, os sub-HALs permitem que a implementação Multi-HAL gerencie wake locks e podem 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 na implementação Multi-HAL.
Sensores dinâmicos
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 retornos de chamada estão disponíveis como parte do ponteiro IHalProxyCallback
fornecido por meio da função initialize()
.
Porta dos Sensores HAL 1.0
Ao atualizar para Sensors Multi-HAL 2.0 a partir de Sensors HAL 1.0 , certifique-se de que a implementação HAL atenda aos seguintes requisitos.
Inicialize o HAL
A função initialize()
deve ser suportada para estabelecer o retorno de chamada entre a implementação sub-HAL e Multi-HAL.
Expor 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 entre reinicializações HAL dos sensores. Isso permite que a estrutura tente restabelecer as conexões dos sensores se o servidor do sistema for reiniciado. O valor retornado por getSensorsList()
pode mudar após a reinicialização do dispositivo.
Pós eventos de sensor para a implementação Multi-HAL
No Sensors HAL 2.0, em vez de esperar que poll()
seja chamado, o sub-HAL deve gravar proativamente eventos de sensor 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. No Sensors Multi-HAL 2.0, os sub-HALs permitem que a implementação 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 na implementação Multi-HAL.
Sensores dinâmicos
No Sensors HAL 1.0, os sensores dinâmicos são retornados por meio da função poll()
. 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 retornos de chamada estão disponíveis como parte do ponteiro IHalProxyCallback
fornecido por meio da função initialize()
.
Porta de Sensores Multi-HAL 1.0
Para portar uma implementação existente do Sensors Multi-HAL 1.0 , siga estas etapas.
- 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
. - Remova quaisquer referências a
hardware/hardware.h
ehardware/sensors.h
, pois elas não são suportadas pelo HAL 2.0. - Porte sub-HALs conforme descrito em Portando de Sensores Hal 1.0 .
- Defina Sensors 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
Execute o VTS
Ao integrar um ou mais sub-HALs ao Sensors 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 VTS dos 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 correção AIDL Multi-HAL, execute VtsAidlHalSensorsTargetTest
.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Execute testes unitários
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 uma nova sub-HAL, esses testes devem servir como um guia sobre como adicionar testes unitários que verifiquem se a nova sub-HAL está implementada corretamente.
Para executar os testes, execute os seguintes comandos:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Teste com os sub-HALs falsos
Os falsos sub-HALs são implementações fictícias da interface ISensorsSubHal
. Os sub-HALs expõem diferentes listas de sensores. Quando os sensores são ativados, eles publicam periodicamente eventos de sensor gerados automaticamente no 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 criar e enviar sub-HALs falsos para um dispositivo, execute as seguintes etapas:
Execute os seguintes comandos para criar 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
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
Reinicie
HalProxy
e carregue os novos sub-HALs listados na configuração.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 do Sensors 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 entã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. Isto indica que o serviço de sensor está num impasse ou falhou e não está a processar eventos de sensor, ou que um grande lote de eventos de sensor foi publicado recentemente a partir de um sub-HAL.
Se a contagem de referências do wake lock for maior que 0
, isso significa HalProxy
adquiriu um wake lock. Isso só deverá ser maior que 0
se um ScopedWakelock
estiver sendo mantido intencionalmente ou se os eventos de ativação tiverem sido enviados ao HalProxy
e não tiverem sido processados pela estrutura do sensor.
O descritor de arquivo passado para o método de depuração do HalProxy
é passado para cada sub-HAL, portanto, os desenvolvedores devem implementar o método de depuração como parte da interface ISensorsSubHal
.