Aggiunta di un nuovo dispositivo

Usa le informazioni in questa pagina per creare i makefile per il tuo dispositivo e prodotto.

Ogni nuovo modulo Android deve avere un file di configurazione per indirizzare il sistema di compilazione con i metadati del modulo, le dipendenze in fase di compilazione e le istruzioni di confezionamento. Android utilizza il sistema di build Soong . Vedere Creazione di Android per ulteriori informazioni sul sistema di compilazione Android.

Comprensione dei livelli di costruzione

La gerarchia di build include i livelli di astrazione che corrispondono alla struttura fisica di un dispositivo. Questi livelli sono descritti nella tabella seguente. Ogni livello si riferisce a quello sopra di esso in una relazione uno-a-molti. Ad esempio, un'architettura può avere più di una scheda e ciascuna scheda può avere più di un prodotto. È possibile definire un elemento in un determinato livello come una specializzazione di un elemento nello stesso livello, il che elimina la copia e semplifica la manutenzione.

Strato Esempio Descrizione
Prodotto myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk Il livello del prodotto definisce le specifiche delle funzionalità di un prodotto di spedizione, ad esempio i moduli da creare, le localizzazioni supportate e la configurazione per le varie localizzazioni. In altre parole, questo è il nome del prodotto complessivo. Le variabili specifiche del prodotto sono definite nei makefile di definizione del prodotto. Un prodotto può ereditare da altre definizioni di prodotto, il che semplifica la manutenzione. Un metodo comune consiste nel creare un prodotto di base che contenga funzionalità che si applicano a tutti i prodotti, quindi creare varianti di prodotto basate su quel prodotto di base. Ad esempio, due prodotti che differiscono solo per le loro radio (CDMA e GSM) possono ereditare dallo stesso prodotto di base che non definisce una radio.
Scheda/dispositivo marlin, blueline, corallo Lo strato scheda/dispositivo rappresenta lo strato fisico di plastica sul dispositivo (ovvero il design industriale del dispositivo). Questo livello rappresenta anche gli schemi essenziali di un prodotto. Questi includono le periferiche sulla scheda e la loro configurazione. I nomi utilizzati sono semplicemente codici per diverse configurazioni di scheda/dispositivo.
Arco braccio, x86, braccio64, x86_64 Il livello dell'architettura descrive la configurazione del processore e l'interfaccia binaria dell'applicazione (ABI) in esecuzione sulla scheda.

Utilizzo di varianti di costruzione

Quando si compila per un prodotto particolare, è utile avere piccole variazioni sulla build della versione finale. Nella definizione di un modulo, il modulo può specificare tag con LOCAL_MODULE_TAGS , che possono essere uno o più valori di optional (predefinito), debug e eng .

Se un modulo non specifica un tag (da LOCAL_MODULE_TAGS ), il suo tag predefinito è optional . Un modulo opzionale viene installato solo se richiesto dalla configurazione del prodotto con PRODUCT_PACKAGES .

Queste sono le varianti di build attualmente definite.

Variante Descrizione
eng Questo è il sapore predefinito.
  • Installa i moduli taggati con eng o debug .
  • Installa i moduli in base ai file di definizione del prodotto, oltre ai moduli contrassegnati.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb è abilitato per impostazione predefinita.
user La variante doveva essere i bit di rilascio finali.
  • Installa i moduli taggati con user .
  • Installa i moduli in base ai file di definizione del prodotto, oltre ai moduli contrassegnati.
  • ro.secure=1
  • ro.debuggable=0
  • adb è disabilitato per impostazione predefinita.
userdebug Uguale a user , con queste eccezioni:
  • Installa anche i moduli contrassegnati con debug .
  • ro.debuggable=1
  • adb è abilitato per impostazione predefinita.

Linee guida per userdebug

L'esecuzione di build userdebug durante i test aiuta gli sviluppatori di dispositivi a comprendere le prestazioni e la potenza delle versioni in fase di sviluppo. Per mantenere la coerenza tra build utente e userdebug e per ottenere metriche affidabili nelle build utilizzate per il debug, gli sviluppatori di dispositivi dovrebbero seguire queste linee guida:

  • userdebug è definito come una build utente con accesso root abilitato, tranne:
    • app solo userdebug eseguite solo su richiesta dall'utente
    • Operazioni che vengono eseguite solo durante la manutenzione inattiva (con caricabatteria/completamente carico), come l'utilizzo di dex2oatd rispetto a dex2oat per le compilazioni in background
  • Non includere funzionalità abilitate/disabilitate per impostazione predefinita in base al tipo di build. Gli sviluppatori sono sconsigliati dall'utilizzare qualsiasi forma di registrazione che influisca sulla durata della batteria, come la registrazione del debug o l'heap dumping.
  • Qualsiasi funzionalità di debug abilitata per impostazione predefinita in userdebug deve essere chiaramente definita e condivisa con tutti gli sviluppatori che lavorano al progetto. Dovresti abilitare le funzionalità di debug solo per un periodo di tempo limitato fino a quando il problema di cui stai tentando di eseguire il debug non viene risolto.

Personalizzazione della build con overlay di risorse

Il sistema di build Android utilizza le risorse in sovrimpressione per personalizzare un prodotto in fase di build. Le sovrapposizioni di risorse specificano i file di risorse che vengono applicati in cima alle impostazioni predefinite. Per utilizzare le sovrapposizioni di risorse, modifica il file di build del progetto per impostare PRODUCT_PACKAGE_OVERLAYS su un percorso relativo alla directory di primo livello. Quel percorso diventa una radice ombra cercata insieme alla radice corrente quando il sistema di compilazione cerca le risorse.

Le impostazioni personalizzate più comunemente sono contenute nel file frameworks/base/core/res/res/values/config.xml .

Per impostare una sovrapposizione di risorse su questo file, aggiungi la directory di sovrapposizione al file di build del progetto utilizzando uno dei seguenti:

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

o

PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay

Quindi, aggiungi un file di sovrapposizione alla directory, ad esempio:

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

Eventuali stringhe o array di stringhe trovati nel file config.xml overlay sostituiscono quelli trovati nel file originale.

Costruire un prodotto

Puoi organizzare i file di origine per il tuo dispositivo in molti modi diversi. Ecco una breve descrizione di un modo per organizzare un'implementazione Pixel.

Pixel è implementato con una configurazione del dispositivo principale denominata marlin . Da questa configurazione del dispositivo, viene creato un prodotto con un makefile di definizione del prodotto che dichiara informazioni specifiche del prodotto sul dispositivo, come il nome e il modello. Puoi visualizzare la directory device/google/marlin per vedere come è impostato tutto questo.

Scrivere i makefile dei prodotti

I passaggi seguenti descrivono come impostare i makefile dei prodotti in modo simile a quello della linea di prodotti Pixel:

  1. Crea una directory device/ <company-name> / <device-name> per il tuo prodotto. Ad esempio, device/google/marlin . Questa directory conterrà il codice sorgente per il tuo dispositivo insieme ai makefile per crearli.
  2. Crea un makefile device.mk che dichiari i file e i moduli necessari per il dispositivo. Per un esempio, vedere device/google/marlin/device-marlin.mk .
  3. Crea un file di definizione del prodotto per creare un prodotto specifico in base al dispositivo. Il seguente makefile è preso da device/google/marlin/aosp_marlin.mk come esempio. Si noti che il prodotto eredita dai file device/google/marlin/device-marlin.mk e vendor/google/marlin/device-vendor-marlin.mk tramite il makefile dichiarando anche le informazioni specifiche del prodotto come nome, marca, e modello.
    # 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 Impostazione delle variabili di definizione del prodotto per ulteriori variabili specifiche del prodotto che puoi aggiungere ai tuoi makefile.

  4. Crea un file AndroidProducts.mk che punti ai makefile del prodotto. In questo esempio, è necessario solo il makefile della definizione del prodotto. L'esempio seguente proviene da device/google/marlin/AndroidProducts.mk (che contiene sia marlin, Pixel, sia sailfish, Pixel XL, che condividevano la maggior parte della configurazione):
    PRODUCT_MAKEFILES := \
    	$(LOCAL_DIR)/aosp_marlin.mk \
    	$(LOCAL_DIR)/aosp_sailfish.mk
    
    COMMON_LUNCH_CHOICES := \
    	aosp_marlin-userdebug \
    	aosp_sailfish-userdebug
    
  5. Crea un makefile BoardConfig.mk che contenga le configurazioni specifiche della scheda. Per un esempio, vedere device/google/marlin/BoardConfig.mk .
  6. Solo per Android 9 e versioni precedenti , crea un file vendorsetup.sh per aggiungere il tuo prodotto (un "pranzo combinato") alla build insieme a una variante di build separata da un trattino. Ad esempio:
    add_lunch_combo <product-name>-userdebug
    
  7. A questo punto puoi creare più varianti di prodotto in base allo stesso dispositivo.

Impostazione delle variabili di definizione del prodotto

Le variabili specifiche del prodotto sono definite nel makefile del prodotto. La tabella mostra alcune delle variabili gestite in un file di definizione del prodotto.

Variabile Descrizione Esempio
PRODUCT_AAPT_CONFIG aapt configurazioni da utilizzare durante la creazione di pacchetti.
PRODUCT_BRAND Il marchio (ad esempio, corriere) per il quale il software è personalizzato, se presente.
PRODUCT_CHARACTERISTICS caratteristiche aapt per consentire l'aggiunta di risorse specifiche per le varianti a un pacchetto. tablet , nosdcard
PRODUCT_COPY_FILES Elenco di parole come source_path:destination_path . Il file nel percorso di origine deve essere copiato nel percorso di destinazione durante la creazione di questo prodotto. Le regole per i passaggi di copia sono definite in config/makefile .
PRODUCT_DEVICE Nome del disegno industriale. Questo è anche il nome della scheda e il sistema di compilazione lo utilizza per individuare BoardConfig.mk . tuna
PRODUCT_LOCALES Un elenco separato da spazi di codici lingua di due lettere, coppie di codici paese di due lettere che descrivono diverse impostazioni per l'utente, come la lingua dell'interfaccia utente e l'ora, la data e la formattazione della valuta. La prima lingua elencata in PRODUCT_LOCALES viene utilizzata come lingua predefinita del prodotto. en_GB , de_DE , es_ES , fr_CA
PRODUCT_MANUFACTURER Nome del produttore. acme
PRODUCT_MODEL Nome visibile dall'utente finale per il prodotto finale.
PRODUCT_NAME Nome visibile dall'utente finale per l'intero prodotto. Appare nella schermata Impostazioni > Informazioni .
PRODUCT_OTA_PUBLIC_KEYS Elenco delle chiavi pubbliche over-the-air (OTA) per il prodotto.
PRODUCT_PACKAGES Elenco degli APK e dei moduli da installare. Contatti del calendario
PRODUCT_PACKAGE_OVERLAYS Indica se utilizzare le risorse predefinite o aggiungere eventuali sovrapposizioni specifiche del prodotto. vendor/acme/overlay
PRODUCT_SYSTEM_PROPERTIES Elenco delle assegnazioni delle proprietà di sistema nel formato "key=value" per la partizione di sistema. Le proprietà di sistema per altre partizioni possono essere impostate tramite PRODUCT_<PARTITION>_PROPERTIES come in PRODUCT_VENDOR_PROPERTIES per la partizione del fornitore. Nomi di partizione supportati: SYSTEM , VENDOR , ODM , SYSTEM_EXT e PRODUCT .

Configurazione della lingua di sistema predefinita e del filtro delle impostazioni locali

Utilizzare queste informazioni per configurare la lingua predefinita e il filtro delle impostazioni locali del sistema, quindi abilitare il filtro delle impostazioni locali per un nuovo tipo di dispositivo.

Proprietà

Configura sia la lingua predefinita che il filtro delle impostazioni locali del sistema utilizzando le proprietà di sistema dedicate:

  • ro.product.locale : per impostare la locale predefinita. Inizialmente è impostato sulla prima locale nella variabile PRODUCT_LOCALES ; puoi sovrascrivere quel valore. (Per ulteriori informazioni, vedere la tabella Impostazione delle variabili di definizione del prodotto .)
  • ro.localization.locale_filter : per impostare un filtro delle impostazioni locali, utilizzando un'espressione regolare applicata ai nomi delle impostazioni locali. Per esempio:
    • Filtro inclusivo: ^(de-AT|de-DE|en|uk).* - consente solo il tedesco (varianti Austria e Germania), tutte le varianti inglesi dell'inglese e l'ucraino
    • Filtro esclusivo: ^(?!de-IT|es).* - esclude il tedesco (variante per l'Italia) e tutte le varianti dello spagnolo.

Abilitazione del filtro locale

Per abilitare il filtro, impostare il valore della stringa della proprietà di sistema ro.localization.locale_filter .

Impostando il valore della proprietà del filtro e la lingua predefinita tramite oem/oem.prop durante la calibrazione di fabbrica è possibile configurare le restrizioni senza inserire il filtro nell'immagine del sistema. Assicurati che queste proprietà vengano prelevate dalla partizione OEM aggiungendole alla variabile PRODUCT_OEM_PROPERTIES come indicato di seguito:

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

Quindi in produzione i valori effettivi vengono scritti in oem/oem.prop , per riflettere i requisiti di destinazione. Con questo approccio, i valori predefiniti vengono mantenuti durante il ripristino delle impostazioni di fabbrica, quindi le impostazioni iniziali sembrano esattamente come una prima configurazione per l'utente.

Impostazione di ADB_VENDOR_KEYS per la connessione tramite USB

La variabile di ambiente ADB_VENDOR_KEYS consente ai produttori di dispositivi di accedere a build di cui è possibile eseguire il debug (-userdebug e -eng, ma non -user) su adb senza autorizzazione manuale. Normalmente adb genera una chiave di autenticazione RSA univoca per ogni computer client, che invierà a qualsiasi dispositivo connesso. Questa è la chiave RSA mostrata nella finestra di dialogo di autorizzazione adb. In alternativa puoi creare chiavi conosciute nell'immagine di sistema e condividerle con il client adb. Ciò è utile per lo sviluppo del sistema operativo e soprattutto per i test perché evita la necessità di interagire manualmente con la finestra di dialogo di autorizzazione adb.

Per creare le chiavi del fornitore, una persona (di solito un responsabile del rilascio) deve:

  1. Genera una coppia di chiavi usando adb keygen . Per i dispositivi Google, Google genera una nuova coppia di chiavi per ogni nuova versione del sistema operativo.
  2. Controlla le coppie di chiavi, da qualche parte nell'albero dei sorgenti. Google li memorizza in vendor/google/security/adb/ , ad esempio.
  3. Imposta la variabile di build PRODUCT_ADB_KEYS in modo che punti alla directory delle tue chiavi. Google lo fa aggiungendo un file Android.mk nella directory delle chiavi che dice PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub , che aiuta a ricordare di generare una nuova coppia di chiavi per ogni versione del sistema operativo.

Ecco il makefile utilizzato da Google nella directory in cui memorizziamo le nostre coppie di chiavi archiviate per ogni versione:

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

Per utilizzare queste chiavi del fornitore, un tecnico deve solo impostare la variabile di ambiente ADB_VENDOR_KEYS in modo che punti alla directory in cui sono archiviate le coppie di chiavi. Questo dice ad adb di provare prima queste chiavi canoniche, prima di ricadere sulla chiave host generata che richiede l'autorizzazione manuale. Quando adb non riesce a connettersi a un dispositivo non autorizzato, il messaggio di errore suggerirà di impostare ADB_VENDOR_KEYS se non è già impostato.