Cómo agregar un nuevo dispositivo

Usa la información de esta página a fin de crear los archivos makefile para tu dispositivo y producto.

Cada módulo nuevo de Android debe tener un archivo de configuración para dirigir el sistema de compilación con metadatos del módulo, instrucciones de empaquetado y dependencias de tiempo de compilación. Android usa el sistema de compilación Soong. Consulta Cómo compilar Android para obtener más información sobre el sistema de compilación de Android.

Cómo interpretar las capas de compilación

La jerarquía de compilación incluye capas de abstracción que corresponden a la estructura física de un dispositivo. Estas capas se describen en la tabla que aparece a continuación. Cada una de ellas tiene una relación de uno a varios con la que está por encima. Por ejemplo, una arquitectura puede tener varias placas y cada placa puede tener varios productos. Puedes definir un elemento en una capa específica como una especialización de un elemento en la misma capa, lo que elimina la necesidad de copiado y simplifica el mantenimiento.

Capa Ejemplo Descripción
Producto myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk La capa define cuál es la función específica de un producto de envío, como los módulos a compilar, los idiomas compatibles y las diferentes configuraciones regionales. En otras palabras, este es el nombre del producto completo. Las variables específicas del producto se definen en los archivos makefile de definición del producto. Un producto puede heredar la configuración de otras definiciones del producto, lo que simplifica el mantenimiento. Un método común es crear un producto base que contenga las funciones que se aplican a todos los productos y, luego, crear variantes de productos basadas en este. Por ejemplo, si hay dos productos que solo se diferencian por las radios (CDMA frente a GSM), estos pueden heredarse del mismo producto base sin una radio definida.
Placa o dispositivo marlin, blueline, coral La capa de placa o dispositivo representa la capa física de plástico del dispositivo (es decir, el diseño industrial de este). Además, representa el esquema básico de un producto, lo que incluye los periféricos de la placa y su configuración. Los nombres usados son solo códigos para las diferentes opciones de configuración de la placa y del dispositivo.
Arquitectura arm, x86, arm64, x86_64 La capa de arquitectura describe la configuración del procesador y la interfaz binaria de la aplicación (ABI) que se ejecuta en la placa.

Cómo usar variantes de compilación

Cuando compilas un producto en particular, resulta útil realizar pequeñas modificaciones en la compilación de actualización final. En una definición de módulo, el módulo puede especificar etiquetas con LOCAL_MODULE_TAGS, que pueden ser uno o varios valores de optional (valor predeterminado), debug y eng.

Si no se especifica una etiqueta en un módulo (mediante LOCAL_MODULE_TAGS), el valor predeterminado es optional. Se instala un módulo opcional únicamente si la configuración del producto con PRODUCT_PACKAGES lo requiere.

Las variantes de compilación definidas actualmente son las siguientes:

Variante Descripción
eng Este es el tipo predeterminado.
  • Instala módulos etiquetados con eng o debug.
  • Instala módulos en función de 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 Es la variante destinada a ser la versión final.
    • Instala módulos etiquetados con user.
    • Instala módulos en función de los archivos de definición del producto, además de los módulos etiquetados.
    • ro.secure=1
    • ro.debuggable=0
    • adb está inhabilitado de forma predeterminada.
    userdebug Es igual que el valor user, con las siguientes excepciones:
    • También instala módulos etiquetados con debug.
    • ro.debuggable=1
    • adb está habilitado de forma predeterminada.

    Lineamientos para userdebug

    Ejecutar compilaciones de userdebug durante las pruebas ayuda a los desarrolladores de dispositivos a comprender el rendimiento y la potencia de las actualizaciones en desarrollo. A fin de mantener la coherencia entre el usuario y las compilaciones de userdebug, y lograr métricas confiables en las compilaciones que se usan para la depuración, los desarrolladores de dispositivos deben seguir estos lineamientos:

    • userdebug se define como una compilación de usuario con acceso de raíz habilitado, excepto por lo siguiente:
      • Las apps específicas de userdebug que se ejecutan solo a pedido del usuario.
      • Las operaciones que se ejecutan solo durante el mantenimiento inactivo (durante la carga o con carga completa), como usar dex2oatd frente a dex2oat para compilaciones en segundo plano.
    • No incluyas funciones que estén habilitadas o inhabilitadas de forma predeterminada según el tipo de compilación. No se aconseja que los desarrolladores usen ningún tipo de registro que afecte la duración de la batería, como el registro de depuración o el volcado de montón.
    • Todas las funciones de depuración que están habilitadas de forma predeterminada en userdebug deben estar claramente definidas y deben compartirse con todos los desarrolladores que trabajan en el proyecto. Solo debes habilitar las funciones de depuración por tiempo limitado hasta que se solucione el problema que intentas depurar.

    Cómo personalizar la compilación con superposiciones de recursos

    El sistema de compilación de Android usa superposiciones de recursos para personalizar un producto en el tiempo de compilación. Las superposiciones de recursos especifican archivos de recursos que se priorizan sobre los valores predeterminados. Para usarlas, modifica el archivo de compilación del proyecto a fin de establecer el valor PRODUCT_PACKAGE_OVERLAYS en una ruta de acceso relativa a tu directorio de nivel superior. Esta ruta se convierte en una raíz secundaria que se busca junto con la raíz actual cuando el sistema de compilación busca recursos.

    Las opciones de configuración que se personalizan con mayor frecuencia se encuentran en el archivo frameworks/base/core/res/res/values/config.xml.

    Para configurar una superposición de recursos en este archivo, agrega el directorio de superposiciones al archivo de compilación del proyecto de la siguiente manera:

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

    o

    PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
    

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

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

    Cualquier string o arreglo de strings que se encuentre en el archivo config.xml de superposición reemplazará a las strings que se encuentren en el archivo original.

    Cómo compilar un producto

    Existen muchas maneras de organizar los archivos fuente en tu dispositivo. Esta es una breve descripción de una manera de organizar una implementación de Pixel.

    Para implementar Pixel, se usa una configuración del dispositivo principal llamada marlin. A partir de esta, se crea un producto con un archivo makefile de definición del producto que declara la información específica de este sobre el dispositivo, como el nombre y el modelo. Puedes consultar el directorio device/google/marlin para ver cómo se realizó la configuración.

    Cómo escribir archivos makefile del producto

    En los siguientes pasos, se describe cómo configurar los archivos makefile de un producto de manera similar a la línea de productos Pixel:

    1. Crea un directorio device/<company-name>/<device-name> para tu producto. Por ejemplo, device/google/marlin. Este incluirá el código fuente del dispositivo junto con los archivos makefile para compilar.
    2. Crea un archivo makefile device.mk en el que se declaren los archivos y módulos necesarios para el dispositivo. Para ver un ejemplo, consulta device/google/marlin/device-marlin.mk.
    3. Crea un archivo makefile de definición del producto a fin de crear un producto específico basado en el dispositivo. El siguiente archivo makefile se toma de device/google/marlin/aosp_marlin.mk a modo de ejemplo. Observa que el producto hereda su configuración de los archivos device/google/marlin/device-marlin.mk y vendor/google/marlin/device-vendor-marlin.mk por medio del archivo makefile y, a su vez, declara la información específica del producto, como el nombre, la marca y el 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
      

      Consulta Cómo establecer variables de definición del producto para obtener variables específicas del producto que puedes agregar a tus archivos makefile.

    4. Crea un archivo AndroidProducts.mk que apunte a los archivos makefile del producto. En este ejemplo, solo se necesita el archivo makefile de la definición del producto. El ejemplo que aparece a continuación es del directorio device/google/marlin/AndroidProducts.mk (que contiene tanto marlin, el dispositivo Pixel, como sailfish, el dispositivo Pixel XL, los cuales comparten gran parte de su configuración):
      PRODUCT_MAKEFILES := \
      	$(LOCAL_DIR)/aosp_marlin.mk \
      	$(LOCAL_DIR)/aosp_sailfish.mk
      
      COMMON_LUNCH_CHOICES := \
      	aosp_marlin-userdebug \
      	aosp_sailfish-userdebug
      
    5. Crea un archivo makefile BoardConfig.mk que contenga las opciones de configuración específicas de la placa. Para ver un ejemplo, consulta device/google/marlin/BoardConfig.mk.
    6. Crea un archivo vendorsetup.sh para agregar tu producto (un "combo de almuerzo") a la compilación junto con una variante de compilación (separados por un guión). Por ejemplo:
      add_lunch_combo <product-name>-userdebug
      
    7. En este punto, puedes crear más variantes de productos basadas en el mismo dispositivo.

    Cómo establecer variables de definición del producto

    Las variables específicas del producto se definen en el archivo makefile de este. En la siguiente tabla, se muestran algunas de las variables incluidas en un archivo de definición del producto.

    Variable Descripción Ejemplo
    PRODUCT_AAPT_CONFIG Son opciones de configuración de aapt para usar durante la creación de paquetes.
    PRODUCT_BRAND Es la marca (por ejemplo, el proveedor) para la que se personaliza el software (si corresponde).
    PRODUCT_CHARACTERISTICS Son las características de aapt que permiten agregar recursos específicos de una variante al paquete. tablet, nosdcard
    PRODUCT_COPY_FILES Lista de palabras como source_path:destination_path. El archivo de la ruta de acceso de origen debe copiarse en la ruta de acceso de destino cuando se compila este producto. Las reglas para los pasos de copiado se definen en el archivo 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 localizar el archivo 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 opciones de configuración para el usuario, como el idioma de la IU y el formato de la hora, la fecha y la moneda. La primera configuración regional que aparece en el valor PRODUCT_LOCALES se usa como la configuración regional predeterminada del producto. en_GB, de_DE, es_ES, fr_CA
    PRODUCT_MANUFACTURER Es el nombre del fabricante. acme
    PRODUCT_MODEL Es el nombre visible del usuario final para el producto final.
    PRODUCT_NAME Es el nombre visible del usuario final para todo el producto. Aparece en la pantalla Configuración > Acerca de.
    PRODUCT_OTA_PUBLIC_KEYS Es la lista de claves públicas inalámbricas (OTA) para el producto.
    PRODUCT_PACKAGES Es la lista de los APK y módulos para instalar. Son los contactos del calendario
    PRODUCT_PACKAGE_OVERLAYS Indica si se deben usar los recursos predeterminados o se deben agregar superposiciones específicas del producto. vendor/acme/overlay
    PRODUCT_PROPERTY_OVERRIDES Es la lista de las asignaciones de propiedades del sistema en formato "key=value".

    Cómo configurar ANDROID_VENDOR_KEYS para que se conecte mediante USB

    La variable de entorno ANDROID_VENDOR_KEYS permite que los fabricantes de dispositivos accedan a las compilaciones de producción mediante adb. Genera una clave para todas las versiones que aceptarán los dispositivos, almacénalas internamente (por ejemplo, en vendor/oem-name/security/adb/) y, luego, usa el valor ANDROID_VENDOR_KEYS a fin de indicar a adb que utilice esas claves canónicas en lugar de claves aleatorias.

    Usa la variable de entorno ANDROID_VENDOR_KEYS para apuntar al directorio que contiene las claves públicas y privadas de adb generadas que se usan para la encriptación. La clave privada se almacena en file, y la clave pública en file.pub. La variable de entorno ANDROID_VENDOR_KEYS apunta a un archivo o directorio en el que se almacenan los pares de claves generados.

    La variable ANDROID_VENDOR_KEYS se configura en un archivo o directorio que contiene pares de claves de autenticación RSA de 2048 bits generadas con el comando de archivo adb keygen. Además de estos pares de claves, están los pares de claves RSA que genera el servidor ADB. Necesitas un par de claves RSA cuando usas adb para conectarte mediante USB por primera vez.

    Debes aceptar la clave RSA de la computadora host para otorgar acceso de adb al dispositivo de manera explícita. De forma predeterminada, los pares de claves que genera el servidor ADB se almacenan en los siguientes directorios del almacén de claves como adbkey (clave privada) y adbkey.pub (clave pública).

    En el caso de las ubicaciones de archivos, en macOS, por lo general, el directorio es $HOME/.android. En Windows, es %USERPROFILE%\.android, mientras que en Linux es $home\.android. En Windows, las claves de autenticación de RSA también pueden estar en C:\Windows\System32\config\systemprofile\.android.

    Cuando el servidor ADB necesita una clave, primero busca en el directorio del almacén de claves del servidor de ADB. En caso de no encontrar ninguna clave, el servidor revisa la variable de entorno ANDROID_VENDOR_KEYS. En caso de no encontrar ninguna clave, el servidor ADB local genera y guarda un nuevo par de claves en su directorio del almacén de claves.