Neues Gerät hinzufügen

Anhand der Informationen auf dieser Seite können Sie die Makefiles für Ihr Gerät und Produkt erstellen.

Jedes neue Android-Modul muss eine Konfigurationsdatei haben, um das Build-System mit Modulmetadaten, Compile-Time-Abhängigkeiten und Verpackungsanweisungen zu steuern. Android verwendet das Soong-Build-System. Weitere Informationen zum Android-Build-System finden Sie unter Android erstellen.

Build-Ebenen

Die Build-Hierarchie umfasst die Abstraktionsebenen, die der physischen Zusammensetzung eines Geräts entsprechen. Diese Ebenen werden in der Tabelle unten beschrieben. Jede Ebene steht in einer 1:n-Beziehung zur Ebene darüber. Eine Architektur kann beispielsweise mehrere Boards haben und jedes Board kann mehrere Produkte haben. Sie können ein Element in einer bestimmten Ebene als Spezialisierung eines Elements in derselben Ebene definieren. Dadurch wird das Kopieren vermieden und die Wartung vereinfacht.

Layer Beispiel Beschreibung
Produkt myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk Die Produktebene definiert die Funktionsspezifikation eines Versandprodukts, z. B. die zu erstellenden Module, die unterstützten Gebietsschemata und die Konfiguration für verschiedene Gebietsschemata. Mit anderen Worten: Das ist der Name des Gesamtprodukts. Produktspezifische Variablen werden in Makefiles für die Produktdefinition definiert. Ein Produkt kann von anderen Produktdefinitionen abgeleitet werden, was die Wartung vereinfacht. Eine gängige Methode ist, ein Basisprodukt mit Funktionen zu erstellen, die für alle Produkte gelten, und dann Produktvarianten auf Grundlage dieses Basisprodukts zu erstellen. Beispielsweise können zwei Produkte, die sich nur durch ihre Funkmodule (CDMA im Vergleich zu GSM) unterscheiden, vom selben Basisprodukt abgeleitet werden, in dem kein Funkmodul definiert ist.
Board/Gerät Marlin, Blueline, Coral Die Leiterplatten-/Geräteschicht stellt die physische Kunststoffschicht des Geräts dar, also das Industriedesign des Geräts. Diese Ebene stellt auch die bloßen Schemata eines Produkts dar. Dazu gehören die Peripheriegeräte auf dem Board und ihre Konfiguration. Die verwendeten Namen sind lediglich Codes für verschiedene Board-/Gerätekonfigurationen.
Bogen arm, x86, arm64, x86_64 Die Architekturschicht beschreibt die Prozessorkonfiguration und die Binärschnittstelle (Application Binary Interface, ABI), die auf dem Board ausgeführt wird.

Build-Varianten verwenden

Wenn Sie für ein bestimmtes Produkt entwickeln, sind geringfügige Abweichungen vom endgültigen Release-Build hilfreich. In einer Moduldefinition kann das Modul Tags mit LOCAL_MODULE_TAGS angeben. Das können ein oder mehrere Werte von optional (Standard), debug und eng sein.

Wenn für ein Modul kein Tag angegeben ist (über LOCAL_MODULE_TAGS), wird standardmäßig das Tag optional verwendet. Ein optionales Modul wird nur installiert, wenn es für die Produktkonfiguration mit PRODUCT_PACKAGES erforderlich ist.

Das sind die derzeit definierten Build-Varianten.

Variante Beschreibung
eng Dies ist die Standardvariante.
  • Installiert Module, die mit eng oder debug gekennzeichnet sind.
  • Installiert Module gemäß den Produktdefinitionsdateien sowie getaggte Module.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb ist standardmäßig aktiviert.
user Die Variante, die als endgültiger Release vorgesehen ist.
  • Installiert Module, die mit user getaggt sind.
  • Installiert Module gemäß den Produktdefinitionsdateien sowie getaggte Module.
  • ro.secure=1
  • ro.debuggable=0
  • adb ist standardmäßig deaktiviert.
userdebug Identisch mit user, mit folgenden Ausnahmen:
  • Installiert auch Module, die mit debug getaggt sind.
  • ro.debuggable=1
  • adb ist standardmäßig aktiviert.

Richtlinien für userdebug

Wenn Geräteentwickler Userdebug-Builds in Tests ausführen, können sie die Leistung und den Stromverbrauch von Releases in der Entwicklung besser nachvollziehen. Damit User- und Userdebug-Builds konsistent sind und zuverlässige Messwerte in Builds erzielt werden, die zum Debuggen verwendet werden, sollten Geräteentwickler die folgenden Richtlinien beachten:

  • „userdebug“ ist als Nutzer-Build mit aktiviertem Root-Zugriff definiert, mit folgenden Ausnahmen:
    • Apps, die nur für Nutzer mit dem Build-Typ „userdebug“ bestimmt sind und nur auf Anfrage des Nutzers ausgeführt werden
    • Vorgänge, die nur während der Wartung im Leerlauf ausgeführt werden (am Ladegerät/vollständig aufgeladen), z. B. die Verwendung von dex2oatd anstelle von dex2oat für Hintergrundkompilierungen
  • Fügen Sie keine Funktionen ein, die je nach Build-Typ standardmäßig aktiviert oder deaktiviert sind. Entwickler sollten keine Form der Protokollierung verwenden, die sich auf die Akkulaufzeit auswirkt, z. B. Debug-Protokollierung oder Heap-Dumping.
  • Alle Debugging-Funktionen, die in userdebug standardmäßig aktiviert sind, sollten klar definiert und für alle Entwickler, die am Projekt arbeiten, freigegeben werden. Sie sollten Debugging-Funktionen nur für einen begrenzten Zeitraum aktivieren, bis das Problem, das Sie beheben möchten, behoben ist.

Build mit Ressourcen-Overlays anpassen

Das Android-Build-System verwendet Ressourcen-Overlays, um ein Produkt zur Build-Zeit anzupassen. In Ressourcen-Overlays werden Ressourcendateien angegeben, die zusätzlich zu den Standardeinstellungen angewendet werden. Wenn Sie Ressourcen-Overlays verwenden möchten, müssen Sie die Build-Datei des Projekts so ändern, dass PRODUCT_PACKAGE_OVERLAYS auf einen Pfad relativ zu Ihrem Verzeichnis auf oberster Ebene festgelegt wird. Dieser Pfad wird zu einem Schattenstammverzeichnis, das zusammen mit dem aktuellen Stammverzeichnis 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.

Wenn Sie ein Ressourcen-Overlay für diese Datei einrichten möchten, fügen Sie dem Buildfile des Projekts das Overlay-Verzeichnis mit einer der folgenden Methoden hinzu:

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

oder

PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay

Fügen Sie dem Verzeichnis dann eine Overlay-Datei hinzu, z. B.:

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

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

Produkt entwickeln

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

Pixel wird mit einer Hauptgerätekonfiguration namens marlin implementiert. Aus dieser Gerätekonfiguration wird ein Produkt mit einer Make-Datei für die Produktdefinition erstellt, in der produktspezifische Informationen zum Gerät wie Name und Modell deklariert werden. Im Verzeichnis device/google/marlin können Sie sehen, wie alles eingerichtet ist.

Produkt-Makefiles schreiben

In den folgenden Schritten wird beschrieben, wie Sie Produkt-Makefiles ähnlich wie bei der Pixel-Produktlinie einrichten:

  1. Erstellen Sie ein device/<company-name>/<device-name>-Verzeichnis für Ihr Produkt. Beispiel: device/google/marlin. Dieses Verzeichnis enthält den Quellcode für Ihr Gerät sowie die Makefiles zum Erstellen des Codes.
  2. Erstellen Sie eine device.mk-Makefile-Datei, in der die für das Gerät erforderlichen Dateien und Module deklariert werden. Ein Beispiel finden Sie unter device/google/marlin/device-marlin.mk.
  3. Erstellen Sie eine Make-Datei für die Produktdefinition, um ein bestimmtes Produkt basierend auf dem Gerät zu erstellen. Das folgende Makefile stammt aus device/google/marlin/aosp_marlin.mk. Das Produkt erbt über die Make-Datei von den Dateien device/google/marlin/device-marlin.mk und vendor/google/marlin/device-vendor-marlin.mk und deklariert 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
    

    Unter Variablen für die Produktdefinition festlegen finden Sie weitere produktspezifische Variablen, die Sie Ihren Makefiles hinzufügen können.

  4. Erstellen Sie eine AndroidProducts.mk-Datei, die auf die Makefiles des Produkts verweist. In diesem Beispiel ist nur das Make-Datei für die Produktdefinition erforderlich. Das folgende Beispiel stammt aus device/google/marlin/AndroidProducts.mk (das sowohl „marlin“ für das Pixel als auch „sailfish“ für das Pixel XL enthält, die die meisten Konfigurationen gemeinsam nutzen):
    PRODUCT_MAKEFILES := \
    	$(LOCAL_DIR)/aosp_marlin.mk \
    	$(LOCAL_DIR)/aosp_sailfish.mk
    
    COMMON_LUNCH_CHOICES := \
    	aosp_marlin-userdebug \
    	aosp_sailfish-userdebug
    
  5. Erstellen Sie eine BoardConfig.mk-Makefile-Datei, die boardspezifische Konfigurationen enthält. Ein Beispiel finden Sie unter device/google/marlin/BoardConfig.mk.
  6. Nur für Android 9 und niedriger: Erstellen Sie eine vendorsetup.sh-Datei, um Ihr Produkt (ein „Mittagsmenü“) zusammen mit einer Build-Variante, die durch einen Bindestrich getrennt ist, dem Build hinzuzufügen. Beispiel:
    add_lunch_combo <product-name>-userdebug
    
  7. An dieser Stelle können Sie weitere Produktvarianten auf Grundlage desselben Geräts erstellen.

Variablen für die Produktdefinition festlegen

Produktspezifische Variablen werden in der Make-Datei des Produkts definiert. Die Tabelle enthält einige der Variablen, die in einer Produktdefinitionsdatei verwaltet werden.

Variable Beschreibung Beispiel
PRODUCT_AAPT_CONFIG aapt-Konfigurationen, die beim Erstellen von Paketen verwendet werden sollen.
PRODUCT_BRAND Die Marke (z. B. Mobilfunkanbieter), für die die Software angepasst wurde.
PRODUCT_CHARACTERISTICS aapt-Merkmale, um einem Paket variantenspezifische Ressourcen hinzuzufügen. tablet, nosdcard
PRODUCT_COPY_FILES Liste mit Wörtern wie source_path:destination_path. Die Datei im Quellpfad soll beim Erstellen dieses Produkts in den Zielpfad kopiert werden. Die Regeln für die Kopierschritte sind in config/makefile definiert.
PRODUCT_DEVICE Name des Designs. Dies ist auch der Name des Boards. Das Build-System verwendet ihn, um BoardConfig.mk zu finden. tuna
PRODUCT_LOCALES Eine durch Leerzeichen getrennte Liste von Paaren aus zweistelligem Sprachcode und zweistelligem Ländercode, die mehrere Einstellungen für den Nutzer beschreiben, z. B. die Sprache der Benutzeroberfläche sowie die Formatierung von Uhrzeit, Datum und Währung. Die erste Sprache, die in PRODUCT_LOCALES aufgeführt ist, wird als Standardsprache des Produkts verwendet. en_GB, de_DE, es_ES, fr_CA
PRODUCT_MANUFACTURER Name des Herstellers. acme
PRODUCT_MODEL Für Endnutzer sichtbarer Name des Endprodukts.
PRODUCT_NAME Für Endnutzer sichtbarer Name des Gesamtprodukts. Wird auf dem Bildschirm Einstellungen > Info angezeigt.
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 Zuweisungen von Systemeigenschaften im Format "key=value" für die Systempartition. Systemattribute für andere Partitionen können über PRODUCT_<PARTITION>_PROPERTIES wie in PRODUCT_VENDOR_PROPERTIES für die Anbieterpartition festgelegt werden. Unterstützte Partitionsnamen: SYSTEM, VENDOR, ODM, SYSTEM_EXT und PRODUCT.

Standardsystemsprache und Gebietsschemafilter konfigurieren

Konfigurieren Sie damit den Filter für die Standardsprache und das Systemgebietsschema und aktivieren Sie dann den Gebietsschemafilter für einen neuen Gerätetyp.

Properties

Konfigurieren Sie sowohl die Standardsprache als auch den System-Locale-Filter mit dedizierten Systemeigenschaften:

  • ro.product.locale: zum Festlegen des Standardschemas. Dieser Wert wird anfangs auf das erste Gebietsschema in der Variablen PRODUCT_LOCALES festgelegt. Sie können diesen Wert überschreiben. Weitere Informationen finden Sie in der Tabelle Variablen für die Produktdefinition festlegen.
  • ro.localization.locale_filter: zum Festlegen eines Gebietsschemafilters mit einem regulären Ausdruck, der auf Gebietsschemanamen angewendet wird. Beispiel:
    • Inklusiver Filter: ^(de-AT|de-DE|en|uk).* – lässt nur Deutsch (Varianten für Österreich und Deutschland), alle englischen Varianten und Ukrainisch zu.
    • Ausschlussfilter: ^(?!de-IT|es).* – schließt Deutsch (italienische Variante) und alle Varianten von Spanisch aus.

Sprachfilter aktivieren

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

Wenn Sie den Wert des Filterattributs und die Standardsprache während der Werkskalibrierung über oem/oem.prop festlegen, können Sie Einschränkungen konfigurieren, ohne den Filter in das System-Image einzubinden. Sie sorgen dafür, dass diese Eigenschaften aus der OEM-Partition übernommen werden, indem Sie sie der Variablen PRODUCT_OEM_PROPERTIES wie unten angegeben hinzufügen:

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

In der Produktion werden dann die tatsächlichen Werte in oem/oem.prop geschrieben, um die Zielanforderungen zu berücksichtigen. Bei diesem Ansatz bleiben die Standardwerte beim Zurücksetzen auf die Werkseinstellungen erhalten. Die ursprünglichen Einstellungen sehen für den Nutzer also genau wie bei einer Ersteinrichtung aus.

ADB_VENDOR_KEYS für die Verbindung über USB festlegen

Mit der Umgebungsvariable ADB_VENDOR_KEYS können Gerätehersteller über ADB ohne manuelle Autorisierung auf debugfähige Builds (-userdebug und -eng, aber nicht -user) zugreifen. Normalerweise generiert adb für jeden Clientcomputer einen eindeutigen RSA-Authentifizierungsschlüssel, der an alle verbundenen Geräte gesendet wird. Dies ist der RSA-Schlüssel, der im ADB-Autorisierungsdialogfeld angezeigt wird. Alternativ können Sie bekannte Schlüssel in das System-Image einbauen und für den ADB-Client freigeben. Das ist nützlich für die Betriebssystementwicklung und insbesondere für Tests, da es die manuelle Interaktion mit dem ADB-Autorisierungsdialog vermeidet.

So erstellen Sie Anbieterschlüssel:

  1. Generieren Sie mit adb keygen ein Schlüsselpaar. Für Google-Geräte generiert Google für jede neue Betriebssystemversion ein neues Schlüsselpaar.
  2. Sehen Sie sich die Schlüsselpaare im Quellbaum an. Google speichert sie beispielsweise in vendor/google/security/adb/.
  3. Legen Sie die Build-Variable PRODUCT_ADB_KEYS so fest, dass sie auf Ihr Schlüsselverzeichnis verweist. Google fügt dazu eine Android.mk-Datei in das Schlüsselverzeichnis ein, in der PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub steht. So wird sichergestellt, dass wir für jede Betriebssystemversion ein neues Schlüsselpaar generieren.

Hier ist das Make-Datei, die Google in dem Verzeichnis verwendet, in dem wir unsere eingecheckten Schlüsselpaare für jeden Release 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 Anbieterschlüssel zu verwenden, muss ein Entwickler nur die Umgebungsvariable ADB_VENDOR_KEYS so festlegen, dass sie auf das Verzeichnis verweist, in dem die Schlüsselpaare gespeichert sind. Dadurch wird adb angewiesen, diese kanonischen Schlüssel zuerst zu verwenden, bevor auf den generierten Hostschlüssel zurückgegriffen wird, für den eine manuelle Autorisierung erforderlich ist. Wenn adb keine Verbindung zu einem nicht autorisierten Gerät herstellen kann, wird in der Fehlermeldung vorgeschlagen, dass Sie ADB_VENDOR_KEYS festlegen, falls dies noch nicht geschehen ist.