Agregar un nuevo dispositivo

Utilice la información de esta página para crear los archivos MAKE para su dispositivo y producto.

Cada nuevo módulo de Android debe tener un archivo de configuración para dirigir el sistema de compilación con metadatos del módulo, dependencias en tiempo de compilación e instrucciones de empaquetado. Android utiliza el sistema de compilación Soong . Consulte Compilación de Android para obtener más información sobre el sistema de compilación de Android.

Comprender las capas de construcción

La jerarquía de construcción incluye las capas de abstracción que corresponden a la composición física de un dispositivo. Estas capas se describen en la siguiente tabla. Cada capa se relaciona con la que está encima en una relación de uno a muchos. Por ejemplo, una arquitectura puede tener más de una placa y cada placa puede tener más de un producto. Puede definir un elemento en una capa determinada como una especialización de un elemento en la misma capa, lo que elimina la copia y simplifica el mantenimiento.

Capa Ejemplo Descripción
Producto miProducto, miProducto_eu, miProducto_eu_fr, j2, sdk La capa de producto define la especificación de características de un producto de envío, como los módulos a construir, las configuraciones regionales admitidas y la configuración para varias configuraciones regionales. En otras palabras, este es el nombre del producto en general. Las variables específicas del producto se definen en archivos MAKE de definición de producto. Un producto puede heredar de otras definiciones de producto, lo que simplifica el mantenimiento. Un método común es crear un producto base que contenga características que se apliquen a todos los productos y luego crear variantes de producto basadas en ese producto base. Por ejemplo, dos productos que se diferencian sólo por sus radios (CDMA versus GSM) pueden heredar del mismo producto base que no define una radio.
Tablero/dispositivo marlín, línea azul, coral La capa de placa/dispositivo representa la capa física de plástico del dispositivo (es decir, el diseño industrial del dispositivo). Esta capa también representa los esquemas básicos de un producto. Estos incluyen los periféricos de la placa y su configuración. Los nombres utilizados son simplemente códigos para diferentes configuraciones de placa/dispositivo.
Arco brazo, x86, brazo64, x86_64 La capa de arquitectura describe la configuración del procesador y la interfaz binaria de aplicaciones (ABI) que se ejecuta en la placa.

Usando variantes de compilación

Al compilar para un producto en particular, es útil tener variaciones menores en la versión final. En una definición de módulo, el módulo puede especificar etiquetas con LOCAL_MODULE_TAGS , que pueden ser uno o más valores de optional (predeterminado), debug y eng .

Si un módulo no especifica una etiqueta (por LOCAL_MODULE_TAGS ), su etiqueta por defecto es optional . Se instala un módulo opcional solo si lo requiere la configuración del producto con PRODUCT_PACKAGES .

Estas son las variantes de compilación definidas actualmente.

Variante Descripción
eng Este es el sabor predeterminado.
  • Instala módulos etiquetados con eng o debug .
  • Instala módulos de acuerdo con los archivos de definición del producto, además de los módulos etiquetados.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb está habilitado de forma predeterminada.
user La variante pretendía ser los bits de lanzamiento final.
  • Instala módulos etiquetados con user .
  • Instala módulos de acuerdo con los archivos de definición del producto, además de los módulos etiquetados.
  • ro.secure=1
  • ro.debuggable=0
  • adb está deshabilitado de forma predeterminada.
userdebug Lo mismo que user , con estas excepciones:
  • También instala módulos etiquetados con debug .
  • ro.debuggable=1
  • adb está habilitado de forma predeterminada.

Directrices para la depuración de usuarios

La ejecución de compilaciones de depuración de usuario en las pruebas ayuda a los desarrolladores de dispositivos a comprender el rendimiento y el poder de las versiones en desarrollo. Para mantener la coherencia entre el usuario y las compilaciones de depuración del usuario, y para lograr métricas confiables en las compilaciones utilizadas para la depuración, los desarrolladores de dispositivos deben seguir estas pautas:

  • userdebug se define como una compilación de usuario con acceso raíz habilitado, excepto:
    • aplicaciones de solo depuración de usuario que el usuario ejecuta solo bajo demanda
    • Operaciones que se ejecutan solo durante el mantenimiento inactivo (con el cargador/completamente cargado), como el uso dex2oatd frente a dex2oat para compilaciones en segundo plano.
  • No incluya funciones que estén habilitadas/deshabilitadas de forma predeterminada según el tipo de compilación. Se desaconseja a los desarrolladores utilizar cualquier forma de registro que afecte la duración de la batería, como el registro de depuración o el volcado de montón.
  • Cualquier función de depuración habilitada de forma predeterminada en userdebug debe definirse claramente y compartirse con todos los desarrolladores que trabajan en el proyecto. Debe habilitar las funciones de depuración solo por tiempo limitado hasta que se resuelva el problema que está intentando depurar.

Personalizando la compilación con superposiciones de recursos

El sistema de compilación de Android utiliza superposiciones de recursos para personalizar un producto en el momento de la compilación. Las superposiciones de recursos especifican archivos de recursos que se aplican además de los valores predeterminados. Para utilizar superposiciones de recursos, modifique el archivo de compilación del proyecto para configurar PRODUCT_PACKAGE_OVERLAYS en una ruta relativa a su directorio de nivel superior. Esa ruta se convierte en una raíz oculta que se busca junto con la raíz actual cuando el sistema de compilación busca recursos.

Las configuraciones personalizadas más comúnmente están contenidas en el archivo frameworks/base/core/res/res/values/config.xml .

Para configurar una superposición de recursos en este archivo, agregue el directorio de superposición al archivo de compilación del proyecto usando uno de los siguientes:

PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay

o

PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay

Luego, agregue un archivo de superposición al directorio, por ejemplo:

vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml

Cualquier cadena o matriz de cadenas que se encuentre en el archivo config.xml de superposición reemplaza a las que se encuentran en el archivo original.

Construyendo un producto

Puedes organizar los archivos fuente de tu dispositivo de muchas maneras diferentes. A continuación se ofrece una breve descripción de una forma de organizar una implementación de Pixel.

Pixel se implementa con una configuración de dispositivo principal llamada marlin . A partir de esta configuración de dispositivo, se crea un producto con un archivo MAKE de definición de producto que declara información específica del producto sobre el dispositivo, como el nombre y el modelo. Puede ver el directorio device/google/marlin para ver cómo está configurado todo esto.

Escribir archivos MAKE de productos

Los siguientes pasos describen cómo configurar archivos MAKE de productos de forma similar a la de la línea de productos Pixel:

  1. Cree un directorio device/ <company-name> / <device-name> para su producto. Por ejemplo, device/google/marlin . Este directorio contendrá el código fuente de su dispositivo junto con los archivos MAKE para crearlos.
  2. Cree un archivo MAKE device.mk que declare los archivos y módulos necesarios para el dispositivo. Para ver un ejemplo, consulte device/google/marlin/device-marlin.mk .
  3. Cree un archivo MAKE de definición de producto para crear un producto específico basado en el dispositivo. El siguiente archivo MAKE está tomado de device/google/marlin/aosp_marlin.mk como ejemplo. Tenga en cuenta que el producto hereda de los archivos device/google/marlin/device-marlin.mk y vendor/google/marlin/device-vendor-marlin.mk a través del archivo MAKE y al mismo tiempo declara la información específica del producto, como nombre, marca, y modelo.
    # Inherit from the common Open Source product configuration
    $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
    
    PRODUCT_NAME := aosp_marlin
    PRODUCT_DEVICE := marlin
    PRODUCT_BRAND := Android
    PRODUCT_MODEL := AOSP on msm8996
    PRODUCT_MANUFACTURER := Google
    PRODUCT_RESTRICT_VENDOR_FILES := true
    
    PRODUCT_COPY_FILES += device/google/marlin/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.marlin
    
    $(call inherit-product, device/google/marlin/device-marlin.mk)
    $(call inherit-product-if-exists, vendor/google_devices/marlin/device-vendor-marlin.mk)
    
    PRODUCT_PACKAGES += \
        Launcher3QuickStep \
        WallpaperPicker
    

    Consulte Configuración de variables de definición de producto para obtener variables adicionales específicas del producto que puede agregar a sus archivos MAKE.

  4. Cree un archivo AndroidProducts.mk que apunte a los archivos MAKE del producto. En este ejemplo, sólo se necesita el archivo MAKE de definición del producto. El siguiente ejemplo es de device/google/marlin/AndroidProducts.mk (que contiene tanto el marlin, el Pixel, como el pez vela, el Pixel XL, que compartió la mayor parte de la configuración):
    PRODUCT_MAKEFILES := \
    	$(LOCAL_DIR)/aosp_marlin.mk \
    	$(LOCAL_DIR)/aosp_sailfish.mk
    
    COMMON_LUNCH_CHOICES := \
    	aosp_marlin-userdebug \
    	aosp_sailfish-userdebug
    
  5. Cree un archivo MAKE BoardConfig.mk que contenga configuraciones específicas de la placa. Para ver un ejemplo, consulte device/google/marlin/BoardConfig.mk .
  6. Solo para Android 9 y versiones anteriores , cree un archivo vendorsetup.sh para agregar su producto (un "combo de almuerzo") a la compilación junto con una variante de compilación separada por un guión. Por ejemplo:
    add_lunch_combo <product-name>-userdebug
    
  7. En este punto, puede crear más variantes de productos basadas en el mismo dispositivo.

Establecer variables de definición de producto

Las variables específicas del producto se definen en el archivo MAKE del producto. La tabla muestra algunas de las variables mantenidas en un archivo de definición de producto.

Variable Descripción Ejemplo
PRODUCT_AAPT_CONFIG Configuraciones aapt para usar al crear paquetes.
PRODUCT_BRAND La marca (por ejemplo, operador) para la que está personalizado el software.
PRODUCT_CHARACTERISTICS características aapt para permitir agregar recursos específicos de variantes a un paquete. tablet , nosdcard
PRODUCT_COPY_FILES Lista de palabras como source_path:destination_path . El archivo en la ruta de origen debe copiarse en la ruta de destino al crear este producto. Las reglas para los pasos de copia se definen en config/makefile .
PRODUCT_DEVICE Nombre del diseño industrial. Este también es el nombre de la placa y el sistema de compilación lo usa para ubicar BoardConfig.mk . tuna
PRODUCT_LOCALES Una lista separada por espacios de códigos de idioma de dos letras y pares de códigos de país de dos letras que describen varias configuraciones para el usuario, como el idioma de la interfaz de usuario y el formato de hora, fecha y moneda. La primera configuración regional enumerada en PRODUCT_LOCALES se utiliza como configuración regional predeterminada del producto. en_GB , de_DE , es_ES , fr_CA
PRODUCT_MANUFACTURER Nombre del fabricante. acme
PRODUCT_MODEL Nombre visible para el usuario final del producto final.
PRODUCT_NAME Nombre visible para el usuario final del producto general. Aparece en la pantalla Configuración > Acerca de .
PRODUCT_OTA_PUBLIC_KEYS Lista de claves públicas inalámbricas (OTA) para el producto.
PRODUCT_PACKAGES Lista de APK y módulos a instalar. Contactos del calendario
PRODUCT_PACKAGE_OVERLAYS Indica si se deben utilizar recursos predeterminados o agregar superposiciones específicas del producto. vendor/acme/overlay
PRODUCT_SYSTEM_PROPERTIES Lista de asignaciones de propiedades del sistema en el formato "key=value" para la partición del sistema. Las propiedades del sistema para otras particiones se pueden configurar a través de PRODUCT_<PARTITION>_PROPERTIES como en PRODUCT_VENDOR_PROPERTIES para la partición del proveedor. Nombres de partición admitidos: SYSTEM , VENDOR , ODM , SYSTEM_EXT y PRODUCT .

Configurar el idioma predeterminado del sistema y el filtro local

Utilice esta información para configurar el idioma predeterminado y el filtro de configuración regional del sistema, luego habilite el filtro de configuración regional para un nuevo tipo de dispositivo.

Propiedades

Configure tanto el idioma predeterminado como el filtro local del sistema utilizando propiedades dedicadas del sistema:

  • ro.product.locale : para configurar la configuración regional predeterminada. Inicialmente se establece en la primera configuración regional de la variable PRODUCT_LOCALES ; puedes anular ese valor. (Para obtener más información, consulte la tabla Configuración de variables de definición de producto ).
  • ro.localization.locale_filter : para configurar un filtro de configuración regional, utilizando una expresión regular aplicada a los nombres de la configuración regional. Por ejemplo:
    • Filtro inclusivo: ^(de-AT|de-DE|en|uk).* - permite solo el alemán (variantes de Austria y Alemania), todas las variantes inglesas del inglés y el ucraniano.
    • Filtro exclusivo: ^(?!de-IT|es).* - excluye alemán (variante de Italia) y todas las variantes de español.

Habilitar el filtro local

Para habilitar el filtro, establezca el valor de cadena de propiedad del sistema ro.localization.locale_filter .

Al configurar el valor de la propiedad del filtro y el idioma predeterminado a través de oem/oem.prop durante la calibración de fábrica, puede configurar restricciones sin incluir el filtro en la imagen del sistema. Asegúrese de que estas propiedades se recojan de la partición OEM agregándolas a la variable PRODUCT_OEM_PROPERTIES como se indica a continuación:

# Delegation for OEM customization
PRODUCT_OEM_PROPERTIES += \
    ro.product.locale \
    ro.localization.locale_filter

Luego, en producción, los valores reales se escriben en oem/oem.prop para reflejar los requisitos objetivo. Con este enfoque, los valores predeterminados se conservan durante el restablecimiento de fábrica, por lo que la configuración inicial se ve exactamente como una primera configuración para el usuario.

Configuración de ADB_VENDOR_KEYS para conectarse a través de USB

La variable de entorno ADB_VENDOR_KEYS permite a los fabricantes de dispositivos acceder a compilaciones depurables (-userdebug y -eng, pero no -user) a través de adb sin autorización manual. Normalmente, adb genera una clave de autenticación RSA única para cada computadora cliente, que enviará a cualquier dispositivo conectado. Esta es la clave RSA que se muestra en el cuadro de diálogo de autorización de adb. Como alternativa, puede crear claves conocidas en la imagen del sistema y compartirlas con el cliente adb. Esto es útil para el desarrollo del sistema operativo y especialmente para las pruebas porque evita la necesidad de interactuar manualmente con el cuadro de diálogo de autorización de adb.

Para crear claves de proveedor, una persona (normalmente un administrador de versiones) debe:

  1. Genere un par de claves usando adb keygen . Para los dispositivos de Google, Google genera un nuevo par de claves para cada nueva versión del sistema operativo.
  2. Verifique los pares de claves en algún lugar del árbol de origen. Google los almacena en vendor/google/security/adb/ , por ejemplo.
  3. Configure la variable de compilación PRODUCT_ADB_KEYS para que apunte a su directorio de claves. Google hace esto agregando un archivo Android.mk en el directorio de claves que dice PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub , lo que ayuda a garantizar que recordemos generar un nuevo par de claves para cada versión del sistema operativo.

Este es el archivo MAKE que Google utiliza en el directorio donde almacenamos nuestros pares de claves registrados para cada versión:

PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub

ifeq ($(wildcard $(PRODUCT_ADB_KEYS)),)
  $(warning ========================)
  $(warning The adb key for this release)
  $(warning )
  $(warning   $(PRODUCT_ADB_KEYS))
  $(warning )
  $(warning does not exist. Most likely PLATFORM_VERSION in build/core/version_defaults.mk)
  $(warning has changed and a new adb key needs to be generated.)
  $(warning )
  $(warning Please run the following commands to create a new key:)
  $(warning )
  $(warning   make -j8 adb)
  $(warning   LOGNAME=android-eng HOSTNAME=google.com adb keygen $(patsubst %.pub,%,$(PRODUCT_ADB_KEYS)))
  $(warning )
  $(warning and upload/review/submit the changes)
  $(warning ========================)
  $(error done)
endif

Para utilizar estas claves de proveedor, un ingeniero solo necesita configurar la variable de entorno ADB_VENDOR_KEYS para que apunte al directorio en el que se almacenan los pares de claves. Esto le indica a adb que pruebe primero estas claves canónicas, antes de recurrir a la clave de host generada que requiere autorización manual. Cuando adb no puede conectarse a un dispositivo no autorizado, el mensaje de error le sugerirá que configure ADB_VENDOR_KEYS si aún no lo está.