O Sensors Multi-HAL é um framework que permite que HALs de sensores sejam executados ao lado de 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 atribui a eles um objeto de callback que pode processar a postagem de eventos e a aquisição e liberação do bloqueio de despertar. Um sub-HAL de sensores é uma HAL de sensores integrada a um objeto compartilhado na partição do fornecedor e usada pela estrutura multi-HAL. Esses sub-HALs não dependem um do outro 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 versões mais recentes, 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 de ângulo de dobradiça. Para oferecer suporte a esse tipo de sensor, os sub-HALs precisam usar as APIs sub-HAL definidas no cabeçalho SubHal 2.1.
Para dispositivos com 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 a Multi-HAL de sensores 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 Android
10 ou mais recente,
introduz várias abstrações sobre a HAL de sensores
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 da 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 "initialize" transmite uma classe
IHalProxyCallback
em vez de duas FMQs eISensorsCallback
. - Os sub-HALs precisam implementar uma função de depuração para fornecer informações de depuração em relatórios de bugs.
- Os sub-HALs precisam implementar uma função de nome para que o sub-HAL carregado possa ser distinguido de outros sub-HALs.
A principal diferença entre o Multi-HAL de sensores 2 e o HAL de sensores 2 está nas
funções de inicialização. Em vez de fornecer FMQs, a interface IHalProxyCallback
fornece dois métodos: um para postar eventos de sensor no framework
de sensores e outro para criar bloqueios de despertar. Por baixo dos panos, a Multi-HAL de sensores 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 os sub-HALs usem o método
createScopedWakelock
para delegar a responsabilidade de expirar bloqueios de despertar ao
Sensores Multi-HAL e centralizar o uso de bloqueios de despertar em um bloqueio de despertar comum
para todo o Sensores 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 sensores do Android
é reiniciado e o estado do sensor precisa ser redefinido. Além disso, quando os eventos são
postados na classe HalProxy
, mas a estrutura de sensores não consegue aceitar
os eventos imediatamente, o Multi-HAL de sensores pode mover os eventos para uma linha de execução
em segundo plano para permitir que o trabalho continue em todos os 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 alguns recursos.
HalProxy.h
: o objetoHalProxy
é instanciado pela multi-HAL de sensores e processa a transmissão de dados das sub-HALs para o framework de sensores.HalProxy.cpp
: A implementação deHalProxy
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 precisam seguir para serem compatíveis comHalProxy
. O sub-HAL implementa o método initialize para que o objetoHalProxyCallback
possa ser usado parapostEvents
ecreateScopedWakelock
.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 doHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: esta implementação de sub-HAL de exemplo 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 o Sensors Multi-HAL nas seguintes situações:
- Como usar a Multi-HAL de sensores com a HAL de sensores AIDL
- Implementação do Sensors Multi-HAL 2.1
- Portar do Sensors Multi-HAL 2.0 para o Multi-HAL 2.1
- Portar da HAL 2.0 de sensores
- Portar da HAL 1.0 de sensores
- Portar do Sensors Multi-HAL 1.0
Usar a Multi-HAL de sensores 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 multi-HAL AIDL, que está em hardware/interfaces/sensors/aidl/default/multihal/. O módulo processa a conversão entre tipos de definição de HAL de sensores AIDL e HIDL e define um wrapper em torno da interface multi-HAL descrita em Implementação de sensores 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 multi-HAL do AIDL permite expor o rastreador principal e os tipos de sensores 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 da HAL 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:
- Implemente a interface
ISensorsSubHal
conforme descrito emSubHal.h
. - Implemente o método
sensorsHalGetSubHal_2_1
emSubHal.h
. Adicione um destino
cc_library_shared
para criar o sub-HAL recém-implementado. Ao adicionar o destino:- Verifique se o destino foi 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 um exemplo de entrada
Android.bp
para criar uma biblioteca de 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 compatíveis no dispositivo.Remova todos os arquivos de serviço
android.hardware.sensors
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, o HalProxy
é iniciado, procura o sub-HAL recém-implementado e
o inicializa chamando
sensorsHalGetSubHal_2_1
.
Portar do Sensors Multi-HAL 2.0 para o Multi-HAL 2.1
Para fazer a portabilidade do Multi-HAL 2.0 para o Multi-HAL 2.1, implemente a
interface SubHal
e recompile o sub-HAL.
Estas são as diferenças entre as interfaces 2.0 e 2.1 SubHal
:
- O
IHalProxyCallback
usa os tipos criados na versão 2.1 da especificaçãoISensors.hal
. - A função
initialize()
transmite um novoIHalProxyCallback
em vez daquele da interface 2.0SubHal
. - Os sub-HALs precisam implementar
getSensorsList_2_1
einjectSensorData_2_1
em vez degetSensorsList
einjectSensorData
, já que esses métodos usam os novos tipos adicionados na versão 2.1 da especificaçãoISensors.hal
. - Os sub-HALs precisam expor
sensorsHalGetSubHal_2_1
em vez desensorsHalGetSubHal
para que o Multi-HAL os trate como sub-HALs da versão 2.1.
Porta da HAL 2.0 de sensores
Ao fazer upgrade para o Sensors Multi-HAL 2.0 da HAL de sensores 2.0, verifique se a implementação da HAL atende aos seguintes requisitos.
Inicializar a HAL
A HAL 2.0 de sensores 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 bloqueios de despertar e notificar sobre conexão e
desconexões de sensores dinâmicos.
Postar eventos do sensor na implementação Multi-HAL
Em vez de postar eventos de sensor pela FMQ, a sub-HAL precisa gravar eventos de sensor no
IHalProxyCallback
quando eles estiverem disponíveis.
Eventos WAKE_UP
No HAL 2.0 de sensores, o HAL pode gerenciar o bloqueio de despertar para a implementação. No
Sensors Multi-HAL 2.0, os sub-HALs permitem que a implementação do Multi-HAL
gerencie wake locks e solicite que um wake lock seja adquirido invocando
createScopedWakelock
.
Um bloqueio de ativação 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 dinâmicas do sensor mudarem. Esses callbacks estão
disponíveis como parte do ponteiro IHalProxyCallback
fornecido pela
função initialize()
.
Porta da HAL de sensores 1.0
Ao fazer upgrade para o Sensors Multi-HAL 2.0 da HAL de sensores 1.0, verifique se a implementação da HAL atende aos seguintes requisitos.
Inicializar a HAL
A função initialize()
precisa ser compatível para estabelecer o callback entre
a sub-HAL e a implementação da 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 do HAL de sensores. 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
for reiniciado.
Postar eventos do sensor na implementação Multi-HAL
Na HAL 2.0 de sensores, em vez de esperar que poll()
seja chamado, a sub-HAL
precisa gravar proativamente eventos de sensor em
IHalProxyCallback
sempre que eles estiverem disponíveis.
Eventos WAKE_UP
Na HAL 1.0 de sensores, a HAL pode gerenciar o bloqueio de despertar para a implementação. No
Sensors Multi-HAL 2.0, os sub-HALs permitem que a implementação do Multi-HAL
gerencie bloqueios de despertar e solicite a aquisição de um bloqueio de despertar invocando
createScopedWakelock
.
Um bloqueio de ativação 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
Na HAL 1.0 de sensores, 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 dinâmicas do sensor mudarem. Esses callbacks estão
disponíveis como parte do ponteiro IHalProxyCallback
fornecido pela
função initialize()
.
Portar do Sensors Multi-HAL 1.0
Para migrar uma implementação atual do Sensors Multi-HAL 1.0, siga estas etapas.
- Verifique se a configuração do 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
. - Remova todas as referências a
hardware/hardware.h
ehardware/sensors.h
porque elas não são compatíveis com a HAL 2.0. - Faça a portabilidade das sub-HALs conforme descrito em Portabilidade da HAL de sensores 1.0.
- Defina o Sensors Multi-HAL 2.0 como o HAL designado seguindo as etapas 3 e 4 na seção Implementação do Sensors Multi-HAL 2.0.
Validação
Executar o VTS
Depois de integrar um ou mais sub-HALs com o Sensors Multi-Hal 2.1, use o Vendor Test Suite (VTS) para garantir que as implementações do sub-HAL atendam a todos os requisitos definidos pela interface HAL de sensores.
Para executar apenas os testes de 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 Multi-HAL da AIDL, 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 falsos que
são instanciados no teste de unidade e não são carregados dinamicamente. Ao criar um
novo sub-HAL, esses testes servem 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
Testar com sub-HALs falsos
Os sub-HALs falsos 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 postam periodicamente eventos 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 de 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 os sub-HALs falsos para um dispositivo, siga estas etapas:
Execute os comandos a seguir para criar e enviar por push os três diferentes sub-HALs falsos 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 do HAL de 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 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 de HalProxy
e seus sub-HALs são enviadas ao terminal. Confira abaixo 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 grande (1.000 ou mais), isso indica que há muitos eventos pendentes para serem gravados na estrutura 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 um sub-HAL.
Se a contagem de referência do wake lock for maior que 0
, isso significa que HalProxy
adquiriu um wake lock. Esse valor só será maior que 0
se um ScopedWakelock
estiver sendo mantido intencionalmente ou se eventos de despertar foram enviados para HalProxy
e não
foram processados pela estrutura do sensor.
O descritor de arquivo transmitido ao método de depuração de HalProxy
é transmitido a cada
sub-HAL. Portanto, os desenvolvedores precisam implementar o método de depuração como parte da
interface ISensorsSubHal
.