A camada de abstração de hardware (HAL) de sensores é a interface entre o framework de sensores do Android e os sensores de um dispositivo, como um acelerômetro ou giroscópio. O HAL de sensores define as funções que precisam ser implementadas para permitir que o framework controle os sensores.
A HAL de sensores 2.0 está disponível no Android 10 e versões mais recentes para dispositivos novos e atualizados. O HAL 2.0 de sensores é baseado no HAL 1.0 de sensores, mas tem várias diferenças importantes que impedem a compatibilidade com versões anteriores. A HAL 2.0 de sensores usa filas rápidas de mensagens (FMQs) para enviar eventos de sensor da HAL para o framework de sensores do Android.
O HAL de sensores 2.1 está disponível no Android 11 e versões mais recentes
para dispositivos novos e atualizados. A HAL 2.1 de sensores é uma iteração da HAL 2.0 de sensores
que expõe o tipo de sensor
HINGE_ANGLE
e atualiza vários métodos para aceitar o tipo HINGE_ANGLE
.
Interface HAL 2.1
A principal fonte de documentação para a HAL de sensores 2.1 está na definição da HAL em
hardware/interfaces/sensors/2.1/ISensors.hal.
Se houver um conflito de requisitos entre esta página e ISensors.hal
,
use o requisito em ISensors.hal
.
Interface HAL 2.0
A principal fonte de documentação para a HAL 2.0 de sensores está na definição da HAL em
hardware/interfaces/sensors/2.0/ISensors.hal.
Se houver um conflito de requisitos entre esta página e ISensors.hal
,
use o requisito em ISensors.hal
.
Implementar a HAL 2.0 e a HAL 2.1 de sensores
Para implementar o Sensors HAL 2.0 ou 2.1, um objeto precisa estender a interface ISensors
e implementar todas as funções definidas em 2.0/ISensors.hal
ou 2.1/ISensors.hal
.
Inicializar a HAL
A HAL de sensores precisa ser inicializada pela estrutura de sensores do Android antes de poder ser usada. O framework chama a função initialize()
para HAL 2.0 e
a função initialize_2_1()
para HAL 2.1 para fornecer três parâmetros à
HAL de sensores: dois descritores de FMQ e um ponteiro para um objeto ISensorsCallback
.
A HAL usa o primeiro descritor para criar a FMQ de eventos usada para gravar eventos
do sensor no framework. A HAL usa o segundo descritor para criar a FMQ de Wake
Lock usada para sincronizar quando a HAL libera o bloqueio de despertar para eventos de sensor WAKE_UP
. A HAL precisa salvar um ponteiro para o objeto ISensorsCallback
para que as funções de callback necessárias possam ser invocadas.
A função initialize()
ou initialize_2_1()
precisa ser a primeira chamada ao inicializar a HAL de sensores.
Expor sensores disponíveis
Para conferir uma lista de todos os sensores estáticos disponíveis no dispositivo, use a função
getSensorsList()
no HAL 2.0 e a função getSensorsList_2_1()
no
HAL 2.1. Essa função retorna uma lista de sensores, cada um identificado exclusivamente pelo
identificador. O identificador de um determinado sensor não pode mudar quando o processo
que hospeda a HAL de sensores é reiniciado. Os identificadores podem mudar em reinicializações de dispositivos e
em reinicializações do servidor do sistema.
Se vários sensores compartilharem o mesmo tipo e propriedade de despertar, o primeiro sensor na lista será chamado de sensor padrão e será retornado aos apps que usam a função getDefaultSensor(int sensorType, bool wakeUp)
.
Estabilidade da lista de sensores
Depois de uma reinicialização da HAL de sensores, se os dados retornados por getSensorsList()
ou getSensorsList_2_1()
indicarem uma mudança significativa em comparação com a lista de sensores recuperada antes da reinicialização, o framework vai acionar uma reinicialização do tempo de execução do Android. Mudanças significativas na lista de sensores incluem casos em que um sensor com um determinado identificador está ausente ou teve atributos alterados, ou em que novos sensores foram introduzidos. Embora a reinicialização do ambiente de execução do Android seja prejudicial
para o usuário, ela é necessária porque o framework Android não consegue mais atender ao
contrato da API Android, em que sensores estáticos (não dinâmicos) não mudam durante o
ciclo de vida de um app. Isso também pode impedir que o framework restabeleça
solicitações de sensores ativos feitas por apps. Portanto, recomendamos que os fornecedores de HAL evitem mudanças desnecessárias na lista de sensores.
Para garantir identificadores de sensor estáveis, a HAL precisa mapear deterministicamente um determinado sensor físico no dispositivo para o identificador dele. Embora nenhuma implementação específica seja exigida pela interface HAL de sensores, os desenvolvedores têm várias opções disponíveis para atender a esse requisito.
Por exemplo, a lista de sensores pode ser classificada usando uma combinação dos atributos fixos de cada sensor, como fornecedor, modelo e tipo de sensor. Outra opção se baseia no fato de que o conjunto de sensores estáticos do dispositivo é fixo no hardware. Portanto, o HAL precisa saber quando todos os sensores esperados concluíram a inicialização antes de retornar de getSensorsList()
ou getSensorsList_2_1()
. Essa lista de sensores esperados pode ser compilada no binário da HAL ou armazenada em um arquivo de configuração no sistema de arquivos, e a ordem de aparição pode ser usada para derivar identificadores estáveis. Embora a melhor solução dependa dos detalhes específicos da implementação da sua HAL, o requisito principal é que os identificadores de sensores não mudem entre reinicializações da HAL.
Configurar sensores
Antes de ser ativado, um sensor precisa ser configurado com um período de amostragem e uma latência máxima de geração de relatórios usando a função batch()
.
Um sensor precisa poder ser reconfigurado a qualquer momento usando batch()
sem perda de dados.
Período de amostragem
O período de amostragem tem um significado diferente com base no tipo de sensor que está sendo configurado:
- Contínuo: os eventos de sensor são gerados a uma taxa contínua.
- Na mudança: os eventos são gerados em uma taxa não superior ao período de amostragem e podem ser gerados em uma taxa mais lenta do que o período de amostragem se o valor medido não mudar.
- Única vez: o período de amostragem é ignorado.
- Especial: para mais detalhes, consulte Tipos de sensores.
Para saber mais sobre a interação entre um período de amostragem e os modos de relatório de um sensor, consulte Modos de relatório.
Latência máxima de geração de relatórios
A latência máxima de geração de relatórios define o tempo máximo em nanossegundos que os eventos podem ser atrasados e armazenados no FIFO de hardware antes de serem gravados na FMQ de eventos pela HAL enquanto o SoC está ativo.
Um valor zero significa que os eventos precisam ser informados assim que forem medidos, ignorando completamente o FIFO ou esvaziando-o assim que um evento do sensor estiver presente.
Por exemplo, um acelerômetro ativado a 50 Hz com uma latência máxima de relatório de zero aciona interrupções 50 vezes por segundo quando o SoC está ativo.
Quando a latência máxima de geração de relatórios é maior que zero, os eventos do sensor não precisam ser informados assim que são detectados. Os eventos podem ser armazenados temporariamente no FIFO de hardware e informados em lotes, desde que nenhum evento seja atrasado por mais do que a latência máxima de relatório. Todos os eventos desde o lote anterior são registrados e retornados de uma só vez. Isso reduz o número de interrupções enviadas ao SoC e permite que ele mude para um modo de menor consumo de energia enquanto o sensor captura e agrupa dados.
Cada evento tem um carimbo de data/hora associado. Atrasar o momento em que um evento é informado não pode afetar o carimbo de data/hora dele. O carimbo de data/hora precisa ser preciso e corresponder ao momento em que o evento aconteceu fisicamente, e não ao momento em que foi informado.
Para mais informações e requisitos sobre como informar eventos de sensor com latência máxima de relatório diferente de zero, consulte Lotes.
Ativar sensores
O framework ativa e desativa sensores usando a função activate()
.
Antes de ativar um sensor, o framework precisa configurá-lo usando batch()
.
Depois que um sensor é desativado, outros eventos dele não podem ser gravados na FMQ de eventos.
Sensores de descarga
Se um sensor estiver configurado para agrupar dados, o framework poderá forçar
uma descarga imediata de eventos de sensor em lote chamando flush()
. Isso faz com que os eventos de sensor em lote para o identificador de sensor especificado sejam gravados imediatamente na FMQ de eventos. A HAL de sensores precisa anexar um evento de conclusão de limpeza
ao final dos eventos de sensor gravados como resultado de uma chamada para
flush()
.
A limpeza é feita de forma assíncrona. Ou seja, essa função precisa retornar imediatamente. Se a implementação usar uma única FIFO para vários sensores, ela será limpa, e o evento de limpeza concluída será adicionado apenas para o sensor especificado.
Se o sensor especificado não tiver um FIFO (nenhum buffer possível) ou se o FIFO estiver
vazio no momento da chamada, flush()
ainda precisará ser concluído e enviar um evento de conclusão
de limpeza para esse sensor. Isso se aplica a todos os sensores, exceto os de
uma só vez.
Se flush()
for chamado para um sensor único, flush()
vai retornar
BAD_VALUE
e não vai gerar um evento de conclusão de limpeza.
Gravar eventos de sensor na FMQ
A FMQ de eventos é usada pela HAL de sensores para enviar eventos de sensores ao framework de sensores do Android.
A FMQ de eventos é uma FMQ sincronizada, o que significa que qualquer tentativa de gravar mais eventos do que o espaço disponível permite resulta em uma gravação com falha. Nesse caso, a HAL precisa determinar se grava o conjunto atual de eventos como dois grupos menores ou todos os eventos juntos quando houver espaço suficiente.
Quando a HAL de sensores gravar o número desejado de eventos do sensor na
FMQ de eventos, ela precisará notificar o framework de que os eventos estão prontos
gravando o bit EventQueueFlagBits::READ_AND_PROCESS
na função
EventFlag::wake
da FMQ de eventos. O EventFlag pode ser criado no Event FMQ
usando EventFlag::createEventFlag
e a função getEventFlagWord()
do Event FMQ.
As HALs 2.0/2.1 de sensores são compatíveis com write
e writeBlocking
na FMQ de eventos.
A implementação padrão fornece uma referência para usar write
. Se a função
writeBlocking
for usada, a flag readNotification
precisará ser definida como
EventQueueFlagBits::EVENTS_READ
, que é definida pelo framework quando ele lê
eventos da FMQ de eventos. A flag de notificação de gravação precisa ser definida como
EventQueueFlagBits::READ_AND_PROCESS
, o que notifica o framework de que os eventos
foram gravados na FMQ de eventos.
Eventos WAKE_UP
Os eventos WAKE_UP
são eventos de sensor que fazem com que o processador de aplicativos (AP) seja
ativado e processe o evento imediatamente. Sempre que um evento WAKE_UP
é gravado
na FMQ de eventos, a HAL de sensores precisa proteger um wake lock para garantir que o
sistema permaneça ativo até que o framework possa processar o evento. Ao receber um evento WAKE_UP
, o framework protege o próprio wake lock, permitindo que o HAL de sensores libere o dele. Para sincronizar quando a HAL de sensores
liberar o bloqueio de despertar, use a FMQ de bloqueio de despertar.
O HAL de sensores precisa ler o FMQ de Wake Lock para determinar o número de eventos WAKE_UP
processados pelo framework. A HAL só deve liberar o bloqueio de despertar
para eventos WAKE_UP
se o número total de eventos WAKE_UP
não processados for zero.
Depois de processar os eventos do sensor, o framework conta o número de eventos marcados como WAKE_UP
e grava esse número de volta na FMQ de Wake Lock.
O framework define a notificação de gravação WakeLockQueueFlagBits::DATA_WRITTEN
na FMQ de bloqueio de despertar sempre que grava dados nela.
Sensores dinâmicos
Sensores dinâmicos não fazem parte fisicamente do dispositivo, mas podem ser usados como entrada para ele, como um gamepad com um acelerômetro.
Quando um sensor dinâmico é conectado, a função onDynamicSensorConnected
em
ISensorsCallback
precisa ser chamada da HAL de sensores. Isso notifica o framework do novo sensor dinâmico e permite que ele seja controlado pelo framework e que os eventos do sensor sejam consumidos pelos clientes.
Da mesma forma, quando um sensor dinâmico é desconectado, a função
onDynamicSensorDisconnected
em ISensorsCallback
precisa ser chamada para
que o framework possa remover qualquer sensor que não esteja mais disponível.
Canal direto
O canal direto é um método de operação em que os eventos do sensor são gravados em uma memória específica em vez de na FMQ de eventos, ignorando o Android Sensors Framework. Um cliente que registra um canal direto precisa ler os eventos do sensor diretamente da memória usada para criar o canal direto e não vai receber os eventos do sensor pelo framework. A função configDirectReport()
é semelhante a batch()
para operação normal e configura o canal de
relatório direto.
As funções registerDirectChannel()
e unregisterDirectChannel()
criam ou destroem um novo canal direto.
Modos de operação
A função setOperationMode()
permite que o framework configure um sensor
para que ele possa injetar dados no sensor. Isso é útil para testes, principalmente para algoritmos que existem abaixo da estrutura.
A função injectSensorData()
na HAL 2.0 e a função injectSensorsData_2_1()
na HAL 2.0 são normalmente usadas para transmitir parâmetros operacionais à HAL de sensores. A função também pode ser usada para injetar eventos de sensor em um
sensor específico.
Validação
Para validar a implementação da HAL de sensores, execute os testes do CTS e do VTS de sensores.
Testes do CTS
Os testes do CTS de sensor estão presentes nos testes automatizados do CTS e no app manual CTS Verifier.
Os testes automatizados estão localizados em cts/tests/sensor/src/android/hardware/cts. Esses testes verificam a funcionalidade padrão dos sensores, como ativação, agrupamento em lotes e taxas de eventos do sensor.
Os testes do CTS Verifier estão localizados em cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Esses testes exigem entrada manual do operador de teste e garantem que os sensores informem valores precisos.
A aprovação nos testes do CTS é essencial para garantir que o dispositivo em teste atenda a todos os requisitos do CDD.
Testes VTS
Os testes VTS para a HAL 2.0 de sensores estão localizados em
hardware/interfaces/sensors/2.0/vts.
Os testes VTS para Sensors HAL 2.1 estão localizados em
hardware/interfaces/sensors/2.1/vts.
Esses testes garantem que o HAL de sensores seja implementado corretamente e que todos os requisitos em ISensors.hal
e ISensorsCallback.hal
sejam atendidos adequadamente.
Fazer upgrade da HAL 2.0 para a 2.1 de sensores
Ao fazer upgrade da HAL de sensores 2.0 para a 2.1, sua implementação da HAL precisa incluir os métodos
initialize_2_1()
, getSensorsList_2_1()
e injectSensorsData_2_1()
junto com os tipos da HAL 2.1. Esses métodos precisam atender aos mesmos
requisitos descritos para a HAL 2.0 acima.
Como as HALs de versão secundária precisam oferecer suporte a todas as funções das HALs anteriores, as HALs 2.1 precisam ser inicializadas como HALs 2.0. Para evitar a complexidade de oferecer suporte às duas versões da HAL, recomendamos usar a Multi-HAL 2.1.
Para um exemplo de como implementar seu próprio HAL 2.1 de sensores, consulte Sensors.h.
Fazer upgrade da HAL 1.0 de sensores para a 2.0
Ao fazer upgrade da HAL 1.0 para a 2.0 de sensores, verifique se a implementação da HAL atende aos seguintes requisitos.
Inicializar a HAL
A função initialize()
precisa ser compatível para estabelecer FMQs entre o
framework e a HAL.
Expor sensores disponíveis
No HAL 2.0 de sensores, a função getSensorsList()
precisa retornar o mesmo valor durante uma única inicialização do dispositivo, mesmo em reinicializações do HAL de sensores. Um novo requisito da função getSensorsList()
é que ela 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 do sensor se o servidor do sistema
for reiniciado. O valor retornado por getSensorsList()
pode mudar depois que o dispositivo
for reiniciado.
Gravar eventos de sensor na FMQ
Em vez de esperar que poll()
seja chamado, na HAL 2.0 de sensores, a HAL de sensores precisa gravar proativamente eventos de sensor na FMQ de eventos sempre que eles estiverem disponíveis. A HAL também é responsável por gravar os bits corretos em
EventFlag
para causar uma leitura de FMQ no framework.
Eventos WAKE_UP
Na HAL 1.0 de sensores, a HAL podia liberar o bloqueio de despertar para qualquer evento WAKE_UP
em qualquer chamada subsequente para poll()
depois que um WAKE_UP
era postado em poll()
. Isso indicava que o framework havia processado todos os eventos do sensor e obtido um bloqueio de despertar, se necessário. Como na HAL 2.0 de sensores,
a HAL não sabe mais quando o framework processou eventos gravados na
FMQ, a FMQ de bloqueio de despertar permite que o framework se comunique com a HAL quando ela
processou eventos de WAKE_UP
.
Na HAL 2.0 de sensores, o bloqueio de despertar protegido pela HAL de sensores para eventos WAKE_UP
precisa começar com SensorsHAL_WAKEUP
.
Sensores dinâmicos
Os sensores dinâmicos foram retornados usando a função poll()
na HAL 1.0 de sensores.
A HAL de sensores 2.0 exige que onDynamicSensorsConnected
e onDynamicSensorsDisconnected
em ISensorsCallback
sejam chamados sempre que as conexões de sensores dinâmicos mudarem. Esses callbacks estão disponíveis como parte do
ponteiro ISensorsCallback
fornecido pela função initialize()
.
Modos de operação
O modo DATA_INJECTION
para sensores WAKE_UP
precisa ser compatível com a HAL de sensores
2.0.
Suporte a várias HALs
As HALs de sensores 2.0 e 2.1 oferecem suporte a multi-HAL usando o framework Sensors Multi-HAL. Para detalhes da implementação, consulte Portar da HAL 1.0 de sensores.