新增設備

使用此頁面中的資訊為您的裝置和產品建立 makefile。

每個新的 Android 模組都必須有一個配置文件,以使用模組元資料、編譯時依賴項和打包指令來指導建置系統。 Android 使用Soong 建置系統。有關 Android 構建系統的更多信息,請參閱構建 Android

了解建構層

建構層次結構包括與設備的物理構成相對應的抽象層。下表描述了這些層。每一層都與它上面的一層以一對多的關係相關。例如,一個架構可以有多個板,每個板可以有多個產品。您可以將給定層中的元素定義為同一層中元素的特化,這消除了複製並簡化了維護。

例子描述
產品myProduct、myProduct_eu、myProduct_eu_fr、j2、sdk產品層定義了運輸產品的功能規範,例如要建置的模組、支援的區域設定以及各種區域設定的配置。換句話說,這是整個產品的名稱。產品特定的變數在產品定義 makefile 中定義。一個產品可以繼承其他產品的定義,從而簡化維護。常見的方法是建立包含適用於所有產品的功能的基礎產品,然後基於該基礎產品建立產品變體。例如,僅無線電功能不同(CDMA 與 GSM)的兩種產品可以繼承未定義無線電功能的相同基本產品。
闆卡/設備馬林魚、藍線、珊瑚板/設備層代表設備上塑膠的物理層(即設備的工業設計)。該層也代表產品的裸原理圖。其中包括板上的周邊設備及其配置。使用的名稱只是不同板/設備配置的代碼。
臂、x86、arm64、x86_64架構層描述了板上運行的處理器配置和應用程式二進位介面(ABI)。

使用構建變體

在針對特定產品進行建置時,對最終發布版本進行微小的變更很有用。在模組定義中,模組可以使用LOCAL_MODULE_TAGS指定標籤,該標籤可以是optional (預設)、 debugeng中的一個或多個值。

如果模組未指定標籤(透過LOCAL_MODULE_TAGS ),則其標籤預設為optional 。只有當PRODUCT_PACKAGES的產品配置需要時,才會安裝選用模組。

這些是當前定義的構建變體。

變體描述
eng這是預設的口味。
  • 安裝標示engdebug的模組。
  • 除了標記的模組之外,還根據產品定義檔安裝模組。
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb預設啟用。
user該變體旨在成為最終版本。
  • 安裝標示為user模組。
  • 除了標記的模組之外,還根據產品定義檔安裝模組。
  • ro.secure=1
  • ro.debuggable=0
  • adb預設是禁用的。
userdebuguser相同,但有以下例外:
  • 也安裝標有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 建立產品,該文件聲明有關設備的產品特定信息,例如名稱和型號。您可以查看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特性允許將特定於變體的資源新增至套件。 tablet nosdcard
PRODUCT_COPY_FILESsource_path:destination_path這樣的單字列表。建置此產品時,應將來源路徑中的檔案複製到目標路徑。複製步驟的規則在config/makefile中定義。
PRODUCT_DEVICE工業外觀設計名稱。這也是板名稱,建造系統使用它來定位BoardConfig.mk tuna
PRODUCT_LOCALES以空格分隔的兩個字母語言代碼、兩個字母國家/地區代碼對的列表,描述使用者的多種設置,例如 UI 語言和時間、日期和貨幣格式。 PRODUCT_LOCALES中列出的第一個區域設定用作產品的預設區域設定。 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設定過濾器屬性值和預設語言,您可以配置限制,而無需將過濾器烘焙到系統映像中。您可以透過將這些屬性新增至PRODUCT_OEM_PROPERTIES變數來確保從 OEM 分區取得這些屬性,如下所示:

# 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 用戶端共用它們。這對於作業系統開發特別是測試很有用,因為它避免了手動與 adb 授權對話方塊互動的需要。

要建立供應商金鑰,一個人(通常是發布經理)應該:

  1. 使用adb keygen產生金鑰對。對於 Google 設備,Google 會為每個新作業系統版本產生一個新金鑰對。
  2. 檢查來源樹中某處的密鑰對。例如,Google 將它們儲存在vendor/google/security/adb/中。
  3. 將建置變數PRODUCT_ADB_KEYS設定為指向您的金鑰目錄。 Google 透過在金鑰目錄中新增一個Android.mk檔案來實現此目的,其中包含PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub ,這有助於確保我們記住為每個作業系統版本產生新的金鑰對。

這是 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 (如果尚未設定)。