Ambiente de execução do hub de contexto (CHRE, na sigla em inglês)

Os smartphones contêm vários processadores, cada um otimizado para realizar tarefas diferentes. No entanto, o Android só é executado em um processador: o processador de aplicativos (AP). O AP é ajustado para oferecer um ótimo desempenho em casos de uso com a tela ligada, como jogos, mas consome muita energia para oferecer suporte a recursos que exigem bursts curtos e frequentes de processamento o tempo todo, mesmo quando a tela está desligada. Processadores menores conseguem lidar com essas cargas de trabalho de maneira mais eficiente, concluindo as tarefas sem afetar significativamente a duração da bateria. No entanto, os ambientes de software nesses processadores de baixo consumo são mais limitados e podem variar muito, dificultando o desenvolvimento em várias plataformas.

O ambiente de execução do hub de contexto (CHRE, na sigla em inglês) oferece uma plataforma comum para executar apps em um processador de baixo consumo, com uma API simples, padronizada e integrada. A CHRE facilita para os OEMs de dispositivos e parceiros confiáveis a redução do processamento do AP, a economia de bateria e a melhoria de várias áreas da experiência do usuário, além de ativar uma classe de recursos sempre ativados e contextualizados, especialmente aqueles que envolvem a aplicação de machine learning na detecção de ambiente.

Principais conceitos

O CHRE é o ambiente de software em que pequenos apps nativos, chamados nanoapps, são executados em um processador de baixo consumo de energia e interagem com o sistema usando a API CHRE comum. Para acelerar a implementação adequada das APIs CHRE, uma implementação de referência multiplataforma do CHRE está incluída no AOSP. A implementação de referência inclui código e abstrações comuns para o hardware e o software subjacentes por meio de uma série de camadas de abstração de plataforma (PALs, na sigla em inglês). Os nanoapps quase sempre estão vinculados a um ou mais apps clientes em execução no Android, que interagem com o CHRE e os nanoapps por APIs ContextHubManager de sistema de acesso restrito.

Em um nível alto, é possível fazer comparações entre a arquitetura do CHRE e o Android como um todo. No entanto, há algumas distinções importantes:

  • O CHRE oferece suporte apenas à execução de nanoapps desenvolvidos em código nativo (C ou C++). Não há suporte para Java.
  • Devido a restrições de recursos e limitações de segurança, o CHRE não está aberto para uso por apps Android arbitrários de terceiros. Somente apps confiáveis pelo sistema podem acessar esse recurso.

Também há uma distinção importante entre o conceito de CHRE e um hub de sensores. Embora seja comum usar o mesmo hardware para implementar o hub de sensores e o CHRE, o CHRE em si não oferece os recursos de sensor exigidos pelo HAL de sensores Android. A CHRE está vinculada à HAL do hub de contexto e atua como um cliente de um framework de sensor específico do dispositivo para receber dados do sensor sem envolver o AP.

Arquitetura do framework CHRE

Figura 1. Arquitetura do framework CHRE

HAL do hub de contexto

A camada de abstração de hardware (HAL) do hub de contexto é a interface entre o framework do Android e a implementação CHRE do dispositivo, definida em hardware/interfaces/contexthub. O HAL do hub de contexto define as APIs pelas quais o framework do Android descobre os hubs de contexto disponíveis e os nanoapps, interage com esses nanoapps por meio da transmissão de mensagens e permite que os nanoapps sejam carregados e descarregados. Uma implementação de referência do HAL do hub de contexto que funciona com a implementação de referência do CHRE está disponível em system/chre/host.

Em caso de conflito entre esta documentação e a definição do HAL, a definição do HAL terá precedência.

Inicialização

Quando o Android é inicializado, o ContextHubService invoca a função HAL getHubs() para determinar se há hubs de contexto disponíveis no dispositivo. Essa é uma chamada única de bloqueio, portanto, precisa ser concluída rapidamente para evitar o atraso na inicialização e precisa retornar um resultado preciso, já que novos hubs de contexto não podem ser introduzidos depois.

Carregar e descarregar nanoapps

Um hub de contexto pode incluir um conjunto de nanoapps incluídos na imagem do dispositivo e carregados quando o CHRE é iniciado. Eles são conhecidos como nanoapps pré-carregados e precisam ser incluídos na primeira resposta possível para queryApps().

A HAL do Context Hub também oferece suporte ao carregamento e à remoção dinâmicos de nanoapps no tempo de execução, pelas funções loadNanoApp() e unloadNanoApp(). Os nanoapps são fornecidos à HAL em um formato binário específico para a implementação de hardware e software do CHRE do dispositivo.

Se a implementação para carregar um nanoapp envolver a gravação dele em uma memória não volátil, como o armazenamento flash anexado ao processador que executa o CHRE, a implementação do CHRE sempre precisa ser inicializada com esses nanoapps dinâmicos no estado desativado. Isso significa que nenhum código do nanoapp é executado até que uma solicitação enableNanoapp() seja recebida pelo HAL. Nanoapps pré-carregados podem ser inicializados no estado ativado.

O hub de contexto é reiniciado

Embora não seja esperado que a CHRE seja reiniciada durante o curso da operação normal, ela pode ser necessária para se recuperar de condições inesperadas, como uma tentativa de acessar um endereço de memória não mapeado. Nessas situações, a CHRE é reiniciada independente do Android. O HAL notifica o Android sobre isso pelo evento RESTARTED, que só pode ser enviado depois que o CHRE for reinicializado para aceitar novas solicitações, como queryApps().

Visão geral do sistema CHRE

O CHRE foi projetado com base em uma arquitetura orientada a eventos, em que a unidade principal de computação é um evento transmitido para o ponto de entrada de processamento de eventos de um nanoapp. Embora o framework CHRE possa ter várias linhas de execução, um determinado nanoapp nunca é executado de várias linhas em paralelo. O framework CHRE interage com um determinado nanoapp por um dos três pontos de entrada do nanoapp (nanoappStart(), nanoappHandleEvent() e nanoappEnd()) ou por um callback fornecido em uma chamada anterior da API CHRE. Os nanoapps interagem com o framework CHRE e o sistema subjacente pela API CHRE. A API CHRE oferece um conjunto de recursos básicos, bem como instalações para acessar sinais contextuais, incluindo sensores, GNSS, Wi-Fi, WWAN e áudio, e pode ser estendida com outros recursos específicos do fornecedor para uso por nanoapps específicos.

Sistema de build

Embora o HAL do hub de contexto e outros componentes necessários do lado do AP sejam criados com o Android, o código executado no CHRE pode ter requisitos que o tornam incompatível com o sistema de build do Android, como a necessidade de uma toolchain especializada. Portanto, o projeto CHRE no AOSP oferece um sistema de build simplificado baseado no GNU Make para compilar nanoapps e, opcionalmente, o framework CHRE em bibliotecas que podem ser integradas ao sistema. Os fabricantes de dispositivos que adicionarem suporte ao CHRE precisam integrar o suporte do sistema de build para os dispositivos de destino ao AOSP.

A API CHRE é gravada no padrão de linguagem C99, e a implementação de referência usa um subconjunto restrito de C++11 adequado para apps com recursos limitados.

API CHRE

A API CHRE é uma coleção de arquivos de cabeçalho C que definem a interface de software entre um nanoapp e o sistema. Ele foi projetado para tornar o código de nanoapps compatível com todos os dispositivos que oferecem suporte ao CHRE, o que significa que o código-fonte de um nanoapp não precisa ser modificado para oferecer suporte a um novo tipo de dispositivo, embora possa precisar ser recompilado especificamente para o conjunto de instruções do processador ou a interface binária do aplicativo (ABI, na sigla em inglês) do dispositivo de destino. A arquitetura e o design da API CHRE também garantem que os nanoapps sejam binários compatíveis com diferentes versões da API CHRE, o que significa que um nanoapp não precisa ser recompilado para ser executado em um sistema que implemente uma versão diferente da API CHRE em comparação com a API de destino em que o nanoapp é compilado. Em outras palavras, se um binário de nanoapp for executado em um dispositivo compatível com a API CHRE v1.3 e esse dispositivo for atualizado para oferecer suporte à API CHRE v1.4, o mesmo binário de nanoapp continuará funcionando. Da mesma forma, o nanoapp pode ser executado na API CHRE v1.2 e pode determinar em tempo de execução se ele exige recursos da API v1.3 para ser usado ou se ele pode operar, potencialmente com uma degradação suave do recurso.

Novas versões da API CHRE são lançadas com o Android. No entanto, como a implementação da CHRE faz parte da implementação do fornecedor, a versão da API CHRE com suporte em um dispositivo não está necessariamente vinculada a uma versão do Android.

Resumo da versão

Assim como o esquema de controle de versão do Android HIDL, a API CHRE segue o controle de versão semântica. A versão principal indica a compatibilidade binária, enquanto a versão secundária é incrementada quando os recursos compatíveis com versões anteriores são introduzidos. A API CHRE inclui anotações do código-fonte para identificar qual versão introduziu uma função ou um parâmetro, por exemplo, @since v1.1.

A implementação do CHRE também expõe uma versão de patch específica da plataforma pelo chreGetVersion(), que indica quando correções de bugs ou atualizações menores são feitas na implementação.

Versão 1.0 (Android 7)

Inclui suporte a sensores e recursos principais de nanoapps, como eventos e timers.

Versão 1.1 (Android 8)

Apresenta recursos de localização por localização do GNSS e medições brutas, verificação de Wi-Fi e informações de rede móvel, além de refinamentos gerais para ativar a comunicação entre nanoapps e outras melhorias.

Versão 1.2 (Android 9)

Adiciona suporte a dados de um microfone de baixa potência, medição de RTT do Wi-Fi, notificações de ativação e suspensão de AP e outras melhorias.

Versão 1.3 (Android 10)

Melhora os recursos relacionados aos dados de calibração do sensor, adiciona suporte para limpar dados de sensores em lote sob demanda, define o tipo de sensor de detecção de etapas e amplia os eventos de localização do GNSS com campos de precisão adicionais.

Versão 1.4 (Android 11)

Adiciona suporte a informações de célula 5G, despejo de depuração de nanoapp e outras melhorias.

Recursos obrigatórios do sistema

Embora as fontes de indicadores contextuais, como sensores, sejam categorizadas em áreas de recursos opcionais, algumas funções principais são necessárias em todas as implementações de CHRE. Isso inclui as APIs principais do sistema, como as que configuram timers, enviam e recebem mensagens de clientes no processador de aplicativos, na geração de registros, entre outras. Para detalhes completos, consulte os cabeçalhos da API.

Além dos recursos principais do sistema codificados na API CHRE, também há recursos obrigatórios no nível do sistema do CHRE especificados no nível da HAL do hub de contexto. O mais importante é a capacidade de carregar e descarregar nanoapps dinamicamente.

Biblioteca C/C++ padrão

Para minimizar o uso da memória e a complexidade do sistema, as implementações CHRE precisam oferecer suporte a apenas um subconjunto das bibliotecas C e C++ padrão e dos recursos de linguagem que exigem suporte ao ambiente de execução. Seguindo esses princípios, alguns recursos são excluídos explicitamente devido à memória e às dependências no nível do SO, e outros porque são substituídos por APIs específicas do CHRE mais adequadas. Embora essa não seja uma lista completa, os recursos abaixo não devem ser disponibilizados para nanoapps:

  • Exceções de C++ e informações de tipo de ambiente de execução (RTTI)
  • Suporte à biblioteca padrão de multithreading, incluindo cabeçalhos C++11 <thread>, <mutex>, <atomic>, <future>
  • Bibliotecas de entrada/saída padrão C e C++
  • Biblioteca de modelos padrão (STL) do C++
  • Biblioteca de expressões regulares padrão do C++
  • Alocação de memória dinâmica usando funções padrão (por exemplo, malloc, calloc, realloc, free, operator new) e outras funções de biblioteca padrão que usam a alocação dinâmica de forma inerente, como std::unique_ptr.
  • Suporte a localização e caracteres Unicode
  • Bibliotecas de data e hora
  • Funções que modificam o fluxo normal do programa, incluindo <setjmp.h>, <signal.h>, abort, std::terminate
  • Como acessar o ambiente do host, incluindo system e getenv
  • POSIX e outras bibliotecas não incluídas nos padrões de linguagem C99 ou C++11

Em muitos casos, recursos equivalentes estão disponíveis nas funções da API CHRE e bibliotecas de utilitários. Por exemplo, chreLog pode ser usado para registro de depuração direcionado ao sistema Logcat do Android, em que um programa mais tradicional pode usar printf ou std::cout.

Por outro lado, alguns recursos de biblioteca padrão são obrigatórios. Cabe à implementação da plataforma expor esses recursos usando bibliotecas estáticas para inclusão em um nanoapp binário ou vinculação dinâmica entre o nanoapp e o sistema. Isso inclui, mas não se limita a:

  • Utilitários de string e matriz: memcmp, memcpy, memmove, memset, strlen
  • Biblioteca de matemática: funções de ponto flutuante de precisão única usadas com frequência:

    • Operações básicas: ceilf, fabsf, floorf, fmaxf, fminf, fmodf, roundf, lroundf, remainderf
    • Funções exponenciais e de potência: expf, log2f, powf, sqrtf
    • Funções trigonométricas e hiperbólicas: sinf, cosf, tanf, asinf, acosf, atan2f, tanhf

Embora algumas plataformas de suporte ofereçam suporte a recursos adicionais, um nanoapp não é considerado portátil em implementações de CHRE, a menos que ele restrinja as dependências externas a funções da API CHRE e funções de biblioteca padrão aprovadas.

Recursos opcionais

Para promover hardware e software, a API CHRE é dividida em áreas de recursos, que são consideradas opcionais do ponto de vista da API. Embora esses recursos não sejam necessários para oferecer suporte a uma implementação compatível do CHRE, eles podem ser necessários para oferecer suporte a um nanoapp específico. Mesmo que uma plataforma não ofereça suporte a um determinado conjunto de APIs, os nanoapps que fazem referência a essas funções precisam ser capazes de criar e carregar.

Sensores

A API CHRE permite solicitar dados de sensores, incluindo acelerômetro, giroscópio, magnetômetro, sensor de luz ambiente e proximidade. O objetivo dessas APIs é fornecer um conjunto de recursos semelhante às APIs Android Sensors, incluindo suporte a lotes de amostras de sensores para reduzir o consumo de energia. O processamento de dados do sensor no CHRE permite processamento de sinais de movimento com muito menos energia e latência menor em comparação com a execução no AP.

GNSS

A CHRE fornece APIs para solicitar dados de local de um sistema global de satélites de navegação (GNSS, na sigla em inglês), incluindo GPS e outras constelações de satélites. Isso inclui solicitações de correções periódicas de posição, bem como dados brutos de medição, embora ambos sejam recursos independentes. Como a CHRE tem um link direto para o subsistema GNSS, o consumo de energia é reduzido em comparação com as solicitações GNSS baseadas em AP, porque o AP pode permanecer inativo durante todo o ciclo de vida de uma sessão de localização.

Wi-Fi

O CHRE permite interagir com o chip Wi-Fi, principalmente para fins de localização. Embora o GNSS funcione bem para locais externos, os resultados das verificações de Wi-Fi podem fornecer informações de localização precisas em ambientes fechados e em áreas desenvolvidas. Além de evitar o custo de ativar o AP para uma verificação, o CHRE pode detectar os resultados das buscas de Wi-Fi realizadas pelo firmware Wi-Fi para fins de conectividade, que normalmente não são entregues ao AP por motivos de energia. O uso de verificações de conectividade para fins contextuais ajuda a reduzir o número total de verificações de Wi-Fi realizadas, economizando energia.

Foi adicionado suporte a Wi-Fi na API CHRE v1.1, incluindo a capacidade de monitorar os resultados e acionar verificações sob demanda. Esses recursos foram estendidos na v1.2 com a capacidade de realizar medições de tempo de retorno (RTT, na sigla em inglês) em relação a pontos de acesso compatíveis com o recurso, o que permite a determinação precisa da posição relativa.

WWAN

A API CHRE fornece a capacidade de recuperar informações de identificação da célula de serviço e das células vizinhas, que normalmente são usadas para fins de localização de alta granularidade.

Áudio

O CHRE pode processar lotes de dados de áudio de um microfone de baixo consumo, que normalmente usa hardware usado para implementar o HAL do SoundTrigger. O processamento de dados de áudio no CHRE pode permitir que ele seja combinado com outros dados, como sensores de movimento.

Implementação de referência

O código de referência para o framework CHRE está incluído no AOSP no projeto system/chre, implementado em C++11. Embora não seja estritamente obrigatório, é recomendável que todas as implementações de CHRE sejam baseadas nessa base de código, para ajudar a garantir a consistência e acelerar a adoção de novos recursos. Esse código pode ser considerado um análogo ao framework principal do Android, já que é uma implementação de código aberto de APIs usadas por apps, servindo como base e padrão para compatibilidade. Embora ele possa ser personalizado e estendido com recursos específicos do fornecedor, a recomendação é manter o código comum o mais próximo possível da referência. Assim como os HALs do Android, a implementação de referência da CHRE usa várias abstrações de plataforma para permitir que ela seja adaptada a qualquer dispositivo que atenda aos requisitos mínimos.

Para detalhes técnicos e um guia de portabilidade, consulte o README incluído no projeto system/chre.