Ajouter un appareil

Utilisez les informations de cette page pour créer les fichiers make pour votre appareil et votre produit.

Chaque nouveau module Android doit disposer d'un fichier de configuration pour diriger le système de compilation avec les métadonnées du module, les dépendances au moment de la compilation et les instructions d'empaquetage. Android utilise le système de compilation Soong. Pour en savoir plus sur le système de compilation Android, consultez Compilation d'Android.

Comprendre les couches de compilation

La hiérarchie de compilation inclut les couches d'abstraction qui correspondent à la composition physique d'un appareil. Ces calques sont décrits dans le tableau ci-dessous. Chaque couche est liée à celle qui la précède dans une relation de type un à plusieurs. Par exemple, une architecture peut comporter plusieurs cartes, et chaque carte peut comporter plusieurs produits. Vous pouvez définir un élément d'une couche donnée comme une spécialisation d'un élément de la même couche, ce qui élimine la copie et simplifie la maintenance.

Calque Exemple Description
Produit myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk La couche produit définit les spécifications des fonctionnalités d'un produit d'expédition, telles que les modules à créer, les paramètres régionaux compatibles et la configuration pour différents paramètres régionaux. En d'autres termes, il s'agit du nom du produit global. Les variables spécifiques aux produits sont définies dans les fichiers make de définition des produits. Un produit peut hériter d'autres définitions de produits, ce qui simplifie la maintenance. Une méthode courante consiste à créer un produit de base contenant des fonctionnalités qui s'appliquent à tous les produits, puis à créer des variantes de produit basées sur ce produit de base. Par exemple, deux produits qui ne diffèrent que par leur radio (CDMA ou GSM) peuvent hériter du même produit de base qui ne définit pas de radio.
Carte/appareil marlin, blueline, coral La couche de carte/d'appareil représente la couche physique de plastique sur l'appareil (c'est-à-dire le design industriel de l'appareil). Cette couche représente également les schémas de base d'un produit. Cela inclut les périphériques de la carte et leur configuration. Les noms utilisés ne sont que des codes pour différentes configurations de cartes/d'appareils.
Arc arm, x86, arm64, x86_64 La couche d'architecture décrit la configuration du processeur et l'interface binaire d'application (ABI) exécutée sur la carte.

Utiliser des variantes de compilation

Lorsque vous créez une application pour un produit spécifique, il est utile de disposer de petites variations de la version finale. Dans une définition de module, le module peut spécifier des tags avec LOCAL_MODULE_TAGS, qui peuvent être une ou plusieurs valeurs de optional (par défaut), debug et eng.

Si un module ne spécifie pas de tag (par LOCAL_MODULE_TAGS), son tag est défini par défaut sur optional. Un module facultatif n'est installé que s'il est requis par la configuration du produit avec PRODUCT_PACKAGES.

Voici les variantes de compilation actuellement définies.

Variant Description
eng Il s'agit de la saveur par défaut.
  • Installe les modules tagués avec eng ou debug.
  • Installe les modules en fonction des fichiers de définition du produit, en plus des modules tagués.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb est activé par défaut.
user Variante destinée à être la version finale.
  • Installe les modules tagués avec user.
  • Installe les modules en fonction des fichiers de définition du produit, en plus des modules tagués.
  • ro.secure=1
  • ro.debuggable=0
  • adb est désactivé par défaut.
userdebug Même chose que pour user, avec les exceptions suivantes :
  • Installe également les modules tagués avec debug.
  • ro.debuggable=1
  • adb est activé par défaut.

Consignes pour userdebug

L'exécution de builds userdebug lors des tests aide les développeurs d'appareils à comprendre les performances et la puissance des versions en développement. Pour assurer la cohérence entre les versions utilisateur et userdebug, et pour obtenir des métriques fiables dans les versions utilisées pour le débogage, les développeurs d'appareils doivent suivre ces consignes :

  • userdebug est défini comme un build utilisateur avec accès racine activé, sauf :
    • Applications userdebug uniquement exécutées à la demande par l'utilisateur
    • Opérations qui ne s'exécutent que pendant la maintenance inactive (sur le chargeur/entièrement chargé), comme l'utilisation de dex2oatd par rapport à dex2oat pour les compilations en arrière-plan
  • N'incluez pas de fonctionnalités activées/désactivées par défaut en fonction du type de compilation. Nous déconseillons aux développeurs d'utiliser toute forme de journalisation qui affecte l'autonomie de la batterie, comme la journalisation de débogage ou le vidage du tas.
  • Toutes les fonctionnalités de débogage activées par défaut dans userdebug doivent être clairement définies et partagées avec tous les développeurs travaillant sur le projet. Vous ne devez activer les fonctionnalités de débogage que pendant une durée limitée, jusqu'à ce que le problème que vous essayez de déboguer soit résolu.

Personnaliser la compilation avec des overlays de ressources

Le système de compilation Android utilise des calques de ressources pour personnaliser un produit au moment de la compilation. Les superpositions de ressources spécifient les fichiers de ressources qui sont appliqués en plus des valeurs par défaut. Pour utiliser des calques de ressources, modifiez le fichier de compilation du projet afin de définir PRODUCT_PACKAGE_OVERLAYS sur un chemin d'accès relatif à votre répertoire de premier niveau. Ce chemin d'accès devient une racine fantôme recherchée avec la racine actuelle lorsque le système de compilation recherche des ressources.

Les paramètres les plus souvent personnalisés se trouvent dans le fichier frameworks/base/core/res/res/values/config.xml.

Pour configurer une superposition de ressources sur ce fichier, ajoutez le répertoire de superposition au fichier de compilation du projet à l'aide de l'une des méthodes suivantes :

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

ou

PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay

Ajoutez ensuite un fichier de superposition au répertoire, par exemple :

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

Toutes les chaînes ou tableaux de chaînes trouvés dans le fichier config.xml de superposition remplacent ceux trouvés dans le fichier d'origine.

Créer un produit

Vous pouvez organiser les fichiers sources de votre appareil de différentes manières. Voici une brève description d'une façon d'organiser l'implémentation de Pixel.

Pixel est implémenté avec une configuration d'appareil principale nommée marlin. À partir de cette configuration d'appareil, un produit est créé avec un fichier make de définition de produit qui déclare des informations spécifiques au produit concernant l'appareil, telles que le nom et le modèle. Vous pouvez consulter le répertoire device/google/marlin pour voir comment tout cela est configuré.

Écrire des fichiers make de produit

Les étapes suivantes décrivent comment configurer les fichiers make de produit de manière semblable à celle de la gamme de produits Pixel :

  1. Créez un répertoire device/<company-name>/<device-name> pour votre produit. Par exemple, device/google/marlin. Ce répertoire contiendra le code source de votre appareil ainsi que les fichiers make pour les compiler.
  2. Créez un fichier make device.mk qui déclare les fichiers et les modules nécessaires pour l'appareil. Pour obtenir un exemple, consultez device/google/marlin/device-marlin.mk.
  3. Créez un fichier make de définition de produit pour créer un produit spécifique en fonction de l'appareil. Le makefile suivant est tiré de device/google/marlin/aosp_marlin.mk à titre d'exemple. Notez que le produit hérite des fichiers device/google/marlin/device-marlin.mk et vendor/google/marlin/device-vendor-marlin.mk via le fichier makefile, tout en déclarant les informations spécifiques au produit telles que le nom, la marque et le modèle.
    # 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
    

    Pour découvrir d'autres variables spécifiques aux produits que vous pouvez ajouter à vos fichiers make, consultez Définir des variables de définition de produit.

  4. Créez un fichier AndroidProducts.mk qui pointe vers les fichiers makefile du produit. Dans cet exemple, seul le fichier makefile de définition du produit est nécessaire. L'exemple ci-dessous provient de device/google/marlin/AndroidProducts.mk (qui contient à la fois marlin, le Pixel, et sailfish, le Pixel XL, qui partageaient la plupart des configurations) :
    PRODUCT_MAKEFILES := \
    	$(LOCAL_DIR)/aosp_marlin.mk \
    	$(LOCAL_DIR)/aosp_sailfish.mk
    
    COMMON_LUNCH_CHOICES := \
    	aosp_marlin-userdebug \
    	aosp_sailfish-userdebug
    
  5. Créez un fichier make BoardConfig.mk contenant des configurations spécifiques à la carte. Pour obtenir un exemple, consultez device/google/marlin/BoardConfig.mk.
  6. Pour Android 9 et versions antérieures uniquement, créez un fichier vendorsetup.sh pour ajouter votre produit (un "combo déjeuner") à la compilation avec une variante de compilation séparée par un tiret. Exemple :
    add_lunch_combo <product-name>-userdebug
    
  7. À ce stade, vous pouvez créer d'autres variantes de produit basées sur le même appareil.

Définir les variables de définition du produit

Les variables spécifiques aux produits sont définies dans le fichier makefile du produit. Le tableau présente certaines des variables conservées dans un fichier de définition de produit.

Variable Description Exemple
PRODUCT_AAPT_CONFIG Configurations aapt à utiliser lors de la création de packages.
PRODUCT_BRAND Marque (par exemple, opérateur) pour laquelle le logiciel est personnalisé.
PRODUCT_CHARACTERISTICS Caractéristiques aapt permettant d'ajouter des ressources spécifiques à une variante à un package. tablet, nosdcard
PRODUCT_COPY_FILES Liste de mots tels que source_path:destination_path. Le fichier situé au chemin d'accès source doit être copié vers le chemin d'accès de destination lors de la compilation de ce produit. Les règles pour les étapes de copie sont définies dans config/makefile.
PRODUCT_DEVICE Nom du design industriel. Il s'agit également du nom de la carte, que le système de compilation utilise pour localiser BoardConfig.mk. tuna
PRODUCT_LOCALES Liste de paires de codes de langue et de pays à deux lettres, séparées par un espace, qui décrivent plusieurs paramètres pour l'utilisateur, tels que la langue de l'interface utilisateur et le format de l'heure, de la date et de la devise. Le premier paramètre régional listé dans PRODUCT_LOCALES est utilisé comme paramètre régional par défaut du produit. en_GB, de_DE, es_ES, fr_CA
PRODUCT_MANUFACTURER Nom du fabricant. acme
PRODUCT_MODEL Nom du produit final visible par l'utilisateur final.
PRODUCT_NAME Nom du produit global visible par l'utilisateur final. S'affiche sur l'écran Paramètres > À propos.
PRODUCT_OTA_PUBLIC_KEYS Liste des clés publiques OTA (Over-The-Air) pour le produit.
PRODUCT_PACKAGES Liste des APK et des modules à installer. Contacts de l'agenda
PRODUCT_PACKAGE_OVERLAYS Indique s'il faut utiliser les ressources par défaut ou ajouter des calques spécifiques à un produit. vendor/acme/overlay
PRODUCT_SYSTEM_PROPERTIES Liste des attributions de propriétés système au format "key=value" pour la partition système. Les propriétés système des autres partitions peuvent être définies via PRODUCT_<PARTITION>_PROPERTIES, comme dans PRODUCT_VENDOR_PROPERTIES pour la partition du fournisseur. Noms de partition acceptés : SYSTEM, VENDOR, ODM, SYSTEM_EXT et PRODUCT.

Configurer le filtre de langue et de paramètres régionaux par défaut du système

Utilisez ces informations pour configurer le filtre de langue par défaut et de paramètres régionaux du système, puis activez le filtre de paramètres régionaux pour un nouveau type d'appareil.

Propriétés

Configurez à la fois la langue par défaut et le filtre de paramètres régionaux du système à l'aide de propriétés système dédiées :

  • ro.product.locale : pour définir les paramètres régionaux par défaut. Cette valeur est initialement définie sur le premier paramètre régional de la variable PRODUCT_LOCALES, mais vous pouvez la remplacer. (Pour en savoir plus, consultez le tableau Définir des variables de définition de produit.)
  • ro.localization.locale_filter : permet de définir un filtre de paramètres régionaux à l'aide d'une expression régulière appliquée aux noms de paramètres régionaux. Par exemple :
    • Filtre inclusif : ^(de-AT|de-DE|en|uk).* – n'autorise que l'allemand (variantes pour l'Allemagne et l'Autriche), toutes les variantes de l'anglais et l'ukrainien
    • Filtre exclusif : ^(?!de-IT|es).* – exclut l'allemand (variante italienne) et toutes les variantes de l'espagnol.

Activer le filtre de paramètres régionaux

Pour activer le filtre, définissez la valeur de chaîne de la propriété système ro.localization.locale_filter.

En définissant la valeur de la propriété de filtre et la langue par défaut via oem/oem.prop lors de la calibration en usine, vous pouvez configurer des restrictions sans intégrer le filtre dans l'image système. Pour vous assurer que ces propriétés sont extraites de la partition OEM, ajoutez-les à la variable PRODUCT_OEM_PROPERTIES comme indiqué ci-dessous :

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

Ensuite, en production, les valeurs réelles sont écrites dans oem/oem.prop pour refléter les exigences cibles. Avec cette approche, les valeurs par défaut sont conservées lors du rétablissement de la configuration d'usine. Les paramètres initiaux ressemblent donc exactement à une première configuration pour l'utilisateur.

Définir ADB_VENDOR_KEYS pour se connecter via USB

La variable d'environnement ADB_VENDOR_KEYS permet aux fabricants d'appareils d'accéder aux versions débogables (-userdebug et -eng, mais pas -user) via adb sans autorisation manuelle. Normalement, adb génère une clé d'authentification RSA unique pour chaque ordinateur client, qu'il envoie à tout appareil connecté. Il s'agit de la clé RSA affichée dans la boîte de dialogue d'autorisation adb. Vous pouvez également intégrer des clés connues dans l'image système et les partager avec le client adb. Cela est utile pour le développement de l'OS et en particulier pour les tests, car cela évite d'avoir à interagir manuellement avec la boîte de dialogue d'autorisation adb.

Pour créer des clés de fournisseur, une personne (généralement un responsable des versions) doit :

  1. Générez une paire de clés à l'aide de adb keygen. Pour les appareils Google, Google génère une nouvelle paire de clés pour chaque nouvelle version de l'OS.
  2. Enregistrez les paires de clés quelque part dans l'arborescence source. Google les stocke dans vendor/google/security/adb/, par exemple.
  3. Définissez la variable de compilation PRODUCT_ADB_KEYS pour qu'elle pointe vers votre répertoire de clés. Pour ce faire, Google ajoute un fichier Android.mk dans le répertoire de clés, qui indique PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub. Cela permet de s'assurer que nous générons une nouvelle paire de clés pour chaque version de l'OS.

Voici le fichier makefile que Google utilise dans le répertoire où nous stockons nos paires de clés enregistrées pour chaque version :

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

Pour utiliser ces clés de fournisseur, un ingénieur n'a qu'à définir la variable d'environnement ADB_VENDOR_KEYS pour qu'elle pointe vers le répertoire dans lequel les paires de clés sont stockées. Cela indique à adb d'essayer d'abord ces clés canoniques, avant de revenir à la clé hôte générée qui nécessite une autorisation manuelle. Lorsque adb ne parvient pas à se connecter à un appareil non autorisé, le message d'erreur vous suggère de définir ADB_VENDOR_KEYS si ce n'est pas déjà fait.