Los smartphones contienen varios procesadores, cada uno optimizado para realizar tareas diferentes. Sin embargo, Android solo se ejecuta en un procesador: el procesador de aplicaciones (AP). El AP está ajustado para ofrecer un excelente rendimiento en casos de uso con la pantalla encendida, como los juegos, pero consume demasiada energía para admitir funciones que requieren ráfagas de procesamiento frecuentes y cortas todo el tiempo, incluso cuando la pantalla está apagada. Los procesadores más pequeños pueden controlar estas cargas de trabajo de manera más eficiente y completar sus tareas sin afectar de manera significativa la duración de la batería. Sin embargo, los entornos de software en estos procesadores de baja potencia son más limitados y pueden variar mucho, lo que dificulta el desarrollo multiplataforma.
El entorno de ejecución del centro de contexto (CHRE) proporciona una plataforma común para ejecutar apps en un procesador de baja potencia, con una API simple, estandarizada y compatible con la incorporación. La CHRE permite que los OEM de dispositivos y sus socios de confianza transfieran el procesamiento del AP, ahorren batería y mejoren varias áreas de la experiencia del usuario, y habiliten una clase de funciones siempre activas y conscientes del contexto, en especial aquellas que involucran la aplicación del aprendizaje automático a la detección ambiental.
Conceptos clave
CHRE es el entorno de software en el que las apps nativas pequeñas, denominadas nanoapps, se ejecutan en un procesador de bajo consumo y, además, interactúan con el sistema subyacente a través de la API de CHRE común. Para acelerar la implementación correcta de las APIs de CHRE, se incluye una implementación de referencia multiplataforma de CHRE en AOSP. La implementación de referencia incluye código común y abstracciones del hardware y software subyacentes a través de una serie de capas de abstracción de la plataforma (PAL). Las nanoapps casi siempre están vinculadas a una o más apps cliente que se ejecutan en Android, que interactúan con el CHRE y las nanoapps a través de las APIs del sistema ContextHubManager
de acceso restringido.
En un nivel alto, se pueden establecer paralelismos entre la arquitectura de CHRE y Android en su totalidad. Sin embargo, existen algunas distinciones importantes:
- CHRE admite solo la ejecución de nanoapps desarrolladas en código nativo (C o C++). No se admite Java.
- Debido a las limitaciones de recursos y de seguridad, el CHRE no está abierto para que lo usen apps de terceros de Android arbitrarias. Solo las apps de confianza del sistema pueden acceder a él.
También es importante distinguir entre el concepto de CHRE y un concentrador de sensores. Si bien es común usar el mismo hardware para implementar el concentrador de sensores y el CHRE, este último no proporciona las capacidades de los sensores que requiere el HAL de sensores de Android. El CHRE está vinculado al HAL de Context Hub y actúa como cliente de un framework de sensores específico del dispositivo para recibir datos de sensores sin involucrar al AP.
Figura 1: Arquitectura del framework de CHRE
HAL de Context Hub
La capa de abstracción de hardware (HAL) del centro de contexto es la interfaz entre el framework de Android y la implementación de CHRE del dispositivo, que se define en hardware/interfaces/contexthub
.
La HAL de Context Hub define las APIs a través de las cuales el framework de Android descubre los concentradores de contexto disponibles y sus nanoapps, interactúa con esas nanoapps a través del envío de mensajes y permite que se carguen y descarguen las nanoapps. En system/chre/host
, puedes encontrar una implementación de referencia de la HAL del centro de contexto que funciona con la implementación de referencia de CHRE.
En caso de conflicto entre esta documentación y la definición de HAL, prevalecerá la definición de HAL.
Inicialización
Cuando se inicia Android, ContextHubService invoca la función HAL getHubs()
para determinar si hay concentradores de contexto disponibles en el dispositivo. Esta es una llamada única de bloqueo, por lo que debe completarse rápidamente para evitar retrasar el inicio y debe mostrar un resultado preciso, ya que no se pueden agregar nuevos centros de contexto más adelante.
Carga y descarga nanoapps
Un concentrador de contexto puede incluir un conjunto de nanoapps que se incluyen en la imagen del dispositivo y se cargan cuando se inicia el CHRE. Se conocen como nanoapps precargadas y deben incluirse en la primera respuesta posible a queryApps()
.
La HAL de Context Hub también admite la carga y la descarga dinámica de nanoapps en el tiempo de ejecución mediante las funciones loadNanoApp()
y unloadNanoApp()
. Las nanoapps se proporcionan a la HAL en un formato binario específico para la implementación de hardware y software de CHRE del dispositivo.
Si la implementación para cargar una nanoaplicación implica escribirla en una memoria no volátil, como el almacenamiento flash conectado al procesador que ejecuta CHRE, la implementación de CHRE siempre debe iniciarse con estas nanoaplicaciones dinámicas en el estado inhabilitado. Esto significa que no se ejecuta ninguno de los códigos de la nanoapp hasta que se recibe una solicitud de enableNanoapp()
a través del HAL. Las nanoapps precargadas se pueden inicializar en el estado habilitado.
Reinicio del centro de contexto
Si bien no se espera que el CHRE se reinicie durante el funcionamiento normal, puede ser necesario recuperarse de condiciones inesperadas, como un intento de acceder a una dirección de memoria no asignada. En estas situaciones, CHRE se reinicia independientemente de Android. El HAL notifica esto a Android a través del evento RESTARTED
, que solo debe enviar después de que se haya reinicializado el CHRE hasta el punto en que pueda aceptar solicitudes nuevas, como queryApps()
.
Descripción general del sistema de CHRE
El CHRE se diseñó en torno a una arquitectura orientada a eventos, en la que la unidad principal de procesamiento es un evento que se pasa al punto de entrada de manejo de eventos de una nanoaplicación. Si bien el framework de CHRE puede ser multiproceso, una nanoaplicación determinada nunca se ejecuta desde varios subprocesos en paralelo. El framework de CHRE interactúa con una nanoapp determinada a través de uno de los tres puntos de entrada de nanoapp (nanoappStart()
, nanoappHandleEvent()
y nanoappEnd()
) o a través de una devolución de llamada proporcionada en una llamada anterior a la API de CHRE, y las nanoapps interactúan con el framework de CHRE y el sistema subyacente a través de la API de CHRE. La API de CHRE proporciona un conjunto de funciones básicas, así como herramientas para acceder a indicadores contextuales, incluidos sensores, GNSS, Wi-Fi, WWAN y audio, y se puede ampliar con funciones adicionales específicas del proveedor para que las usen las nanoapps específicas del proveedor.
Sistema de compilación
Si bien el HAL de Context Hub y otros componentes necesarios del lado del AP se compilan junto con Android, el código que se ejecuta dentro de CHRE puede tener requisitos que lo hagan incompatible con el sistema de compilación de Android, como la necesidad de una cadena de herramientas especializada. Por lo tanto, el proyecto CHRE en AOSP proporciona un sistema de compilación simplificado basado en GNU Make para compilar nanoapps y, de manera opcional, el framework de CHRE en bibliotecas que se pueden integrar con el sistema. Los fabricantes de dispositivos que agregan compatibilidad con CHRE deben integrar la compatibilidad del sistema de compilación para sus dispositivos de destino en AOSP.
La API de CHRE se escribe en el estándar de lenguaje C99, y la implementación de referencia usa un subconjunto restringido de C++11 adecuado para apps con recursos limitados.
API de CHRE
La API de CHRE es una colección de archivos de encabezado C que define la interfaz del software entre una nanoapp y el sistema. Está diseñado para hacer que el código de las nanoapps sea compatible con todos los dispositivos compatibles con CHRE, lo que significa que no es necesario modificar el código fuente de una nanoapp para que admita un nuevo tipo de dispositivo, aunque podría necesitar volver a compilarse específicamente para el conjunto de instrucciones del procesador del dispositivo de destino o la interfaz binaria de la aplicación (ABI). La arquitectura de CHRE y el diseño de la API también garantizan que las nanoapps sean compatibles con objetos binarios en las diferentes versiones de la API de CHRE. Esto significa que no es necesario volver a compilar una nanoapp para que se ejecute en un sistema que implemente una versión diferente de la API de CHRE en comparación con la API de destino con la que se compiló la nanoapp. En otras palabras, si un objeto binario de nanoapp se ejecuta en un dispositivo compatible con la API de CHRE v1.3, y ese dispositivo se actualiza para admitir la API de CHRE v1.4, el mismo objeto binario de nanoapp sigue funcionando. De manera similar, la nanoaplicación puede ejecutarse en la API de CHRE v1.2 y determinar en el tiempo de ejecución si requiere capacidades de la API v1.3 para lograr su uso o si puede funcionar, posiblemente con una degradación elegante de funciones.
Las versiones nuevas de la API de CHRE se lanzan junto con Android. Sin embargo, como la implementación de CHRE forma parte de la implementación del proveedor, la versión de la API de CHRE compatible con un dispositivo no está necesariamente vinculada a una versión de Android.
Resumen de la versión
Al igual que el esquema de control de versiones de HIDL de Android, la API de CHRE sigue el control de versiones semántico.
La versión principal indica compatibilidad con objetos binarios, mientras que la versión secundaria aumenta cuando se introducen funciones retrocompatibles. La API de CHRE
incluye anotaciones de código fuente para identificar qué versión introdujo una función
o un parámetro, por ejemplo, @since v1.1
.
La implementación de CHRE también expone una versión de parche específica de la plataforma a través de chreGetVersion()
, que indica cuándo se realizan correcciones de errores o actualizaciones menores en la implementación.
Versión 1.0 (Android 7)
Incluye compatibilidad con sensores y capacidades principales de nanoapp, como eventos y cronómetros.
Versión 1.1 (Android 8)
Presenta capacidades de ubicación a través de la ubicación del GNSS y las mediciones sin procesar, el escaneo de Wi-Fi y la información de la red móvil, junto con mejoras generales para habilitar la comunicación de nanoaplicaciones a nanoaplicaciones y otras mejoras.
Versión 1.2 (Android 9)
Se agregó compatibilidad con datos de un micrófono de bajo consumo, rango de Wi-Fi RTT, notificaciones de suspensión y activación de PA, y otras mejoras.
Versión 1.3 (Android 10)
Mejora las funciones relacionadas con los datos de calibración del sensor, agrega compatibilidad para borrar datos de sensores por lotes a pedido, define el tipo de sensor de detección de pasos y extiende los eventos de ubicación del GNSS con campos de precisión adicionales.
Versión 1.4 (Android 11)
Se agregó compatibilidad con la información de celdas 5G, el volcado de depuración de nanoapp y otras mejoras.
Funciones obligatorias del sistema
Si bien las fuentes de indicadores contextuales, como los sensores, se clasifican en áreas de atributos opcionales, se requieren algunas funciones principales en todas las implementaciones de CHRE. Esto incluye las APIs principales del sistema, como las que se usan para configurar temporizadores, enviar y recibir mensajes a clientes en el procesador de aplicaciones, el registro y otras. Para obtener más información, consulta los encabezados de la API.
Además de las funciones principales del sistema codificadas en la API de CHRE, también hay funciones obligatorias a nivel del sistema de CHRE especificadas a nivel del HAL de Context Hub. La más significativa de ellas es la capacidad de cargar y descargar nanoapps de forma dinámica.
Biblioteca estándar C/C++
Para minimizar el uso de memoria y la complejidad del sistema, las implementaciones de CHRE deben admitir solo un subconjunto de las bibliotecas C y C++ estándar, y las funciones de lenguaje que requieren compatibilidad con el tiempo de ejecución. Siguiendo estos principios, algunas funciones se excluyen de forma explícita debido a su memoria y a sus amplias dependencias a nivel del SO, y otras porque se reemplazan por APIs específicas de CHRE más adecuadas. Si bien no se trata de una lista exhaustiva, las siguientes funciones no están diseñadas para estar disponibles para las nanoapps:
- Excepciones de C++ y la información de tipo de tiempo de ejecución (RTTI)
- Compatibilidad con subprocesos de bibliotecas estándar, incluidos los encabezados de C++11
<thread>
,<mutex>
,<atomic>
y<future>
- Bibliotecas de entrada y salida estándar de C y C++
- Biblioteca de plantillas estándar (STL) de C++
- Biblioteca de expresiones regulares estándar de C++
- Asignación dinámica de memoria a través de funciones estándar (por ejemplo,
malloc
,calloc
,realloc
,free
yoperator new
) y otras funciones estándar de la biblioteca que usan de forma inherente la asignación dinámica, comostd::unique_ptr
- Compatibilidad con la localización y los caracteres Unicode
- Bibliotecas de fecha y hora
- Funciones que modifican el flujo normal del programa, incluidas
<setjmp.h>
,<signal.h>
,abort
ystd::terminate
- Acceso al entorno de host, incluidos
system
ygetenv
- POSIX y otras bibliotecas que no se incluyen en los estándares de lenguaje C99 o C++11
En muchos casos, las funciones equivalentes están disponibles en las bibliotecas de utilidad y las funciones de la API de CHRE. Por ejemplo, se puede usar chreLog
para el registro de depuración orientado al sistema Logcat de Android, donde un programa más tradicional podría usar printf
o std::cout
.
Por el contrario, se requieren algunas funciones de biblioteca estándar. Depende de la implementación de la plataforma exponerlos a través de bibliotecas estáticas para su inclusión en un objeto binario de nanoaplicación o mediante la vinculación dinámica entre la nanoaplicación y el sistema. Esto incluye, entre otros, los siguientes:
- Utilidades de cadenas y arrays:
memcmp
,memcpy
,memmove
,memset
,strlen
Biblioteca matemática: Funciones de punto flotante de precisión simple de uso general:
- Operaciones básicas:
ceilf
,fabsf
,floorf
,fmaxf
,fminf
,fmodf
,roundf
,lroundf
yremainderf
- Funciones exponenciales y de potencia:
expf
,log2f
,powf
,sqrtf
- Funciones hiperbólicas y trigonométricas:
sinf
,cosf
,tanf
,asinf
,acosf
,atan2f
,tanhf
- Operaciones básicas:
Si bien algunas plataformas subyacentes admiten capacidades adicionales, una nanoaplicación no se considera portátil en las implementaciones de CHRE, a menos que restrinja sus dependencias externas a las funciones de la API de CHRE y a las funciones de la biblioteca estándar aprobadas.
Funciones opcionales
Para promocionar el hardware y el software, la API de CHRE se divide en áreas de funciones, que se consideran opcionales desde la perspectiva de la API. Si bien es posible que estas funciones no sean necesarias para admitir una implementación de CHRE compatible, sí podrían serlo para admitir una nanoapp en particular. Incluso si una plataforma no admite un conjunto determinado de APIs, las nanoapps que hacen referencia a esas funciones deben poder compilarse y cargarse.
Sensores
La API de CHRE permite solicitar datos de sensores, como el acelerómetro, el giroscopio, el magnetómetro, el sensor de luz ambiental y la proximidad. Estas APIs están diseñadas para proporcionar un conjunto de funciones similares a las APIs de Android Sensors, que incluye la compatibilidad para agrupar muestras de sensores por lotes para reducir el consumo de energía. El procesamiento de datos de sensores dentro de CHRE permite un procesamiento de señales de movimiento con una latencia y una energía mucho más bajas en comparación con la ejecución en el AP.
GNSS
CHRE proporciona APIs para solicitar datos de ubicación desde un sistema global de navegación satelital (GNSS), incluido el GPS y otras constelaciones de satélites. Esto incluye solicitudes de correcciones de posición periódicas y datos de medición sin procesar, aunque ambos son capacidades independientes. Como la CHRE tiene un vínculo directo con el subsistema GNSS, se reduce la energía en comparación con las solicitudes de GNSS basadas en AP, ya que el AP puede permanecer inactivo durante todo el ciclo de vida de una sesión de ubicación.
Wi-Fi
El CHRE permite interactuar con el chip Wi-Fi, principalmente para fines de ubicación. Si bien el GNSS funciona bien para ubicaciones al aire libre, los resultados de los análisis de Wi-Fi pueden proporcionar información de ubicación precisa en interiores y en áreas desarrolladas. Además de evitar el costo de activar el PA para una búsqueda, CHRE puede escuchar los resultados de las búsquedas de Wi-Fi realizadas por el firmware de Wi-Fi con fines de conectividad, que normalmente no se entregan al PA por motivos de energía. Aprovechar los análisis de conectividad con fines contextuales ayuda a reducir la cantidad total de análisis de Wi-Fi realizados, lo que ahorra energía.
Se agregó compatibilidad con Wi-Fi en la versión 1.1 de la API de CHRE, incluida la capacidad de supervisar los resultados y activar los análisis a pedido. Estas capacidades se ampliaron en la versión 1.2 con la capacidad de realizar mediciones de tiempo de ida y vuelta (RTT) en puntos de acceso que admiten la función, lo que permite una determinación precisa de la posición relativa.
WWAN
La API de CHRE proporciona la capacidad de recuperar información de identificación de celdas para la celda de entrega y sus vecinas, lo que, por lo general, se usa con fines de ubicación aproximada.
Audio
El CHRE puede procesar lotes de datos de audio desde un micrófono de baja potencia, que, por lo general, aprovecha el hardware que se usa para implementar el HAL de SoundTrigger. El procesamiento de datos de audio en CHRE puede permitir que se fusionen con otros datos, como sensores de movimiento.
Implementación de referencia
El código de referencia para el marco de trabajo CHRE se incluye en el AOSP en el proyecto system/chre
, implementado en C++11. Si bien no es estrictamente necesario, se recomienda que todas las implementaciones de CHRE se basen en esta base de código para garantizar la coherencia y acelerar la adopción de nuevas funciones. Este código se puede ver como un análogo del framework principal de Android, ya que es una implementación de código abierto de las APIs que usan las apps, que sirve como modelo de referencia y estándar para la compatibilidad. Si bien se puede personalizar y extender con capacidades específicas del proveedor, la recomendación es mantener el código común lo más cerca posible de la referencia. Al igual que las HAL de Android, la implementación de referencia de CHRE usa varias abstracciones de plataforma para permitir que se adapte a cualquier dispositivo que cumpla con los requisitos mínimos.
Para obtener detalles técnicos y una guía de portabilidad, consulta el archivo README incluido en el proyecto system/chre
.