Imagen del sistema compartida de Android

En esta página, se presentan varios mecanismos que los OEM de dispositivos Android pueden usar para tener su propia imagen del sistema compartida (SSI) en todas las líneas de productos. También se propone un procedimiento para basar una SSI propiedad del OEM en una imagen genérica del sistema (GSI) compilada por AOSP.

Información general

Con Project Treble, el sistema Android monolítico se dividió en dos partes: la parte específica del hardware (la implementación del proveedor) y la parte genérica del SO (el framework del SO Android). El software de cada uno se instala en una partición independiente: la partición del proveedor para el software específico del hardware y la partición del sistema para el software genérico del SO. Se define y aplica una interfaz con versiones, llamada interfaz de proveedor (VINTF), en las dos particiones. Con este sistema de particiones, puedes modificar la partición del sistema sin modificar la partición del proveedor y viceversa.

Motivación

El código del framework lanzado en AOSP cumplió con la arquitectura de Treble y mantuvo la retrocompatibilidad con implementaciones anteriores de proveedores. Por ejemplo, una imagen genérica del sistema compilada a partir de fuentes de AOSP de Android 10 puede ejecutarse en cualquier dispositivo compatible con Treble que ejecute Android 8 o una versión posterior. Los proveedores de SoC y los OEM modifican la versión de Android que se incluye en los dispositivos para el consumidor. (Consulta Ciclo de vida de una versión de Android). Estos cambios y extensiones que se realizaron en el framework no se escribieron para mantener la retrocompatibilidad, lo que se tradujo en una mayor complejidad y un costo más alto en una actualización del SO. Los cambios y las modificaciones específicos del dispositivo aumentan el costo y la complejidad de actualizar una versión del SO de Android.

Antes de Android 11, no había una arquitectura clara que permitiera a los socios compilar extensiones modulares para el framework del SO Android. En este documento, se describen los pasos que los proveedores de SoC y los OEM pueden seguir para crear un SSI. Esto significa que hay una sola imagen, compilada a partir de las fuentes del framework del SO Android para reutilizarla en varios dispositivos, mantener la retrocompatibilidad con las implementaciones de los proveedores y proporcionar una reducción significativa en la complejidad y el costo de las actualizaciones del SO Android. Para conocer los pasos específicos que debes seguir para crear una SSI, consulta la sección Pasos sugeridos para la SSI basada en GSI y ten en cuenta que no es necesario que uses los cuatro pasos. Los pasos que elijas (solo el paso 1, por ejemplo) dependerán de tu implementación.

Descripción general de la SSI

Con SSI, los componentes de software específicos del producto y las extensiones del OEM se colocan en una nueva partición /product. Los componentes de la partición /product usan una interfaz estable y bien definida para interactuar con los componentes de la partición /system. Los OEM pueden optar por compilar una sola SSI o tener una pequeña cantidad de SSI para usar en varios SKU de dispositivos. Cuando se lanza una nueva versión del SO Android, los OEM invierten solo una vez en actualizar sus SSI a la versión más reciente de Android. Pueden reutilizar los SSI para actualizar varios dispositivos sin actualizar la partición /product.

Ten en cuenta que los OEM y los proveedores de SoC compilan SSI que incluyen todas las funciones y modificaciones personalizadas que necesita un OEM. Los mecanismos y las prácticas recomendadas que se proporcionan en esta página están diseñados para que los OEM los usen y alcancen estos objetivos clave:

  • Reutiliza la SSI en varios SKU de dispositivos.
  • Actualizar el sistema Android con las extensiones modulares para facilitar las actualizaciones del SO

La idea principal de separar los componentes específicos del producto en la partición del producto es similar a la idea de Treble de separar los componentes específicos del SoC en la partición del proveedor. Una interfaz de producto (similar a VINTF) permite la comunicación entre el SSI y la partición del producto. Ten en cuenta que, con respecto a la SSI, el término "componentes" describe todos los recursos, archivos binarios, textos, bibliotecas, etcétera, que se instalan en las imágenes, que esencialmente se convierten en particiones.

Particiones alrededor de la SSI

En la figura 1, se muestran las particiones alrededor de la SSI y las interfaces con versiones en las particiones y las políticas en las interfaces. En esta sección, se explica cada una de las particiones y las interfaces en detalle.

Particiones e interfaces alrededor del diagrama de bloques del SSI

Figura 1: Particiones e interfaces en torno a la SSI

Imágenes y particiones

La información de esta sección distingue entre los términos imagen y partición.

  • Una imagen es una pieza conceptual de software que se puede actualizar de forma independiente.
  • Una partición es una ubicación de almacenamiento física que se puede actualizar de forma independiente.

Las secciones de la figura 1 se definen de la siguiente manera:

  • SSI: La SSI es la imagen común a un OEM y puede existir en varios dispositivos. No tiene componentes específicos del hardware ni del producto. Por definición, todo lo que se encuentra en un SSI determinado se comparte entre todos los dispositivos que lo usan. El SSI se compone de una sola imagen /system o de una imagen /system y las particiones /system_ext, como se muestra en la Figura 1.

    • La partición /system contiene componentes basados en el AOSP, mientras que /system_ext, cuando se implementa, contiene extensiones y componentes del OEM y del proveedor del SoC que están estrechamente vinculados con los componentes del AOSP. Por ejemplo, una biblioteca del framework de Java del OEM que proporciona APIs personalizadas para las propias apps del OEM se ajusta mejor a la partición /system_ext que a la partición /system. El contenido de las particiones /system y /system_ext se compila a partir de fuentes de Android modificadas por el OEM.

    • La partición /system_ext es opcional, pero es beneficioso usarla para cualquier función y extensión personalizadas que estén estrechamente vinculadas con los componentes basados en AOSP. Esta distinción te ayuda a identificar los cambios que debes realizar para trasladar esos componentes de la partición /system_ext a la partición /product durante un período.

  • Producto: Es una colección de componentes específicos del producto o dispositivo que representan personalizaciones y extensiones del OEM para el SO Android. Coloca los componentes específicos del SoC en la partición /vendor. Los proveedores de SoC también pueden usar la partición /product para los componentes adecuados, como los independientes del SoC. Por ejemplo, si un proveedor de SoC proporciona un componente independiente del SoC a sus clientes OEM (que es opcional para incluirlo en el producto), el proveedor de SoC puede colocar ese componente en la imagen del producto. La ubicación de un componente no está determinada por su propiedad, sino por su propósito.

  • Proveedor: Es una colección de componentes específicos del SoC.

  • ODM: Es una colección de componentes específicos de la placa que no proporciona el SoC. Por lo general, el proveedor del SoC es propietario de la imagen del proveedor, mientras que el fabricante del dispositivo es propietario de la imagen del ODM. Cuando no hay una partición /odm separada, las imágenes del proveedor del SoC y del ODM se combinan en la partición /vendor.

Interfaces entre imágenes

Existen dos interfaces principales para las imágenes de proveedores y productos en torno a la SSI:

  • Interfaz de proveedor (VINTF): La VINTF es la interfaz para los componentes que residen en las imágenes del proveedor y del ODM. Los componentes de las imágenes del producto y del sistema solo pueden interactuar con las imágenes del proveedor y del ODM a través de esta interfaz. Por ejemplo, una imagen del proveedor no puede depender de una parte privada de la imagen del sistema, y viceversa. Esto se define originalmente en Project Treble, que divide las imágenes en particiones del sistema y del proveedor. La interfaz se describe con los siguientes mecanismos:

    • HIDL (el HAL de transferencia solo está disponible para los módulos system y system_ext)
    • AIDL estable
    • Configuraciones
      • API de propiedades del sistema
      • API de esquema del archivo de configuración
    • VNDK
    • APIs del SDK de Android
    • Biblioteca del SDK de Java
  • Interfaces del producto: La interfaz del producto es la interfaz entre el SSI y la imagen del producto. Definir una interfaz estable desacopla los componentes del producto de los componentes del sistema en una SSI. La interfaz del producto requiere las mismas interfaces estables que VINTF. Sin embargo, solo se aplican las APIs del VNDK y del SDK de Android para los dispositivos que se lanzan con Android 11 (y versiones posteriores).

Cómo habilitar la SSI en Android 11

En esta sección, se explica cómo usar las nuevas funciones para admitir SSI en Android 11.

La partición /system_ext

La partición /system_ext se introdujo en Android 11 como una partición opcional. (Es el lugar para los componentes que no son del AOSP y que tienen un acoplamiento estrecho con los componentes definidos por el AOSP en la partición /system). Se supone que la partición /system_ext es la extensión específica del OEM para la partición /system, sin una interfaz definida en las dos particiones. Los componentes de la partición /system_ext pueden realizar llamadas a la API privadas en la partición /system, y los componentes de la partición /system pueden realizar llamadas a la API privadas en la partición /system_ext.

Debido a que las dos particiones están estrechamente acopladas, ambas se actualizan juntas cuando se lanza una nueva versión de Android. Una partición /system_ext creada para la versión anterior de Android no necesita ser compatible con la partición /system en la próxima versión de Android.

Para instalar un módulo en la partición /system_ext, agrega system_ext_specific: true al archivo Android.bp. En el caso de los dispositivos que no tienen una partición /system_ext, instala esos módulos en el subdirectorio ./system_ext de la partición /system.

Historial

A continuación, se muestra un poco de historia sobre la partición /system_ext. El objetivo del diseño era colocar todos los componentes específicos del OEM, independientemente de si son comunes, en la partición /product. Sin embargo, moverlos todos a la vez no era factible, en especial cuando algunos componentes tenían un acoplamiento estrecho con la partición /system. Para mover un componente con acoplamiento alto a la partición /product, se debe extender la interfaz del producto. A menudo, esto requería que el componente en sí se refactorizara de forma exhaustiva, lo que consumía mucho tiempo y esfuerzo. La partición /system_ext comenzó como un lugar para alojar temporalmente los componentes que no están listos para trasladarse a la partición /product. El objetivo de la SSI era, en última instancia, eliminar la partición /system_ext.

Sin embargo, la partición /system_ext es útil para mantener la partición /system lo más cerca posible del AOSP. Con la SSI, la mayor parte del esfuerzo de actualización se dedica a los componentes de las particiones /system y /system_ext. Cuando la imagen del sistema se compila a partir de fuentes lo más similares posible a las de AOSP, puedes enfocar el esfuerzo de actualización en la imagen de system_ext.

Desvincula los componentes de las particiones /system y /system_ext en la partición /product

Android 9 introdujo una partición /product que se vincula con la partición /system. Los módulos de la partición /product usan los recursos del sistema sin ninguna restricción, y viceversa. Para que la SSI sea posible en Android 10, los componentes del producto se dividen en las particiones /system_ext y /product. La partición /system_ext no tiene que cumplir con las restricciones sobre el uso de componentes del sistema que la partición /product cumplía en Android 9. A partir de Android 10, la partición /product debe separarse de la partición /system y debe usar interfaces estables de las particiones /system y /system_ext.

El propósito principal de la partición /system_ext es extender las funciones del sistema, en lugar de instalar módulos de productos incluidos en el paquete, como se describe en la sección /system_ext partition. Para ello, separa los módulos específicos del producto y muévelos a la partición /product. La desagregación de los módulos específicos del producto hace que /system_ext sea común a los dispositivos. (Para obtener más detalles, consulta Cómo hacer que la partición /system_ext sea común).

Para separar la partición /product de los componentes del sistema, esta debe tener la misma política de aplicación que la partición /vendor que ya se separó con Project Treble./product

A partir de Android 11, se aplican las interfaces nativas y de Java para la partición /product, como se describe a continuación. Para obtener más información, consulta Enforcing Product Partition Interfaces.

  • Interfaces nativas: Los módulos nativos de la partición /product deben separarse de las demás particiones. Las únicas dependencias permitidas de los módulos de productos son algunas bibliotecas del VNDK (incluido el LLNDK) de la partición /system. Las bibliotecas JNI de las que dependen las apps del producto deben ser bibliotecas del NDK.
  • Interfaces de Java: Los módulos de Java (app) en la partición /product no pueden usar APIs ocultas porque son inestables. Estos módulos solo deben usar APIs públicas y APIs del sistema de la partición /system, y bibliotecas del SDK de Java en la partición /system o /system_ext. Puedes definir bibliotecas del SDK de Java para APIs personalizadas.

Pasos sugeridos para la SSI basada en GSI

Particiones sugeridas para la SSI basada en GSI

Figura 2: Particiones sugeridas para la SSI basada en GSI

Una imagen genérica del sistema (GSI) es la imagen del sistema que se compila directamente desde AOSP. Se usa para las pruebas de cumplimiento de Treble (por ejemplo, CTS en GSI) y como plataforma de referencia que los desarrolladores de apps pueden usar para probar la compatibilidad de sus apps cuando no tienen un dispositivo real que ejecute la versión requerida de Android.

Los OEM también pueden usar la GSI para crear su SSI. Como se explica en Imágenes y particiones, el SSI consta de la imagen del sistema para los componentes definidos por el AOSP y la imagen system_ext para los componentes definidos por el OEM. Cuando se usa la GSI como imagen system, el OEM puede enfocarse en la imagen system_ext para la actualización.

En esta sección, se proporciona una guía para los OEM que desean modularizar sus personalizaciones en las particiones /system_ext y /product mientras usan una imagen del sistema de AOSP o casi de AOSP. Si los OEM compilan la imagen del sistema a partir de fuentes de AOSP, pueden sustituir la imagen del sistema que compilan por la GSI que proporciona AOSP. Sin embargo, los OEM no necesitan alcanzar el paso final (usar la GSI tal como está) de inmediato.

Paso 1: Hereda generic_system.mk para la imagen del sistema del OEM (GSI del OEM)

Al heredar generic_system.mk (que se llamaba mainline_system.mk en Android 11 y se cambió a generic_system.mk en AOSP), la imagen del sistema (GSI del OEM) incluye todos los archivos que tiene la GSI del AOSP. Los OEM pueden modificar estos archivos para que la GSI del OEM contenga los archivos propietarios del OEM, además de los archivos de la GSI del AOSP. Sin embargo, los OEM no pueden modificar el archivo generic_system.mk.

Cómo heredar `generic_system.mk` para la imagen del sistema del OEM

Figura 3: Cómo heredar generic_system.mk para la imagen del sistema del OEM

Paso 2: Haz que la GSI del OEM tenga la misma lista de archivos que la GSI del AOSP

En esta etapa, el GSI del OEM no puede tener archivos adicionales. Los archivos propios del OEM se deben mover a las particiones system_ext o product.

Cómo quitar los archivos agregados de la GSI del OEM

Figura 4: Cómo quitar los archivos agregados de la GSI del OEM

Paso 3: Define una lista de entidades permitidas para limitar los archivos modificados en la GSI del OEM

Para verificar los archivos modificados, los OEM pueden usar la herramienta compare_images y comparar la GSI de AOSP con la GSI del OEM. Obtén el GSI de AOSP del destino de compilación de AOSP generic_system_*.

Si ejecutas la herramienta compare_images periódicamente con el parámetro allowlist, puedes supervisar las diferencias fuera de la lista de entidades permitidas. Esto evita la necesidad de realizar modificaciones adicionales en la GSI del OEM.

Cómo definir una lista de entidades permitidas para reducir la lista de archivos modificados en la GSI del OEM

Figura 5: Define una lista de entidades permitidas para reducir la lista de archivos modificados en la GSI del OEM

Paso 4: Haz que la GSI del OEM tenga los mismos objetos binarios que la GSI del AOSP

La limpieza de la lista de entidades permitidas permite que los OEM usen la GSI del AOSP como imagen del sistema para sus propios productos. Para limpiar la lista de entidades permitidas, los OEM pueden abandonar sus cambios en la GSI del OEM o transferir sus cambios al AOSP para que la GSI del AOSP los incluya.

Haz que la GSI del OEM tenga los mismos objetos binarios que la GSI del AOSP

Figura 6: Hacer que la GSI del OEM tenga los mismos objetos binarios que la GSI del AOSP

Define la SSI para los OEM

Cómo proteger la partición /system durante la compilación

Para evitar cualquier cambio específico del producto en la partición /system y definir la GSI del OEM, los OEM pueden usar una macro de makefile llamada require-artifacts-in-path para evitar cualquier declaración de módulos del sistema después de que se llame a la macro. Consulta el ejemplo para crear un archivo makefile y habilitar la verificación de la ruta del artefacto.

Los OEM pueden definir una lista para permitir que los módulos específicos del producto se instalen en la partición /system de forma temporal. Sin embargo, la lista debe estar vacía para que la GSI del OEM sea común a todos los productos del OEM. Este proceso sirve para definir la GSI del OEM y puede ser independiente de los pasos para la GSI del AOSP.

Aplica las interfaces de productos

Para garantizar que la partición /product no esté agrupada, los OEM pueden asegurarse de que sus dispositivos apliquen las interfaces de productos configurando PRODUCT_PRODUCT_VNDK_VERSION:= current para los módulos nativos y PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true para los módulos de Java. Estas variables se configuran automáticamente si el PRODUCT_SHIPPING_API_LEVEL del dispositivo es mayor o igual que 30. Para obtener información detallada, consulta Enforcing Product Partition Interfaces.

Cómo hacer que la partición /system_ext sea común

La partición /system_ext puede variar entre dispositivos, ya que puede tener módulos específicos del dispositivo y agrupados en el sistema. Debido a que el SSI consta de particiones /system y /system_ext, las diferencias en la partición /system_ext impiden que los OEM definan un SSI. Los OEM pueden tener su propio SSI y compartirlo entre varios dispositivos quitando cualquier diferencia y haciendo que la partición /system_ext sea común.

En esta sección, se brindan recomendaciones para que la partición /system_ext sea común.

Expone APIs ocultas en la partición del sistema

Muchas apps específicas del producto no se pueden instalar en la partición del producto porque usan APIs ocultas, que están prohibidas en la partición del producto. Para mover las apps específicas del dispositivo a la partición del producto, quita el uso de APIs ocultas.

La mejor manera de quitar las APIs ocultas de las apps es encontrar las APIs públicas o del sistema alternativas para reemplazarlas. Si no hay APIs para reemplazar las APIs ocultas, los OEM pueden contribuir al AOSP para definir las nuevas APIs del sistema para sus dispositivos.

Como alternativa, los OEM pueden definir APIs personalizadas creando su propia biblioteca del SDK de Java en la partición /system_ext. Puede usar APIs ocultas en la partición del sistema y proporcionar las APIs a las apps en la partición del producto o del proveedor. Los OEM deben congelar las APIs orientadas al producto para garantizar la retrocompatibilidad.

Incluye el superconjunto de todos los APKs y omite la instalación de algunos paquetes para cada dispositivo

Algunos paquetes incluidos en el sistema no son comunes en todos los dispositivos. Puede ser difícil separar estos módulos APK para trasladarlos a la partición del producto o del proveedor. Como solución provisoria, los OEM pueden hacer que la SSI incluya todos los módulos y, luego, filtrar los no deseados con una propiedad de SKU (ro.boot.hardware.sku). Para usar el filtro, los OEM superponen los recursos del framework config_disableApkUnlessMatchedSku_skus_list y config_disableApksUnlessMatchedSku_apk_list.

Para obtener una configuración más precisa, declara un receptor de transmisión que inhabilite los paquetes innecesarios. El receptor de emisión llama a setApplicationEnabledSetting para inhabilitar el paquete cuando recibe el mensaje ACTION_BOOT_COMPLETED.

Define RRO en lugar de usar una superposición de recursos estática

Una superposición de recursos estáticos manipula los paquetes superpuestos. Sin embargo, puede impedir la definición de una SSI, por lo que debes asegurarte de que las propiedades del RRO estén activadas y configuradas correctamente. Si configuran las propiedades de la siguiente manera, los OEM pueden tener todas las superposiciones generadas automáticamente como RRO.

PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty

Si se requiere una configuración detallada, define un RRO de forma manual en lugar de depender de uno generado automáticamente. Para obtener información detallada, consulta Superposiciones de recursos de tiempo de ejecución (RRO). Los OEM también pueden definir RRAs condicionales que dependen de las propiedades del sistema con los atributos android:requiredSystemPropertyName y android:requiredSystemPropertyValue.

Preguntas frecuentes

¿Puedo definir varias SSI?

Depende de la frecuencia y las características de los dispositivos (o el grupo de dispositivos). Los OEM pueden intentar que la partición system_ext sea común, como se describe en Cómo hacer que la partición system_ext sea común. Si un grupo de dispositivos tiene muchas diferencias, es mejor definir varios SSI.

¿Puedo modificar generic_system.mk (mainline_system.mk) para una GSI de OEM?

No, pero los OEM pueden definir un nuevo archivo makefile para una GSI del OEM que herede el archivo generic_system.mk y usar el nuevo archivo makefile en su lugar. Para ver un ejemplo, consulta Enforcing Product Partition Interfaces.

¿Puedo quitar de generic_system.mk los módulos que entran en conflicto con mi implementación?

No. La GSI tiene un conjunto mínimo de módulos que se pueden iniciar y probar. Si crees que un módulo no es esencial, registra un error para actualizar el archivo generic_system.mk en AOSP.