O Sensor de várias HALs é um framework que permite que as HALs dos sensores funcionem com outras HALs do sensor. O recurso Sensores Multi-HAL carrega dinamicamente as sub-HALs de sensores armazenadas como bibliotecas dinâmicas na partição do fornecedor e fornece a elas um objeto de callback que pode processar a publicação de eventos e adquirir e liberar o 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 de várias HALs. Essas sub-HALs não dependem umas das outras ou 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 do â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 o Android 13 ou versões mais recentes que usam a HAL de sensores AIDL, use a camada de paliativo multi-HAL para permitir a funcionalidade de várias HAL. Para detalhes de implementação, consulte Como usar sensores multi-HAL com a HAL de sensores AIDL.
Diferença entre os sensores Multi-HAL 2 e os sensores HAL 2
Os sensores Multi-HAL 2, disponíveis em dispositivos com o Android
10 ou versões mais recentes,
introduzem várias abstrações sobre a HAL
2 de sensores para facilitar
a interação com as APIs da HAL. Os sensores Multi-HAL 2 introduzem a classe
HalProxy
para processar a implementação da interface de sensores da 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 transmite uma classe
IHalProxyCallback
em vez de dois FMQs eISensorsCallback
. - 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 distinta de outras 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
oferece dois métodos: um para postar eventos do sensor no framework
e um para criar wake locks. Internamente, o Multi-HAL de sensores
gerencia todas as interações com os FMQs para garantir o envio pontual de
eventos do sensor para todas as sub-HALs. É altamente recomendável que as sub-HALs usem o método
createScopedWakelock
para delegar a carga de tempo limite dos wake locks aos
sensores Multi-HAL e centralizar o uso do wake lock em um único wake lock
comum para todos os sensores multi-HAL, o que minimiza o bloqueio e o desbloqueio de chamadas.
Os sensores Multi-HAL 2 também têm alguns recursos de segurança integrados. Ele lida com situações em que a FMQ do sensor está cheia ou em que o framework do 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 do sensor não consegue aceitar
os eventos imediatamente, os sensores multi-HAL podem 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 publicação dos
eventos.
Código-fonte e implementação de referência
Todos os códigos multi-HAL de sensores estão disponíveis em
hardware/interfaces/sensors/common/default/2.X/multihal/
.
Aqui estão alguns indicadores para alguns recursos.
HalProxy.h
: o objetoHalProxy
é instanciado pelos sensores multi-HAL e processa a transmissão de dados das sub-HALs para o framework do sensor.HalProxy.cpp
: a implementação deHalProxy
contém toda a lógica necessária para multiplexar a comunicação entre sub-HALs e o framework do sensor.SubHal.h
: a interfaceISensorsSubHal
define a interface que as sub-HALs precisam seguir para serem compatíveis comHalProxy
. A 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 de
SubHal.h
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: esses testes de unidade verificam a implementação deHalProxy
.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árias sub-HALs interagem em um dispositivo.
Implementação
Esta seção descreve como implementar os Sensores Multi-HAL nas seguintes situações:
- Como usar a HAL de sensores com a HAL de sensores AIDL
- Como implementar sensores Multi-HAL 2.1
- Portabilidade de sensores Multi-HAL 2.0 para Multi-HAL 2.1
- Portabilidade a partir de sensores HAL 2.0
- Portabilidade a partir de sensores HAL 1.0
- Portabilidade de sensores Multi-HAL 1.0
Usar a HAL de sensores com a HAL de sensores AIDL
Para permitir o recurso de várias HAL com a HAL de sensores AIDL, importe o módulo de camada de paliativo multi-HAL da AIDL, encontrado em hardware/interfaces/sensors/aidl/default/multihal/. O módulo processa a conversão entre os tipos de definição da HAL de sensores AIDL e HIDL e define um wrapper ao redor da interface multi-HAL descrita em Como implementar sensores Multi-HAL 2.1. A camada de paliativo AIDL multi-HAL é compatível com dispositivos que implementam Sensores Multi-HAL 2.1.
A camada de paliativo AIDL multi-HAL permite expor o rastreador principal e
os tipos de sensor de IMU de eixo limitado na HAL de sensores AIDL. Para usar esses tipos de
sensor definidos pela interface da HAL da AIDL, defina o campo type
no
struct SensorInfo
na implementação de getSensorsList_2_1()
. Isso é seguro
porque os campos de tipo de sensor com base em números inteiros da HAL de sensores AIDL e HIDL
não se sobrepõem.
Implemente sensores Multi-HAL 2.1
Para implementar os Sensores 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 a sub-HAL recém-implementada. 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 conferir um exemplo de entrada
Android.bp
para criar 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 com suporte no dispositivo.Remova todos os serviços
android.hardware.sensors
e arquivosservice.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
é iniciado, procura a sub-HAL recém-implementada e
inicializa-a chamando
sensorsHalGetSubHal_2_1
.
Porta dos sensores Multi-HAL 2.0 para Multi-HAL 2.1
Para fazer a portabilidade de Multi-HAL 2.0 para Multi-HAL 2.1, implemente a interface
SubHal
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çãoISensors.hal
.- A função
initialize()
transmite um novoIHalProxyCallback
em vez daquele da interfaceSubHal
2.0 - As 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
. - As sub-HALs precisam expor
sensorsHalGetSubHal_2_1
em vez desensorsHalGetSubHal
para que a Multi-HAL as trate como sub-HALs da versão 2.1.
Porta dos sensores HAL 2.0
Ao fazer upgrade da HAL 2.0 para Sensores Multi-HAL 2.0">, verifique se a implementação da HAL atende aos requisitos a seguir.
Inicializar a HAL
A HAL 2.0 de sensores tem uma função de inicialização que permite que o serviço de sensores
transmita FMQs e um callback de sensor dinâmico. Nos Sensores Multi-HAL 2.0, a
função initialize()
transmite um único callback que precisa ser usado para postar
eventos do sensor, receber wake locks e notificar sobre desconexões e conexões dinâmicas do sensor.
Publicar eventos do sensor na implementação de várias HALs
Em vez de postar eventos do sensor usando a FMQ, a sub-HAL precisa gravar eventos
do sensor no
IHalProxyCallback
quando esses eventos estão disponíveis.
Eventos WAKE_UP
Na HAL de sensores 2.0, a HAL pode gerenciar o wake lock para a implementação. Nos
Sensores Multi-HAL 2.0, as sub-HALs permitem que a implementação da Multi-HAL
gerencie wake locks e podem solicitar que um wake lock seja adquirido invocando
createScopedWakelock
.
Um wake lock de escopo bloqueado precisa ser adquirido e transmitido para postEvents
ao
publicar eventos de ativação para a implementação de várias HAL.
Sensores dinâmicos
Os sensores Multi-HAL 2.0 exigem que onDynamicSensorsConnected
e
onDynamicSensorsDisconnected
em
IHalProxyCallback
sejam chamados sempre que as conexões dinâmicas do sensor mudam. Esses callbacks estão
disponíveis como parte do ponteiro IHalProxyCallback
fornecido pela
função initialize()
.
Porta dos sensores HAL 1.0
Ao fazer upgrade da HAL 1.0 de sensores para Sensores Multi-HAL 2.0, confira 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 da Multi-HAL.
Expor os sensores disponíveis
Nos Sensores Multi-HAL 2.0, a função getSensorsList()
precisa retornar o mesmo
valor durante a inicialização de um único dispositivo, mesmo quando a HAL dos sensores é reiniciada. Isso permite
que o framework tente restabelecer as conexões do sensor se o servidor do sistema
for reiniciado. O valor retornado por getSensorsList()
pode mudar após a reinicialização
do dispositivo.
Publicar eventos do sensor na implementação de várias HALs
Na HAL de sensores 2.0, em vez de esperar que poll()
seja chamado, a sub-HAL
precisa gravar proativamente eventos do sensor em
IHalProxyCallback
sempre que esses eventos estiverem disponíveis.
Eventos WAKE_UP
Na HAL de sensores 1.0, a HAL pode gerenciar o wake lock para a implementação. Nos
Sensores Multi-HAL 2.0, as sub-HALs permitem que a implementação da Multi-HAL
gerencie wake locks e podem solicitar que um wake lock seja adquirido invocando
createScopedWakelock
.
Um wake lock de escopo bloqueado precisa ser adquirido e transmitido para postEvents
ao
publicar eventos de ativação para a implementação de várias HAL.
Sensores dinâmicos
Na HAL 1.0 de sensores, os sensores dinâmicos são retornados pela função poll()
.
Os sensores Multi-HAL 2.0 exigem que onDynamicSensorsConnected
e
onDynamicSensorsDisconnected
em
IHalProxyCallback
sejam chamados sempre que as conexões dinâmicas do sensor mudam. Esses callbacks estão
disponíveis como parte do ponteiro IHalProxyCallback
fornecido pela
função initialize()
.
Porta dos sensores Multi-HAL 1.0
Para fazer a portabilidade de uma implementação já existente de Sensores Multi-HAL 1.0, siga estas etapas.
- Verifique se a configuração da HAL dos sensores está localizada em
/vendor/etc/sensors/hals.conf
. Isso pode envolver mover o arquivo localizado em/system/etc/sensors/hals.conf
. - Remova todas as referências a
hardware/hardware.h
ehardware/sensors.h
, já que elas não têm suporte à HAL 2.0. - Portas sub-HALs, conforme descrito em Portabilidade de sensores Hal 1.0.
- Defina os Sensores Multi-HAL 2.0 como a HAL designada seguindo as etapas 3 e 4 na seção Como implementar sensores Mutli-HAL 2.0.
Validação
Executar VTS
Quando você integrar uma ou mais sub-HALs aos sensores Multi-Hal 2.1, use o Teste de fornecedor (VTS, na sigla em inglês) para garantir que as implementações de sub-HAL atendam a todos os requisitos definidos pela interface da HAL de sensores.
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 paliativo 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 no 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 precisam servir como um guia sobre como adicionar testes de unidade que
verificam 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
Testar com 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 do sensor gerados automaticamente no HalProxy
com base nos intervalos especificados em uma determinada solicitação.
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 estressar vários aspectos do código da Multi-HAL dos sensores.
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:
Execute os comandos abaixo 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
Atualize a configuração da HAL de sensores em
/vendor/etc/sensors/hals.conf
com os caminhos das 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
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 da HalProxy
e das sub-HALs são
saídas para o terminal. Confira abaixo um exemplo da resposta ao comando para o
objeto HalProxy
e sub-HALs fictícias.
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 a serem gravados no framework
dos sensores. Isso indica que o serviço do sensor está bloqueado, falhou e
não está processando eventos do sensor ou que um grande lote de eventos do sensor foi
publicado recentemente em uma sub-HAL.
Se a contagem de referência de wake lock for maior que 0
, isso significa que HalProxy
adquiriu um wake lock. Esse valor só vai ser maior que 0
se um ScopedWakelock
for retido intencionalmente ou se eventos de ativação tiverem sido enviados para HalProxy
e
não tiverem sido processados pelo framework do sensor.
O descritor de arquivos transmitido ao método de depuração HalProxy
é transmitido a cada
sub-HAL. Os desenvolvedores precisam implementar o método de depuração como parte da
interface ISensorsSubHal
.