Aplica las interfaces de partición de productos

Android 11 desagrupa la partición product para independizarla de las particiones system y vendor. Como parte de estos cambios, ahora puedes controlar el acceso de la partición product a aplicaciones nativas y Java de aplicaciones (que es similar a cómo funciona la aplicación de interfaz para vendor particiones).

Aplica interfaces nativas

Para habilitar la aplicación forzosa de la interfaz nativa, establece PRODUCT_PRODUCT_VNDK_VERSION en current. (La versión se establece automáticamente en current cuando se envía el nivel de API del destino es superior a 29). La aplicación permite lo siguiente:

  • Módulos nativos en la partición product para vincular:
    • De forma estática o dinámica a otros módulos en la partición product que incluir bibliotecas estáticas, compartidas o de encabezado.
    • De forma dinámica a las bibliotecas de VNDK en la partición system.
  • Bibliotecas JNI en APKs sin agrupar en la partición product para vincular con bibliotecas en /product/lib o /product/lib64 (esto se suma al NDK).

La aplicación forzosa no permite otros vínculos a particiones que no sean la partición product.

Aplicación en el tiempo de compilación (Android.bp)

En Android 11, los módulos del sistema pueden crear una variante de imagen del producto, además de las variantes de imagen del kernel y del proveedor. Cuando sea nativo la aplicación forzosa de la interfaz esté habilitada (PRODUCT_PRODUCT_VNDK_VERSION se establece en current):

  • Los módulos nativos en la partición product están en la variante del producto de la variante principal.

  • Los módulos con product_available: true en sus archivos Android.bp están disponibles para la variante del producto.

  • Las bibliotecas o los objetos binarios que especifican product_specific: true pueden vincularse a otras bibliotecas que especifiquen product_specific: true o product_available: true en sus archivos Android.bp.

  • Las bibliotecas del VNDK deben tener product_available: true en sus archivos Android.bp. por lo que los objetos binarios product se pueden vincular a las bibliotecas del VNDK.

En la siguiente tabla, se resumen las propiedades de Android.bp que se usan para crear imágenes variantes.

Propiedades en Android.bp Se crearon las variantes
Antes de la aplicación forzosa Después de la aplicación forzosa
predeterminada (ninguna) núcleo
(incluye /system, /system_ext y /product)

principal (incluye /system y /system_ext, pero no /product)
system_ext_specific: true core core
product_specific: true core producto
vendor: true de proveedor de proveedor
vendor_available: true núcleo, proveedor núcleo, proveedor
product_available: true N/A núcleo, producto
vendor_available: true Y product_available: true N/A principal, producto, proveedor
system_ext_specific: true Y vendor_available: true núcleo, proveedor núcleo, proveedor
product_specific: true Y vendor_available: true núcleo, proveedor producto, proveedor

Aplicación forzosa del tiempo de compilación (Android.mk)

Cuando se habilita la aplicación forzosa de la interfaz nativa, los módulos nativos instalados en el product partición tiene un tipo de vínculo native:product que solo se puede vincular a otros módulos native:product o native:vndk. Intentar vincular a alguna módulos que no sean estos provoca que el sistema de compilación genere una verificación del tipo de vínculo. .

Aplicación forzosa del tiempo de ejecución

Cuando se habilita la aplicación forzosa de la interfaz nativa, la configuración del vinculador para la el vinculador biónico no permite que los procesos del sistema usen bibliotecas product Creando una sección product para los procesos product que no se pueden vincular fuera de la partición product (sin embargo, esos procesos pueden vincularse a VNDK). Los intentos de incumplir la configuración del vínculo del entorno de ejecución hacen que el proceso falle y genere un mensaje de error CANNOT LINK EXECUTABLE.

Aplica interfaces de Java

Para habilitar la aplicación forzosa de la interfaz de Java, configura De PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE a true. (El valor es Se establece automáticamente en true cuando el nivel de API de envío para el destino es superior a 29). Cuando se habilita, la aplicación forzosa permite o rechaza lo siguiente acceso:

API /system /system_ext /product /vendor /data
API pública
@SistemaApi
API de @hide

Al igual que en la partición vendor, una app o una biblioteca de Java en la partición product solo puede usar APIs públicas y del sistema. No se permite vincular a una biblioteca que use APIs ocultas. Esta restricción incluye la vinculación en la compilación el tiempo y los reflejos en el tiempo de ejecución.

Aplicación del tiempo de compilación

En el tiempo de compilación, Make y Soong verifican que los módulos de Java en la partición product no usen APIs ocultas verificando los campos platform_apis y sdk_version. El sdk_version de las apps en la partición product debe Completar con current, system_current o la versión numérica de la API el campo platform_apis debe estar vacío.

Aplicación forzosa del tiempo de ejecución

El entorno de ejecución de Android verifica que las apps de la partición product no usen APIs ocultas, incluida la reflexión. Para obtener más información, consulta Restricciones sobre no perteneciente al SDK interfaces de programación de aplicaciones.

Habilita la aplicación de la interfaz de productos

Sigue los pasos que se indican en esta sección para habilitar la aplicación forzosa de la interfaz de producto.

Paso Tarea Obligatorio
1 Define tu propio archivo makefile del sistema que especifique los paquetes de la partición system y, luego, configura la verificación de requisitos de la ruta de acceso de los artefactos en el archivo device.mk (para evitar que se instalen módulos que no sean del sistema a la partición system). N
2 Limpia la lista de permitidos. N
3 Imponga interfaces nativas e identifique fallas en los vínculos del entorno de ejecución (puede ejecutarse en paralelo con la aplicación de Java). S
4 Aplica interfaces de Java y verifica el comportamiento del entorno de ejecución (se puede ejecutar en paralelo con la aplicación forzosa nativa). S
5 Verifica los comportamientos del tiempo de ejecución. S
6 Actualiza device.mk con la aplicación de la interfaz de producto. S

Paso 1: Crea un archivo makefile y habilita la verificación de la ruta de acceso del artefacto

En este paso, definirás el archivo makefile system.

  1. Crea un archivo makefile que defina los paquetes para la partición system. Por ejemplo, crea un archivo oem_system.mk con lo siguiente:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
    
    # Applications
    PRODUCT_PACKAGES += \
        CommonSystemApp1 \
        CommonSystemApp2 \
        CommonSystemApp3 \
    
    # Binaries
    PRODUCT_PACKAGES += \
        CommonSystemBin1 \
        CommonSystemBin2 \
        CommonSystemBin3 \
    
    # Libraries
    PRODUCT_PACKAGES += \
        CommonSystemLib1 \
        CommonSystemLib2 \
        CommonSystemLib3 \
    
    PRODUCT_SYSTEM_NAME := oem_system
    PRODUCT_SYSTEM_BRAND := Android
    PRODUCT_SYSTEM_MANUFACTURER := Android
    PRODUCT_SYSTEM_MODEL := oem_system
    PRODUCT_SYSTEM_DEVICE := generic
    
    # For system-as-root devices, system.img should be mounted at /, so we
    # include ROOT here.
    _my_paths := \
     $(TARGET_COPY_OUT_ROOT)/ \
     $(TARGET_COPY_OUT_SYSTEM)/ \
    
    $(call require-artifacts-in-path, $(_my_paths),)
    
  2. En el archivo device.mk, hereda el archivo makefile común para system. partición y habilitar la verificación de requisitos de la ruta de acceso a los artefactos. Por ejemplo:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk)
    
    # Enable artifact path requirements checking
    PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
    

Información acerca de los requisitos de la ruta de artefactos

Cuando PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS se establece en true o strict, el sistema de compilación evita que los paquetes definidos en otros archivos de configuración de make se instalen en las rutas de acceso definidas en require-artifacts-in-path y evita que los paquetes definidos en el archivo de configuración de make actual instalen artefactos fuera de las rutas de acceso definidas en require-artifacts-in-path.

En el ejemplo anterior, con PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS configurado como strict, los archivos makefile fuera de oem_system.mk no pueden incluir módulos instalados en la partición root o system. Para incluir estos módulos, debes definirlos en el archivo oem_system.mk o en un archivo makefile incluido. Los intentos de instalar módulos en rutas no permitidas provocan interrupciones en la compilación. Para corregir las pausas, realiza una de las siguientes acciones:

  • Opción 1: Incluye el módulo del sistema en los archivos makefile incluidos en oem_system.mk Esto hace que se cumpla el requisito de ruta de acceso del artefacto (ya que los módulos ahora existen en un archivo makefile incluido) y, por lo tanto, permite la instalación en el conjunto de rutas de acceso en "require-artifacts-in-path".

  • Opción 2: Instala módulos en la partición system_ext o product (y no instales módulos en la partición system).

  • Opción 3: Agrega módulos a PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST. Aquí se muestran los módulos permitidos instalarse.

Paso 2: Vacía la lista permitida

En este paso, harás que el elemento PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST vacío para que todos los dispositivos que comparten oem_system.mk también puedan compartir un solo system imagen. Para vaciar la lista permitida, mueve los módulos de la lista al Haz una partición de system_ext o product, o agrégalos a los archivos de creación system. Esta el paso es opcional porque no es necesario definir una imagen system común para habilitar la aplicación forzosa de la interfaz de producto. Sin embargo, es útil vaciar la lista de entidades permitidas para definir el límite system con system_ext.

Paso 3: Aplica interfaces nativas

En este paso, configurarás PRODUCT_PRODUCT_VNDK_VERSION := current y, luego, buscarás en busca de errores de compilación y entorno de ejecución, y resolverlos. Para verificar el inicio y los registros del dispositivo, así como encontrar y corregir fallas de vinculación del entorno de ejecución, haz lo siguiente:

  1. Establece PRODUCT_PRODUCT_VNDK_VERSION := current.

  2. Compila el dispositivo y busca errores de compilación. Es probable que veas que algunas pausas para variantes de productos o variantes principales faltantes. Pausas comunes incluyen:

    • Cualquier módulo hidl_interface que tenga product_specific: true no se disponibles para los módulos del sistema. Para solucionarlo, reemplaza product_specific: true por system_ext_specific: true.
    • Es posible que a los módulos les falte la variante de producto necesaria para los módulos de productos. Para solucionarlo, haz que ese módulo esté disponible para la partición product. Para ello, haz lo siguiente: Configura product_available: true o mueve el módulo a product. por separado mediante la configuración de product_specific: true.
  3. Resuelve los errores de compilación y asegúrate de que el dispositivo compile correctamente.

  4. Escribe la imagen en la memoria flash y busca errores de entorno de ejecución en el arranque y los registros del dispositivo.

    • Si la etiqueta linker de un registro de casos de prueba muestra una CANNOT LINK EXECUTABLE. mensaje, al archivo make le falta una dependencia (y este no se capturó en tiempo de compilación).
    • Para verificarlo desde el sistema de compilación, agrega la biblioteca requerida al campo shared_libs: o required:.
  5. Resuelve las dependencias faltantes con la guía anterior.

Paso 4: Aplica interfaces de Java

En este paso, configurarás PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true, y, luego, encontrar y corregir los errores de compilación resultantes. Busca dos tipos específicos de errores:

  • Errores de tipo de vínculo. Este error indica que una app se vincula a módulos de Java. que tienen un sdk_version más amplio. Para solucionarlo, puedes ampliar el sdk_version de la app o restringir el sdk_version de la biblioteca. Ejemplo de error:

    error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
    
  • Errores de símbolos: Este error indica que no se puede encontrar un símbolo porque está en una API oculta. Para solucionarlo, usa una API visible (no oculta) o busca un alternativa. Ejemplo de error:

    frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol
                ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
                                               ^
      symbol:   class ProxyAuthenticate
      location: class SipSessionGroup.SipSessionImpl
    

Paso 5: Verifica los comportamientos del entorno de ejecución

En este paso, verificas que los comportamientos del entorno de ejecución sean los esperados. En el caso de las apps que se pueden depurar, puedes supervisar el uso de la API oculta a través del registro con StrictMode.detectNonSdkApiUsage (que genera un registro cuando la app usa una API oculta). Como alternativa, puedes usar la herramienta de análisis estático veridex para obtener el tipo de uso (vinculación o reflexión), el nivel de restricción y la pila de llamadas.

  • Sintaxis de Veridex:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
  • Ejemplo de resultado de veridex:

    #1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s):
           Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V
    
    #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s):
           Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
    

Para obtener más información sobre el uso de veridex, consulta Cómo realizar pruebas con la herramienta veridex.

Paso 6: Actualiza device.mk

Después de corregir todas las fallas de compilación y entorno de ejecución, y verificar que los comportamientos del entorno de ejecución sean los esperados, establece lo siguiente en device.mk:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true