A camada de abstração de hardware de sensores (HAL) é a interface entre a estrutura do sensor Android e os sensores de um dispositivo, como um acelerômetro ou giroscópio. O Sensors HAL define as funções que devem ser implementadas para permitir que a estrutura controle os sensores.
Os sensores HAL 2.0 estão disponíveis no Android 10 e superior para dispositivos novos e atualizados. O Sensors HAL 2.0 é baseado no Sensors HAL 1.0 , mas possui várias diferenças importantes, que o impedem de ser compatível com versões anteriores. Sensores HAL 2.0 usa Fast Message Queues (FMQs) para enviar eventos de sensor do HAL para a estrutura de sensor Android.
Os sensores HAL 2.1 estão disponíveis no Android 11 e superior para dispositivos novos e atualizados. Sensors HAL 2.1 é uma iteração do Sensors HAL 2.0 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 Sensores HAL 2.1 está dentro da definição 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 Sensores HAL 2.0 está dentro da definição 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 Sensores HAL 2.0 e HAL 2.1
Para implementar Sensores HAL 2.0 ou 2.1, um objeto deve estender a interface ISensors
e implementar todas as funções definidas em 2.0/ISensors.hal
ou 2.1/ISensors.hal
.
Inicialize o HAL
O Sensors HAL deve ser inicializado pela estrutura do sensor Android antes de poder ser usado. A estrutura 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 para o Sensors HAL: dois descritores FMQ e um ponteiro para um objeto ISensorsCallback
.
O HAL usa o primeiro descritor para criar o Event FMQ usado para gravar eventos de sensor na estrutura. O HAL usa o segundo descritor para criar o Wake Lock FMQ usado para sincronizar quando o HAL libera seu wake lock para eventos do sensor WAKE_UP
. O HAL deve salvar um ponteiro para o objeto ISensorsCallback
para que quaisquer funções de retorno de chamada necessárias possam ser invocadas.
A função initialize()
ou initialize_2_1()
deve ser a primeira função chamada ao inicializar o HAL dos Sensores.
Expor sensores disponíveis
Para obter 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. Esta função retorna uma lista de sensores, cada um identificado exclusivamente por seu identificador. O identificador de um determinado sensor não deve mudar quando o processo que hospeda o HAL dos Sensores for reiniciado. Os identificadores podem mudar nas reinicializações do dispositivo e nas reinicializações do servidor do sistema.
Se vários sensores compartilharem o mesmo tipo de sensor e propriedade de ativação, o primeiro sensor da lista será chamado de sensor padrão e será retornado aos aplicativos que utilizam a função getDefaultSensor(int sensorType, bool wakeUp)
.
Estabilidade da lista de sensores
Após a reinicialização do Sensors HAL, se os dados retornados por getSensorsList()
ou getSensorsList_2_1()
indicarem uma alteração significativa em comparação com a lista de sensores recuperada antes da reinicialização, a estrutura 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 uma determinada alça está faltando ou possui atributos alterados, ou onde novos sensores são introduzidos. Embora reiniciar o tempo de execução do Android seja prejudicial para o usuário, ele é necessário porque a estrutura do Android não pode mais atender ao contrato da API do Android de que os sensores estáticos (não dinâmicos) não mudam durante a vida útil de um aplicativo. Isso também pode impedir que a estrutura restabeleça solicitações de sensores ativos feitas por aplicativos. Portanto, os fornecedores de HAL são aconselhados a evitar alterações evitáveis na lista de sensores.
Para garantir alças de sensor estáveis, o HAL deve mapear deterministicamente um determinado sensor físico no dispositivo para sua alça. Embora nenhuma implementação específica seja exigida pela interface HAL dos Sensores, os desenvolvedores têm diversas 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 depende do 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()
. Esta lista de sensores esperados pode ser compilada no binário HAL ou armazenada em um arquivo de configuração no sistema de arquivos, e a ordem de aparecimento pode ser usada para derivar identificadores estáveis. Embora a melhor solução dependa dos detalhes específicos de implementação do seu HAL, o principal requisito é que os identificadores do sensor não mudem nas reinicializações do HAL.
Configurar sensores
Antes de um sensor ser ativado, ele deve ser configurado com um período de amostragem e latência máxima de relatório usando a função batch()
.
Um sensor deve poder ser reconfigurado a qualquer momento usando batch()
sem perda de dados do sensor.
Período de amostragem
O período de amostragem tem um significado diferente dependendo do tipo de sensor que está sendo configurado:
- Contínuo: Os eventos do sensor são gerados em uma taxa contínua.
- On-change: Os eventos não são gerados mais rapidamente que o período de amostragem e podem ser gerados a uma taxa mais lenta que o período de amostragem se o valor medido não mudar.
- One-shot: O período de amostragem é ignorado.
- Especial: Para obter 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 relatórios
A latência máxima de relatório define o tempo máximo em nanossegundos que os eventos podem ser atrasados e armazenados no FIFO de hardware antes de serem gravados no Event FMQ por meio do HAL enquanto o SoC está ativo.
Um valor zero significa que os eventos devem ser relatados assim que forem medidos, ignorando completamente o FIFO ou esvaziando o FIFO assim que um evento do sensor estiver presente no FIFO.
Por exemplo, um acelerômetro ativado a 50 Hz com latência máxima de relatório de zero gatilhos interrompe 50 vezes por segundo quando o SoC está ativo.
Quando a latência máxima de relatório é superior a zero, os eventos do sensor não precisam de ser comunicados assim que são detetados. Os eventos podem ser armazenados temporariamente no hardware FIFO e relatados em lotes, desde que nenhum evento seja atrasado 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 o SoC mude para um modo de menor consumo de energia enquanto o sensor captura e agrupa dados em lote.
Cada evento tem um carimbo de data/hora associado a ele. Atrasar o horário em que um evento é relatado não deve afetar o carimbo de data/hora do evento. O carimbo de data/hora deve ser preciso e corresponder ao horário em que o evento ocorreu fisicamente, e não ao horário em que foi relatado.
Para obter informações e requisitos adicionais sobre como relatar eventos de sensor com latência máxima de relatório diferente de zero, consulte Lote .
Ativar sensores
A estrutura habilita e desabilita sensores usando a função activate()
. Antes de ativar um sensor, a estrutura deve primeiro configurar o sensor usando batch()
.
Depois que um sensor for desativado, eventos de sensor adicionais desse sensor não deverão ser gravados no Event FMQ.
Sensores de descarga
Se um sensor estiver configurado para armazenar dados do sensor em lote, a estrutura poderá forçar uma liberação 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 imediatamente gravados no Event FMQ. O Sensors HAL deve anexar um evento flush complete ao final dos eventos do sensor que são gravados como resultado de uma chamada para flush()
.
A liberação acontece de forma assíncrona (ou seja, esta função deve retornar imediatamente). Se a implementação usar um único FIFO para vários sensores, esse FIFO será liberado e o evento flush complete será adicionado apenas para o sensor especificado.
Se o sensor especificado não tiver FIFO (sem buffer possível) ou se o FIFO estiver vazio no momento da chamada, flush()
ainda deverá ser bem-sucedido e enviar um evento de liberação completa para esse sensor. Isto se aplica a todos os sensores, exceto sensores de disparo único.
Se flush()
for chamado para um sensor único, então flush()
deverá retornar BAD_VALUE
e não gerar um evento de liberação completa.
Gravar eventos do sensor no FMQ
O Event FMQ é usado pelo Sensors HAL para enviar eventos de sensor para a estrutura de sensor Android.
O Event FMQ é um FMQ sincronizado, o que significa que qualquer tentativa de gravar mais eventos no FMQ do que o espaço disponível permite resulta em falha na gravação. Nesse caso, o HAL deve determinar se deve escrever o conjunto atual de eventos como dois grupos menores de eventos ou escrever todos os eventos juntos quando houver espaço suficiente disponível.
Quando o Sensors HAL gravou o número desejado de eventos de sensor no Event FMQ, o Sensors HAL deve notificar a estrutura de que os eventos estão prontos gravando o bit EventQueueFlagBits::READ_AND_PROCESS
na função EventFlag::wake
do Event FMQ. O EventFlag pode ser criado a partir do Event FMQ usando EventFlag::createEventFlag
e a função getEventFlagWord()
do Event FMQ.
Os sensores HAL 2.0/2.1 suportam write
e writeBlocking
no Event FMQ. A implementação padrão fornece uma referência para usar write
. Se a função writeBlocking
for usada, o sinalizador readNotification
deverá ser definido como EventQueueFlagBits::EVENTS_READ
, que é definido pela estrutura quando ela lê eventos do Event FMQ. O sinalizador de notificação de gravação deve ser definido como EventQueueFlagBits::READ_AND_PROCESS
, que notifica a estrutura de que eventos foram gravados no Event FMQ.
Eventos WAKE_UP
Eventos WAKE_UP
são eventos de sensor que fazem com que o processador de aplicativos (AP) seja ativado e manipule o evento imediatamente. Sempre que um evento WAKE_UP
é gravado no Event FMQ, o Sensors HAL deve proteger um wake lock para garantir que o sistema permaneça ativo até que a estrutura possa lidar com o evento. Ao receber um evento WAKE_UP
, a estrutura protege seu próprio wake lock, permitindo que o Sensors HAL libere seu wake lock. Para sincronizar quando o Sensors HAL libera seu wake lock, use o Wake Lock FMQ.
O Sensors HAL deve ler o Wake Lock FMQ para determinar o número de eventos WAKE_UP
que a estrutura manipulou. O HAL só deverá liberar seu wake lock para eventos WAKE_UP
se o número total de eventos WAKE_UP
não tratados for zero. Depois de tratar os eventos do sensor, a estrutura conta o número de eventos marcados como eventos WAKE_UP
e grava esse número de volta no Wake Lock FMQ.
A estrutura define a notificação de gravação WakeLockQueueFlagBits::DATA_WRITTEN
no Wake Lock FMQ sempre que grava dados no Wake Lock FMQ.
Sensores dinâmicos
Sensores dinâmicos são sensores que não fazem parte fisicamente do dispositivo, mas podem ser usados como entrada para o dispositivo, como um gamepad com acelerômetro.
Quando um sensor dinâmico é conectado, a função onDynamicSensorConnected
em ISensorsCallback
deve ser chamada a partir do Sensors HAL. Isso notifica a estrutura do novo sensor dinâmico e permite que o sensor seja controlado através da estrutura 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
deve ser chamada para que a estrutura possa remover qualquer sensor que não esteja mais disponível.
Canal direto
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 no Event FMQ, ignorando o Android Sensors Framework. Um cliente que registra um canal direto deve ler os eventos do sensor diretamente da memória que foi usada para criar o canal direto e não receberá os eventos do sensor através do framework. A função configDirectReport()
é semelhante a batch()
para operação normal e configura o canal de reporte direto.
As funções registerDirectChannel()
e unregisterDirectChannel()
criam ou destroem um novo canal direto.
Modos de operação
A função setOperationMode()
permite que a estrutura configure um sensor para que a estrutura possa injetar dados do sensor no sensor. Isto é útil para testes, especialmente para algoritmos que existem abaixo da estrutura.
A função injectSensorData()
no HAL 2.0 e a função injectSensorsData_2_1()
no HAL 2.0 são normalmente usadas para enviar parâmetros operacionais para o HAL dos Sensores. A função também pode ser usada para injetar eventos de sensor em um sensor específico.
Validação
Para validar sua implementação dos Sensores HAL, execute os testes CTS e VTS do sensor.
Testes CTS
Os testes Sensor CTS existem em testes CTS automatizados e no aplicativo CTS Verifier manual.
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 de sensores, lotes e taxas de eventos de sensores.
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 relatem valores precisos.
Passar nos testes CTS é fundamental para garantir que o dispositivo em teste atenda a todos os requisitos do CDD.
Testes VTS
Os testes VTS para sensores HAL 2.0 estão localizados em hardware/interfaces/sensors/2.0/vts . Os testes VTS para Sensores HAL 2.1 estão localizados em hardware/interfaces/sensors/2.1/vts . Esses testes garantem que o Sensors HAL seja implementado corretamente e que todos os requisitos de ISensors.hal
e ISensorsCallback.hal
sejam atendidos adequadamente.
Atualize para sensores HAL 2.1 de 2.0
Ao atualizar para Sensors HAL 2.1 a partir de 2.0, sua implementação HAL deve incluir os métodos initialize_2_1()
, getSensorsList_2_1()
e injectSensorsData_2_1()
, juntamente com os tipos HAL 2.1. Esses métodos devem atender aos mesmos requisitos descritos para o HAL 2.0 acima.
Como as HALs de versões secundárias devem suportar todas as funções das HALs anteriores, as HALs 2.1 devem suportar a inicialização como HALs 2.0. Para evitar a complexidade do suporte a ambas as versões do HAL, é altamente recomendável usar o Multi-HAL 2.1.
Para obter um exemplo de como implementar seu próprio Sensors 2.1 HAL, consulte Sensors.h .
Atualize para sensores HAL 2.0 de 1.0
Ao atualizar para Sensores HAL 2.0 a partir de 1.0, certifique-se de que sua implementação HAL atenda aos seguintes requisitos.
Inicialize o HAL
A função initialize()
deve ser suportada para estabelecer FMQs entre a estrutura e o HAL.
Expor sensores disponíveis
No Sensors HAL 2.0, a função getSensorsList()
deve retornar o mesmo valor durante a inicialização de um único dispositivo, mesmo durante as reinicializações do Sensors HAL. Um novo requisito da função getSensorsList()
é que ela deve retornar o mesmo valor durante a inicialização de um único dispositivo, mesmo durante as reinicializações do Sensors HAL. 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.
Gravar eventos do sensor no FMQ
Em vez de esperar que poll()
seja chamado, no Sensors HAL 2.0, o Sensors HAL deve gravar proativamente eventos de sensor no Event FMQ sempre que eventos de sensor estiverem disponíveis. O HAL também é responsável por escrever os bits corretos no EventFlag
para causar uma leitura do FMQ dentro da estrutura.
Eventos WAKE_UP
No Sensors HAL 1.0, o HAL foi capaz de liberar seu wake lock para qualquer evento WAKE_UP
em qualquer chamada subsequente para poll()
depois que um WAKE_UP
foi postado em poll()
porque isso indicava que a estrutura havia processado todos os eventos do sensor e obtido um wake lock, se necessário. Como, no Sensors HAL 2.0, o HAL não sabe mais quando a estrutura processou eventos gravados no FMQ, o Wake Lock FMQ permite que a estrutura se comunique com o HAL quando tiver manipulado eventos WAKE_UP
.
No Sensors HAL 2.0, o wake lock protegido pelo Sensors HAL para eventos WAKE_UP
deve começar com SensorsHAL_WAKEUP
.
Sensores dinâmicos
Os sensores dinâmicos foram retornados usando a função poll()
no Sensors HAL 1.0. Sensors HAL 2.0 exige que onDynamicSensorsConnected
e onDynamicSensorsDisconnected
em ISensorsCallback
sejam chamados sempre que as conexões de sensores dinâmicos mudarem. Esses retornos de chamada estão disponíveis como parte do ponteiro ISensorsCallback
fornecido por meio da função initialize()
.
Modos de operação
O modo DATA_INJECTION
para sensores WAKE_UP
deve ser suportado em Sensores HAL 2.0.
Suporte multi-HAL
Sensors HAL 2.0 e 2.1 suportam multi-HAL usando a estrutura Sensors Multi-HAL . Para obter detalhes de implementação, consulte Portando de Sensores HAL 1.0 .