新增裝置

請使用本頁資訊,為裝置和產品建立 Makefile。

每個新的 Android 模組都必須有設定檔,以便透過模組中繼資料、編譯時間依附元件和封裝指示,引導建構系統。Android 使用 Soong 建構系統。如要進一步瞭解 Android 建構系統,請參閱「建構 Android」。

瞭解建構層

建構階層包含與裝置實體結構相對應的抽象層。下表說明這些圖層。每個層級都與上一個層級建立一對多關係。舉例來說,架構可以有多個電路板,而每個電路板都可能有多項產品。您可以將特定圖層中的元素定義為同一個圖層中元素的專屬元素,這樣就不必複製,也能簡化維護作業。

層次 範例 說明
產品 myProduct、myProduct_eu、myProduct_eu_fr、j2、sdk 產品層定義了發布產品的功能規格,例如要建構的模組、支援的語言代碼,以及各種語言代碼的設定。換句話說,這是整體產品的名稱。特定產品變數是在產品定義 Makefile 中定義。產品可繼承其他產品定義,簡化維護作業。常見的方法是建立基本產品,其中包含適用於所有產品的功能,然後根據該基本產品建立產品子類。舉例來說,如果兩項產品僅在無線電 (CDMA 與 GSM) 方面有所差異,則可從不定義無線電的相同基本產品繼承。
電路板/裝置 馬林魚、藍線、珊瑚 板/裝置層代表裝置上的塑膠實體層 (也就是裝置的工業設計)。這個圖層也代表產品的簡單示意圖。包括板上的周邊裝置和其設定。這些名稱只是不同主機板/裝置設定的代碼。
拱形 arm、x86、arm64、x86_64 架構層會說明處理器設定,以及在板上執行的應用程式二進位檔介面 (ABI)。

使用建構變化版本

為特定產品建構時,在最終發布版本中加入些微變化會很有幫助。在模組定義中,模組可以使用 LOCAL_MODULE_TAGS 指定標記,該標記可以是 optional (預設)、debugeng 的一或多個值。

如果模組未指定標記 (透過 LOCAL_MODULE_TAGS),其標記預設為 optional。只有在產品設定中使用 PRODUCT_PACKAGES 時,系統才會安裝選用模組。

這些是目前定義的建構變數。

Variant 說明
eng 這是預設風味。
  • 安裝標記為 engdebug 的模組。
  • 除了標記的模組外,也會根據產品定義檔案安裝模組。
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb 預設為啟用。
user 這個變化版本是最終發布版本。
  • 安裝標記為 user 的模組。
  • 除了標記的模組外,也會根據產品定義檔案安裝模組。
  • ro.secure=1
  • ro.debuggable=0
  • adb 預設為停用。
userdebug user 相同,但有以下例外狀況:
  • 也會安裝標記為 debug 的模組。
  • ro.debuggable=1
  • adb 預設為啟用。

userdebug 指南

在測試中執行 userdebug 版本,有助於裝置開發人員瞭解開發中版本的效能和功能。為維持使用者和 userdebug 版本之間的一致性,並在用於偵錯的版本中取得可靠的指標,裝置開發人員應遵循下列指南:

  • 使用者偵錯版本是指已啟用 root 存取權的使用者版本,但以下情況除外:
    • 僅供使用者隨需執行的 userdebug 專用應用程式
    • 僅在閒置維護期間 (充電中/已充飽電) 執行的作業,例如使用 dex2oatddex2oat 進行背景編譯
  • 請勿加入預設會根據建構類型啟用/停用的功能。我們不建議開發人員使用任何會影響電池續航力的記錄功能,例如偵錯記錄或堆積傾印。
  • 您應明確定義在 userdebug 中預設啟用的所有偵錯功能,並與所有專案開發人員分享。您應該只在有限時間內啟用偵錯功能,直到您要嘗試偵錯的問題解決為止。

使用資源重疊自訂建構作業

Android 建構系統會使用資源疊加層,在建構期間自訂產品。資源疊加層可指定在預設值上套用的資源檔案。如要使用資源重疊,請修改專案建構檔案,將 PRODUCT_PACKAGE_OVERLAYS 設為相對於頂層目錄的路徑。當建構系統搜尋資源時,該路徑會成為與目前根目錄一同搜尋的陰影根目錄。

最常見的自訂設定包含在 frameworks/base/core/res/res/values/config.xml 檔案中。

如要在這個檔案中設定資源疊加,請使用下列任一方法,將疊加目錄新增至專案建構檔:

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

PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay

接著,請在目錄中新增疊加檔案,例如:

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

重疊 config.xml 檔案中的任何字串或字串陣列,會取代原始檔案中的字串或字串陣列。

建構產品

您可以透過多種方式整理裝置的來源檔案。以下簡要說明 Pixel 實作項目的一種組織方式。

Pixel 是使用名為 marlin 的主要裝置設定導入。系統會使用產品定義的 Makefile 建立產品,該 Makefile 會宣告裝置的產品專屬資訊,例如名稱和型號。您可以查看 device/google/marlin 目錄,瞭解如何設定所有項目。

編寫產品 Makefile

下列步驟說明如何以類似於 Pixel 產品系列的方式設定產品 Makefile:

  1. 為產品建立 device/<company-name>/<device-name> 目錄。例如:device/google/marlin。這個目錄會包含裝置的來源碼,以及用於建構來源碼的 makefile。
  2. 建立 device.mk makefile,宣告裝置所需的檔案和模組。如需範例,請參閱 device/google/marlin/device-marlin.mk
  3. 建立產品定義 makefile,根據裝置建立特定產品。以下 makefile 取自 device/google/marlin/aosp_marlin.mk 做為範例。請注意,產品會透過 Makefile 繼承 device/google/marlin/device-marlin.mkvendor/google/marlin/device-vendor-marlin.mk 檔案,同時宣告產品專屬資訊,例如名稱、品牌和型號。
    # 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
    

    如要瞭解可新增至 Makefile 的其他產品專屬變數,請參閱「設定產品定義變數」。

  4. 建立指向產品 makefile 的 AndroidProducts.mk 檔案。在這個範例中,只需要產品定義 makefile。以下範例來自 device/google/marlin/AndroidProducts.mk (包含 marlin (Pixel) 和 sailfish (Pixel XL),兩者共用大部分設定):
    PRODUCT_MAKEFILES := \
    	$(LOCAL_DIR)/aosp_marlin.mk \
    	$(LOCAL_DIR)/aosp_sailfish.mk
    
    COMMON_LUNCH_CHOICES := \
    	aosp_marlin-userdebug \
    	aosp_sailfish-userdebug
    
  5. 建立包含板卡專屬設定的 BoardConfig.mk makefile。如需範例,請參閱 device/google/marlin/BoardConfig.mk
  6. 僅限 Android 9 以下版本,請建立 vendorsetup.sh 檔案,將產品 (「午餐組合」) 加入建構作業,並加上以破折號分隔的建構變化版本。例如:
    add_lunch_combo <product-name>-userdebug
    
  7. 此時,您可以根據相同裝置建立更多產品變化版本。

設定產品定義變數

產品專屬變數是在產品的 makefile 中定義。下表列出產品定義檔案中維護的部分變數。

變數 說明 示例
PRODUCT_AAPT_CONFIG 建立套件時要使用的 aapt 設定。
PRODUCT_BRAND 軟體自訂的品牌 (例如電信業者)。
PRODUCT_CHARACTERISTICS aapt 特徵,可讓您將變化版本專屬資源新增至套件。 tabletnosdcard
PRODUCT_COPY_FILES 列出 source_path:destination_path 之類的字詞。建構此產品時,來源路徑中的檔案應複製至目的地路徑。複製步驟的規則已在 config/makefile 中定義。
PRODUCT_DEVICE 工業設計名稱。這也是電路板名稱,而且建構系統會使用這個名稱來尋找 BoardConfig.mk tuna
PRODUCT_LOCALES 以空格分隔的清單,其中包含由兩個字母組成的語言代碼和國家/地區代碼組合,用於說明使用者的多項設定,例如 UI 語言、時間、日期和貨幣格式。PRODUCT_LOCALES 中列出的第 1 個語言代碼會做為產品的預設語言代碼。 en_GBde_DEes_ESfr_CA
PRODUCT_MANUFACTURER 製造商名稱。 acme
PRODUCT_MODEL 使用者看得到的最終產品名稱。
PRODUCT_NAME 使用者看得到的整體產品名稱。會顯示在「設定」>「關於」畫面中。
PRODUCT_OTA_PUBLIC_KEYS 產品的無線電視 (OTA) 公開金鑰清單。
PRODUCT_PACKAGES 要安裝的 APK 和模組清單。 日曆聯絡人
PRODUCT_PACKAGE_OVERLAYS 指出是否要使用預設資源,或新增任何產品專屬疊加層。 vendor/acme/overlay
PRODUCT_SYSTEM_PROPERTIES 系統分區的系統屬性指派項目清單,格式為 "key=value"。您可以透過 PRODUCT_<PARTITION>_PROPERTIES 設定其他分割區的系統屬性,就像為供應商分割區設定 PRODUCT_VENDOR_PROPERTIES 一樣。支援的分割區名稱:SYSTEMVENDORODMSYSTEM_EXTPRODUCT

設定預設系統語言和語言代碼篩選器

您可以利用這項資訊設定預設語言和系統語言代碼篩選器,然後為新裝置類型啟用語言代碼篩選器。

屬性

使用專屬的系統屬性,同時設定預設語言和系統語言代碼篩選器:

  • ro.product.locale:用於設定預設語言代碼。這個值一開始會設為 PRODUCT_LOCALES 變數中的首個語言代碼;您可以覆寫該值。(詳情請參閱「設定產品定義變數」表格)。
  • ro.localization.locale_filter:設定語言代碼篩選器,使用套用至語言代碼名稱的規則運算式。例如:
    • 包含篩選器:^(de-AT|de-DE|en|uk).* - 僅允許德文 (奧地利和德國變化版本)、所有英文變化版本和烏克蘭文
    • 專屬篩選器:^(?!de-IT|es).* - 排除德文 (義大利變化版本) 和所有西班牙文變化版本。

啟用語言代碼篩選器

如要啟用篩選器,請設定 ro.localization.locale_filter 系統屬性字串值。

在工廠校正期間透過 oem/oem.prop 設定篩選器屬性值和預設語言,即可設定限制,而不需要將篩選器加入系統映像檔。如要確保系統從 OEM 分割區擷取這些屬性,請按照下列指示將這些屬性新增至 PRODUCT_OEM_PROPERTIES 變數:

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

然後在實際生產環境中,實際值會寫入 oem/oem.prop,以反映目標需求。使用這種方法時,系統會在恢復原廠設定時保留預設值,因此初始設定會與使用者第一次設定時一模一樣樣。

設定 ADB_VENDOR_KEYS 以便透過 USB 連線

ADB_VENDOR_KEYS 環境變數可讓裝置製造商透過 ADB 存取可偵錯的版本 (-userdebug 和 -eng,但不包括 -user),而無須手動授權。一般來說,adb 會為每部用戶端電腦產生專屬的 RSA 驗證金鑰,並將其傳送至任何已連結的裝置。這是 ADB 授權對話方塊中顯示的 RSA 金鑰。您也可以將已知的金鑰建構至系統映像檔,並與 ADB 用戶端共用。這項功能對於 OS 開發作業 (尤其是測試) 特別實用,因為這樣就不必手動與 ADB 授權對話方塊互動。

如要建立供應商金鑰,請由一位人員 (通常是發布經理) 執行下列操作:

  1. 使用 adb keygen 產生金鑰組。針對 Google 裝置,Google 會為每個新作業系統版本產生新的金鑰組。
  2. 請檢查來源樹狀結構中的某處金鑰組。例如 Google 會將這些資訊儲存在 vendor/google/security/adb/ 中。
  3. 將建構變數 PRODUCT_ADB_KEYS 設為指向金鑰目錄。Google 會在 PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub 的金鑰目錄中新增 Android.mk 檔案,以確保我們記得為每個 OS 版本產生新的金鑰組。

以下是 Google 在儲存每個版本的簽入鍵值組合的目錄中使用的 makefile:

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

如要使用這些供應商金鑰,工程師只需將 ADB_VENDOR_KEYS 環境變數設為指向金鑰組儲存的目錄即可。這會告訴 adb 先嘗試這些標準鍵,再改用需要手動授權的產生主機鍵。如果 adb 無法連線至未經授權的裝置,錯誤訊息會建議您設定 ADB_VENDOR_KEYS (如果尚未設定)。