Hinzufügen eines neuen Geräts

Verwenden Sie die Informationen auf dieser Seite, um die Makefiles für Ihr Gerät und Produkt zu erstellen.

Jedes neue Android-Modul muss über eine Konfigurationsdatei verfügen, um das Build-System mit Modul-Metadaten, Abhängigkeiten zur Kompilierzeit und Verpackungsanweisungen zu steuern. Android verwendet das Song-Build-System . Weitere Informationen zum Android- Buildsystem finden Sie unter Erstellen von Android.

Build-Layer verstehen

Die Build-Hierarchie umfasst die Abstraktionsschichten, die dem physischen Aufbau eines Geräts entsprechen. Diese Schichten werden in der folgenden Tabelle beschrieben. Jede Schicht bezieht sich in einer Eins-zu-Viele-Beziehung auf die darüber liegende. Beispielsweise kann eine Architektur mehr als ein Board haben und jedes Board kann mehr als ein Produkt haben. Sie können ein Element in einer bestimmten Schicht als Spezialisierung eines Elements in derselben Schicht definieren, wodurch das Kopieren entfällt und die Wartung vereinfacht wird.

Schicht Beispiel Beschreibung
Produkt meinProdukt, meinProdukt_eu, meinProdukt_eu_fr, j2, sdk Die Produktebene definiert die Funktionsspezifikation eines Versandprodukts, wie z. B. die zu erstellenden Module, unterstützte Gebietsschemata und die Konfiguration für verschiedene Gebietsschemata. Mit anderen Worten, dies ist der Name des Gesamtprodukts. Produktspezifische Variablen werden in Produktdefinitions-Makefiles definiert. Ein Produkt kann von anderen Produktdefinitionen erben, was die Wartung vereinfacht. Eine gängige Methode besteht darin, ein Basisprodukt zu erstellen, das Funktionen enthält, die für alle Produkte gelten, und dann Produktvarianten basierend auf diesem Basisprodukt zu erstellen. Beispielsweise können zwei Produkte, die sich nur durch ihre Funkgeräte (CDMA versus GSM) unterscheiden, von demselben Basisprodukt erben, das kein Funkgerät definiert.
Platine/Gerät Marlin, Blueline, Koralle Die Platinen-/Geräteschicht stellt die physische Kunststoffschicht auf dem Gerät dar (d. h. das industrielle Design des Geräts). Diese Ebene repräsentiert auch die bloßen Schaltpläne eines Produkts. Dazu gehören die Peripheriegeräte auf dem Board und deren Konfiguration. Die verwendeten Namen sind lediglich Codes für unterschiedliche Platinen-/Gerätekonfigurationen.
Bogen arm, x86, arm64, x86_64 Die Architekturschicht beschreibt die Prozessorkonfiguration und die binäre Anwendungsschnittstelle (ABI), die auf der Platine ausgeführt werden.

Verwenden von Build-Varianten

Beim Erstellen für ein bestimmtes Produkt ist es hilfreich, geringfügige Abweichungen vom endgültigen Release-Build zu haben. In einer Moduldefinition kann das Modul Tags mit LOCAL_MODULE_TAGS angeben, die ein oder mehrere Werte von optional (Standard), debug und eng sein können.

Wenn ein Modul kein Tag angibt (durch LOCAL_MODULE_TAGS ), ist sein Tag standardmäßig optional . Ein optionales Modul wird nur installiert, wenn es von der Produktkonfiguration mit PRODUCT_PACKAGES wird.

Dies sind die derzeit definierten Build-Varianten.

Variante Beschreibung
eng Dies ist der Standardgeschmack.
  • Installiert Module, die mit eng oder debug sind.
  • Installiert Module gemäß den Produktdefinitionsdateien zusätzlich zu gekennzeichneten Modulen.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb ist standardmäßig aktiviert.
user Die Variante soll die endgültigen Release-Bits sein.
  • Installiert Module, die mit user gekennzeichnet sind.
  • Installiert Module gemäß den Produktdefinitionsdateien zusätzlich zu gekennzeichneten Modulen.
  • ro.secure=1
  • ro.debuggable=0
  • adb ist standardmäßig deaktiviert.
userdebug Dasselbe wie user , mit diesen Ausnahmen:
  • Installiert auch Module, die mit debug sind.
  • ro.debuggable=1
  • adb ist standardmäßig aktiviert.

Richtlinien für Userdebug

Das Ausführen von Userdebug-Builds beim Testen hilft Geräteentwicklern, die Leistung und Leistungsfähigkeit von in der Entwicklung befindlichen Releases zu verstehen. Um die Konsistenz zwischen Benutzer- und Benutzer-Debug-Builds aufrechtzuerhalten und zuverlässige Metriken in Builds zu erhalten, die zum Debuggen verwendet werden, sollten Geräteentwickler diese Richtlinien befolgen:

  • userdebug ist als Benutzer-Build mit aktiviertem Root-Zugriff definiert, außer:
    • Userdebug-only-Apps, die nur bei Bedarf vom Benutzer ausgeführt werden
    • Vorgänge, die nur während der Wartung im Leerlauf (auf dem Ladegerät/voll aufgeladen) ausgeführt werden, z. B. die Verwendung von dex2oatd im Vergleich zu dex2oat für Hintergrundkompilierungen
  • Schließen Sie keine Funktionen ein, die basierend auf dem Build-Typ standardmäßig aktiviert/deaktiviert sind. Entwicklern wird davon abgeraten, irgendeine Form der Protokollierung zu verwenden, die sich auf die Batterielebensdauer auswirkt, wie z. B. Debug-Protokollierung oder Heap-Dumping.
  • Alle Debugging-Funktionen, die standardmäßig in userdebug aktiviert sind, sollten klar definiert und mit allen Entwicklern geteilt werden, die an dem Projekt arbeiten. Sie sollten Debugging-Features nur zeitlich begrenzt aktivieren, bis das Problem, das Sie zu debuggen versuchen, behoben ist.

Anpassen des Builds mit Ressourcenüberlagerungen

Das Android-Build-System verwendet Ressourcen-Overlays, um ein Produkt zur Build-Zeit anzupassen. Ressourcenüberlagerungen geben Ressourcendateien an, die über den Standardeinstellungen angewendet werden. Um Ressourcenüberlagerungen zu verwenden, ändern Sie die Projekt-Builddatei, um PRODUCT_PACKAGE_OVERLAYS auf einen Pfad relativ zu Ihrem Verzeichnis der obersten Ebene festzulegen. Dieser Pfad wird zu einem Schattenstamm, der zusammen mit dem aktuellen Stamm durchsucht wird, wenn das Build-System nach Ressourcen sucht.

Die am häufigsten angepassten Einstellungen sind in der Datei frameworks/base/core/res/res/values/config.xml enthalten .

Um ein Ressourcen-Overlay für diese Datei einzurichten, fügen Sie das Overlay-Verzeichnis mit einer der folgenden Methoden zur Projekt-Build-Datei hinzu:

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

oder

PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay

Fügen Sie dann dem Verzeichnis eine Overlay-Datei hinzu, zum Beispiel:

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

Alle Strings oder String-Arrays, die in der Overlay-Datei config.xml gefunden werden, ersetzen die in der Originaldatei gefundenen.

Ein Produkt bauen

Sie können die Quelldateien für Ihr Gerät auf viele verschiedene Arten organisieren. Hier ist eine kurze Beschreibung einer Möglichkeit, eine Pixel-Implementierung zu organisieren.

Pixel wird mit einer Hauptgerätekonfiguration namens marlin implementiert. Aus dieser Gerätekonfiguration wird ein Produkt mit einem Produktdefinitions-Makefile erstellt, das produktspezifische Informationen über das Gerät wie Name und Modell deklariert. Sie können das Verzeichnis device/google/marlin anzeigen, um zu sehen, wie all dies eingerichtet ist.

Schreiben von Produkt-Makefiles

Die folgenden Schritte beschreiben, wie Produkt-Makefiles ähnlich wie bei der Pixel-Produktlinie eingerichtet werden:

  1. Erstellen Sie für Ihr Produkt ein Verzeichnis device/ <company-name> / <device-name> . Beispiel: device/google/marlin . Dieses Verzeichnis enthält den Quellcode für Ihr Gerät zusammen mit den Makefiles, um sie zu erstellen.
  2. Erstellen Sie ein Makefile device.mk , das die für das Gerät erforderlichen Dateien und Module deklariert. Ein Beispiel finden Sie unter device/google/marlin/device-marlin.mk .
  3. Erstellen Sie ein Produktdefinitions-Makefile, um ein bestimmtes Produkt basierend auf dem Gerät zu erstellen. Das folgende Makefile ist als Beispiel aus device/google/marlin/aosp_marlin.mk . Beachten Sie, dass das Produkt von den Dateien device/google/marlin/device-marlin.mk und „ vendor/google/marlin/device-vendor-marlin.mk über das Makefile erbt und gleichzeitig die produktspezifischen Informationen wie Name, Marke, und Modell.
    # 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
    

    Weitere produktspezifische Variablen, die Sie Ihren Makefiles hinzufügen können, finden Sie unter Festlegen von Produktdefinitionsvariablen .

  4. Erstellen Sie eine AndroidProducts.mk -Datei, die auf die Makefiles des Produkts verweist. In diesem Beispiel wird nur das Produktdefinitions-Makefile benötigt. Das folgende Beispiel stammt von device/google/marlin/AndroidProducts.mk (das sowohl marlin, das Pixel, als auch sailfish, das Pixel XL, enthält, das die meisten Konfigurationen gemeinsam hat):
    PRODUCT_MAKEFILES := \
    	$(LOCAL_DIR)/aosp_marlin.mk \
    	$(LOCAL_DIR)/aosp_sailfish.mk
    
    COMMON_LUNCH_CHOICES := \
    	aosp_marlin-userdebug \
    	aosp_sailfish-userdebug
    
  5. Erstellen Sie ein BoardConfig.mk -Makefile, das Board-spezifische Konfigurationen enthält. Ein Beispiel finden Sie unter device/google/marlin/BoardConfig.mk .
  6. Nur für Android 9 und niedriger : Erstellen Sie eine Datei " vendorsetup.sh ", um Ihr Produkt (eine "Mittagessen-Kombination") zum Build hinzuzufügen, zusammen mit einer Build-Variante , die durch einen Bindestrich getrennt ist. Zum Beispiel:
    add_lunch_combo <product-name>-userdebug
    
  7. An dieser Stelle können Sie weitere Produktvarianten basierend auf demselben Gerät erstellen.

Festlegen von Produktdefinitionsvariablen

Produktspezifische Variablen werden im Makefile des Produkts definiert. Die Tabelle zeigt einige der Variablen, die in einer Produktdefinitionsdatei verwaltet werden.

Variable Beschreibung Beispiel
PRODUCT_AAPT_CONFIG aapt Konfigurationen zur Verwendung beim Erstellen von Paketen.
PRODUCT_BRAND Die Marke (z. B. Spediteur), für die die Software angepasst ist, falls vorhanden.
PRODUCT_CHARACTERISTICS aapt Merkmale, um das Hinzufügen variantenspezifischer Ressourcen zu einem Paket zu ermöglichen. tablet , nosdcard
PRODUCT_COPY_FILES Liste von Wörtern wie source_path:destination_path . Die Datei im Quellpfad sollte beim Erstellen dieses Produkts in den Zielpfad kopiert werden. Die Regeln für die Kopierschritte werden in config/makefile definiert.
PRODUCT_DEVICE Name des Industriedesigns. Dies ist auch der Name des Boards, und das Build-System verwendet ihn, um BoardConfig.mk zu finden. tuna
PRODUCT_LOCALES Eine durch Leerzeichen getrennte Liste von Paaren aus zwei Buchstaben Sprachcode und zwei Buchstaben Ländercode, die mehrere Einstellungen für den Benutzer beschreiben, wie z. B. die Sprache der Benutzeroberfläche und Uhrzeit, Datum und Währungsformatierung. Das erste in PRODUCT_LOCALES aufgeführte Gebietsschema wird als Standardgebietsschema des Produkts verwendet. en_GB , de_DE , es_ES , fr_CA
PRODUCT_MANUFACTURER Name des Herstellers. acme
PRODUCT_MODEL Für den Endbenutzer sichtbarer Name des Endprodukts.
PRODUCT_NAME Für den Endbenutzer sichtbarer Name für das Gesamtprodukt. Erscheint im Bildschirm Einstellungen > Info .
PRODUCT_OTA_PUBLIC_KEYS Liste der öffentlichen OTA-Schlüssel (Over-the-Air) für das Produkt.
PRODUCT_PACKAGES Liste der zu installierenden APKs und Module. Kalenderkontakte
PRODUCT_PACKAGE_OVERLAYS Gibt an, ob Standardressourcen verwendet oder produktspezifische Overlays hinzugefügt werden sollen. vendor/acme/overlay
PRODUCT_SYSTEM_PROPERTIES Liste der Systemeigenschaftszuweisungen im Format "key=value" für die Systempartition. Systemeigenschaften für andere Partitionen können über PRODUCT_<PARTITION>_PROPERTIES wie in PRODUCT_VENDOR_PROPERTIES für die Herstellerpartition festgelegt werden. Unterstützte Partitionsnamen: SYSTEM , VENDOR , ODM , SYSTEM_EXT und PRODUCT .

Konfigurieren der Standardsystemsprache und des Gebietsschemafilters

Verwenden Sie diese Informationen, um die Standardsprache und den Gebietsschemafilter des Systems zu konfigurieren, und aktivieren Sie dann den Gebietsschemafilter für einen neuen Gerätetyp.

Eigenschaften

Konfigurieren Sie sowohl die Standardsprache als auch den Gebietsschemafilter des Systems mithilfe dedizierter Systemeigenschaften:

  • ro.product.locale : zum Festlegen des Standardgebietsschemas. Dies wird anfänglich auf das erste Gebietsschema in der Variablen PRODUCT_LOCALES ; Sie können diesen Wert überschreiben. (Weitere Informationen finden Sie in der Tabelle Produktdefinitionsvariablen festlegen .)
  • ro.localization.locale_filter : Zum Festlegen eines Gebietsschemafilters unter Verwendung eines regulären Ausdrucks, der auf Gebietsschemanamen angewendet wird. Zum Beispiel:
    • Inklusiver Filter: ^(de-AT|de-DE|en|uk).* - erlaubt nur Deutsch (Varianten Österreich und Deutschland), alle englischen Varianten des Englischen und Ukrainisch
    • Exklusiver Filter: ^(?!de-IT|es).* - schließt Deutsch (italienische Variante) und alle spanischen Varianten aus.

Aktivieren des Gebietsschemafilters

Um den Filter zu aktivieren, legen Sie den Zeichenfolgenwert der Systemeigenschaft ro.localization.locale_filter fest.

Durch Festlegen des Filtereigenschaftswerts und der Standardsprache über oem/oem.prop während der Werkskalibrierung können Sie Einschränkungen konfigurieren, ohne den Filter in das Systemabbild zu backen. Sie stellen sicher, dass diese Eigenschaften von der OEM-Partition übernommen werden, indem Sie sie wie unten angegeben zur Variablen PRODUCT_OEM_PROPERTIES hinzufügen:

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

In der Produktion werden dann die Ist-Werte nach oem/oem.prop geschrieben, um die Soll-Anforderungen widerzuspiegeln. Bei diesem Ansatz bleiben die Standardwerte während des Zurücksetzens auf die Werkseinstellungen erhalten, sodass die anfänglichen Einstellungen für den Benutzer genau wie eine erste Einrichtung aussehen.

Einstellen von ADB_VENDOR_KEYS zum Verbinden über USB

Die Umgebungsvariable ADB_VENDOR_KEYS ermöglicht Geräteherstellern den Zugriff auf debugfähige Builds (-userdebug und -eng, aber nicht -user) über adb ohne manuelle Autorisierung. Normalerweise generiert adb für jeden Client-Computer einen eindeutigen RSA-Authentifizierungsschlüssel, den es an jedes angeschlossene Gerät sendet. Dies ist der RSA-Schlüssel, der im adb-Autorisierungsdialog angezeigt wird. Alternativ können Sie bekannte Schlüssel in das Systemabbild einbauen und diese mit dem adb-Client teilen. Dies ist nützlich für die Betriebssystementwicklung und insbesondere zum Testen, da es die Notwendigkeit vermeidet, manuell mit dem ADB-Autorisierungsdialogfeld zu interagieren.

Um Lieferantenschlüssel zu erstellen, sollte eine Person (normalerweise ein Release-Manager) Folgendes tun:

  1. Generieren Sie ein Schlüsselpaar mit adb keygen . Für Google-Geräte generiert Google für jede neue Betriebssystemversion ein neues Schlüsselpaar.
  2. Überprüfen Sie die Schlüsselpaare irgendwo im Quellbaum. Google speichert sie beispielsweise vendor/google/security/adb/ .
  3. Legen Sie die Build-Variable PRODUCT_ADB_KEYS so fest, dass sie auf Ihr Schlüsselverzeichnis zeigt. Google tut dies, indem es eine Android.mk -Datei im Schlüsselverzeichnis hinzufügt, die besagt PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub , wodurch sichergestellt wird, dass wir daran denken, für jede Betriebssystemversion ein neues Schlüsselpaar zu generieren.

Hier ist das Makefile, das Google in dem Verzeichnis verwendet, in dem wir unsere eingecheckten Schlüsselpaare für jede Version speichern:

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

Um diese Herstellerschlüssel zu verwenden, muss ein Techniker nur die Umgebungsvariable ADB_VENDOR_KEYS so einstellen, dass sie auf das Verzeichnis zeigt, in dem die Schlüsselpaare gespeichert sind. Dies weist adb an, diese kanonischen Schlüssel zuerst auszuprobieren, bevor auf den generierten Hostschlüssel zurückgegriffen wird, der eine manuelle Autorisierung erfordert. Wenn adb keine Verbindung zu einem nicht autorisierten Gerät herstellen kann, schlägt die Fehlermeldung vor, dass Sie ADB_VENDOR_KEYS falls dies noch nicht geschehen ist.