Imagen del sistema compartido 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 propone un procedimiento para basar un SSI propiedad del OEM en una imagen genérica del sistema (GSI) compilada por AOSP.

Segundo plano

Con el Project Treble, Android monolítico se dividió en dos partes: la parte específica del hardware (la implementación del proveedor) y la parte del SO genérico (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 control de versión, 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 publicado en el AOSP cumplía con la arquitectura de Treble y mantuvo la retrocompatibilidad con las implementaciones de proveedores más antiguos. Por ejemplo, una imagen genérica del sistema compilada a partir de fuentes de AOSP de Android 10 se puede ejecutar en cualquier dispositivo compatible con Treble que se ejecute en Android 8 o versiones posteriores. Los proveedores de SoC y los OEMs modifican la versión de Android que se envía en los dispositivos para consumidores. (consulta Vida útil 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 OEMs pueden seguir para crear un SSI. Esto significa una imagen, compilada a partir de las fuentes del framework del SO Android para su reutilización en varios dispositivos, para mantener la retrocompatibilidad con las implementaciones de proveedores y para proporcionar una reducción significativa en la complejidad y el costo de las actualizaciones del SO Android. Si quieres conocer los pasos específicos que necesitas para crear un SSI, consulta la sección Pasos sugeridos para SSI basados en GSI y ten en cuenta que no necesitas seguir los cuatro pasos. Los pasos que elijas (por ejemplo, solo el paso 1) dependerán de tu implementación.

Descripción general de los SSI

Con SSI, los componentes de software específicos del producto y las extensiones de 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 OEMs pueden compilar un 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 para actualizar sus SSI a la versión más reciente de Android. Pueden volver a usar 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 destinados a que los OEM los usen para alcanzar estos objetivos clave:

  • Reutiliza el SSI en varios SKU de dispositivos.
  • Actualiza 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 del producto (similar a VINTF) permite la comunicación entre SSI y la partición de producto. Ten en cuenta que, con respecto a la SSI, el término “componentes” describe todos los recursos, objetos binarios, textos, bibliotecas, etcétera, que se instalan en las imágenes, que, en esencia, se convierten en particiones.

Particiones alrededor de SSI

En la Figura 1, se muestran las particiones alrededor de SSI y las interfaces con versión 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 de SSI

Figura 1: Interfaces y particiones en torno a 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 de un OEM y puede existir en varios dispositivos. No tiene ningún componente específico de hardware ni del producto. Por definición, todo lo que se incluye en un SSI determinado se comparte entre todos los dispositivos que usan ese SSI. El SSI se compone de una sola imagen /system o de una /system y las particiones /system_ext, como se muestra en la Figura 1.

    • La partición /system contiene componentes basados en AOSP, mientras que /system_ext, cuando se implementa, contiene extensiones y componentes de proveedores de OEM y SoC que están estrechamente vinculados con los componentes de AOSP. Por ejemplo, una biblioteca del framework de Java del OEM que proporciona APIs personalizadas para las apps del OEM se ajusta mejor en /system_ext que en 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 conveniente usarla para las funciones y extensiones personalizadas que están estrechamente vinculadas con componentes basados en AOSP. Esta distinción te ayuda a identificar los cambios que debes realizar para mover 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 del 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 enviar con 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 un conjunto 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 independiente, 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 los SSI:

  • Interfaz de proveedor (VINTF): VINTF es la interfaz para los componentes que residen en el proveedor y las imágenes 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 de 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 mediante los siguientes mecanismos:

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

Habilita SSI en Android 11

En esta sección, se explica cómo usar las nuevas funciones implementadas 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 de AOSP que tienen una vinculación estrecha con los componentes definidos por 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 junto 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 de la próxima versión de Android.

Para instalar un módulo a 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

Aquí tienes información histórica sobre la partición /system_ext. El objetivo de diseño era colocar todos los componentes específicos de OEM, independientemente de si eran comunes, en la partición /product. Sin embargo, no era factible moverlos todos a la vez, en especial cuando algunos componentes tenían una vinculación estrecha 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 se refactorizara el componente en gran medida, lo que consume mucho tiempo y esfuerzo. La partición /system_ext comenzó como un lugar para alojar temporalmente aquellos componentes que aún no están listos para moverse a la partición /product. El objetivo de la SSI era eliminar, en última instancia, 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 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 que son lo más similares posible a las de AOSP, puedes enfocar el esfuerzo de actualización en la imagen system_ext.

Se desagregan los componentes de las particiones /system y /system_ext en la partición /product.

Android 9 introdujo una partición /product que se combina 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 de uso de componentes del sistema que tenía la partición /product en Android 9. A partir de Android 10, la partición /product debe desagruparse de la partición /system y debe usar interfaces estables de las particiones /system y /system_ext.

El objetivo principal de la partición /system_ext es extender las funciones del sistema, en lugar de instalar módulos de productos empaquetados, como se describe en la sección /system_ext partition. Para ello, desagrupa los módulos específicos del producto y muévelos a la partición /product. Si desagrupas los módulos específicos de los productos, /system_ext será común en los dispositivos. (Para obtener más detalles, consulta Cómo hacer que la partición /system_ext sea común).

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

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: Se deben desagrupar los módulos nativos en la partición /product de las otras particiones. Las únicas dependencias permitidas de los módulos de productos son algunas bibliotecas de VNDK (incluido 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 SSI basadas en GSI

Figura 2: Particiones sugeridas para SSI basadas en GSI

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

Los OEMs también pueden usar 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 AOSP y la imagen system_ext para los componentes definidos por el OEM. Cuando se usa la GSI como la 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 OEMs que desean modularizar sus personalizaciones en las particiones /system_ext y /product mientras usan una imagen del sistema AOSP o cercana a AOSP. Si los OEMs compilan la imagen del sistema a partir de fuentes de AOSP, pueden reemplazar la imagen del sistema que compilan con la GSI que proporciona AOSP. Sin embargo, los OEM no necesitan llegar al paso final (usar la GSI tal como está) de una sola vez.

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

Cuando se hereda 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 de AOSP. Los OEM pueden modificar estos archivos para que la GSI del OEM contenga los archivos propiedad del OEM, además de los archivos de la GSI del AOSP. Sin embargo, los OEMs no pueden modificar el archivo generic_system.mk.

Herencia de "generic_system.mk" para la imagen del sistema del OEM

Figura 3: Hereda 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 de AOSP.

El GSI del OEM no puede tener archivos adicionales en esta etapa. Los archivos propietarios del OEM deben trasladarse a las particiones system_ext o product.

Cómo mover archivos agregados fuera del GSI del OEM

Figura 4: Cómo mover los archivos agregados fuera de la GSI de 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 OEMs pueden usar la herramienta compare_images y comparar la GSI de AOSP con la GSI del OEM. Obtén el GSI de AOSP del objetivo de lanzamiento 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 permitida. Esto evita que se necesiten modificaciones adicionales en el GSI del OEM.

Define una lista de entidades permitidas para reducir la lista de archivos modificados en el GSI del OEM

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

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

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

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

Figura 6: Cómo hacer que la GSI de OEM tenga los mismos objetos binarios que la GSI del AOSP

Define SSI para OEM

Protege la partición /system en el tiempo de compilación

Para evitar cambios específicos del producto en la partición /system y definir el GSI del OEM, los OEMs 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 de acceso de artefactos.

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

Aplica las interfaces de productos

Para garantizar que la partición /product no esté empaquetada, los OEMs 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 Java. Estas variables se establecen automáticamente si el PRODUCT_SHIPPING_API_LEVEL del dispositivo es mayor o igual que 30. Para obtener información detallada, consulta Aplica interfaces de partición de productos.

Haz que la partición /system_ext sea común

La partición /system_ext puede diferir entre dispositivos, ya que puede tener módulos específicos del dispositivo empaquetados 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. Para ello, deben quitar las diferencias y hacer que la partición /system_ext sea común.

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

Expone las 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 apps específicas del dispositivo a la partición del producto, quita el uso de APIs ocultas.

La forma preferida 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 OEMs pueden contribuir a AOSP para definir las nuevas APIs del sistema para sus dispositivos.

Como alternativa, los OEMs 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 inmovilizar las APIs orientadas al producto para brindar retrocompatibilidad.

Incluye el superconjunto de todos los APKs y omite algunas instalaciones de paquetes para cada dispositivo.

Algunos paquetes que se incluyen con el sistema no son comunes en todos los dispositivos. Puede ser difícil desvincular estos módulos de APK para moverlos al producto o a la partición del proveedor. Como solución provisional, los OEMs pueden hacer que el SSI incluya todos los módulos y, luego, filtrar los no deseados con una propiedad SKU (ro.boot.hardware.sku). Para usar el filtro, los OEMs 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 emisió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áticos

Una superposición de recursos estáticos manipula los paquetes superpuestos. Sin embargo, puede impedir la definición de un SSI, por lo que debes asegurarte de que las propiedades para RRO estén activadas y configuradas correctamente. Si configuras las propiedades de la siguiente manera, los OEMs 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 del entorno de ejecución (RRO). Los OEMs también pueden definir RRO condicionales que dependen de las propiedades del sistema con los atributos android:requiredSystemPropertyName y android:requiredSystemPropertyValue.

Preguntas frecuentes

¿Puedo definir varios SSI?

Depende de la similitud y las características de los dispositivos (o el grupo de dispositivos). Los OEMs 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. Sin embargo, los OEMs pueden definir un nuevo archivo make para un GSI de OEM que herede el archivo generic_system.mk y use el nuevo archivo make en su lugar. Para ver un ejemplo, consulta Enforcing Product Partition Interfaces.

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

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