建構及部署服務套裝組合

建立中介軟體並編寫自訂程式碼後,您就可以將服務套件部署為 APEX 檔案。

  1. 建立 SDV 設定檔:

    Rust

    1. 執行下列指令,產生 SDV 設定檔:

      vsidlc -c /path/to/catalog -o /path/to/output --apex
      

      使用 --apex 標記執行 vsidlc 時,系統會自動產生所有必要的設定檔,包括:

      • APEX 資訊清單 (apex_manifest.json)
      • SDV 中繼資料資訊清單 (sdv_service_bundles_manifest.textproto)
      • 連結器設定 (linker.config.json)
      • SELinux 檔案情境 (file_contexts)
      • 公開和私密金鑰 (.avbpubkey.pem)
      • 權限聲明和自動化調度管理設定
      • 定義所有必要 Soong 模組的 Android.bp 檔案。

      您可以在下列位置找到產生的設定:

      /path/to/output/apex/
      

      以及

      /path/to/output/configs/
      

    C++

    1. 建立 SDV 中繼資料資訊清單檔案, service_bundle.manifest.textproto 並包含下列必要執行中繼資料欄位:

      • 服務名稱 (須符合命名慣例)
      • 服務套裝組合版本的整數和字串表示法
      • 先前建立的程式庫路徑

      準備必要的服務套裝組合中繼資料,是服務套裝組合封裝和部署作業的必要條件。

      # proto-file: //system/software_defined_vehicle/core_services/service_bundles_registry/proto/sdv_service_bundles_manifest.proto
      # proto-message: SdvServiceBundleManifestEntry
      
      # SDV service bundle metadata definition with mandatory fields.
      sdv_service_bundle_metadata {
        # Service bundle name.
        name: "ServiceBundleName"
        # Service bundle integer version.
        version_number: 42
        # Service bundle version as a string.
        version_name: "42.alpha"
        # Service bundle library path.
        native_library_path: "lib64/libservice_bundle.so"
      }
      
    2. 建立新的連結器設定檔案, linker.config.json

      { "visible": true }
      
    3. 建立新的 apex_manifest.json 檔案,並加入下列欄位:

      • 根據 SDV 命名慣例的不重複 SDV 套件名稱
      • APEX 版本
      • 依附於 SDV Comms 程式庫
      {
        "name": "com.sdv.oem.apex_and_module_name",
        "version": 1,
        "requireNativeLibs": [
            "libsdv_comms_ctx_ffi.so",
            "libsdv_comms_dt_ffi.so",
            "libsdv_comms_id_ffi.so",
            "libsdv_comms_sd_ffi.so"
        ]
      }
      
    4. 建立公開金鑰 (apex_name.apex_key.avbpubkey) 和私密金鑰 (apex_name.apex_key.pem)。

    5. 建立新的 SELinux 檔案內容 apex_file_contexts

      (/.*)?    u:object_r:system_file:s0
      

      詳情請參閱「安全環境和類別」。

    6. 在新的或現有的 Android.bp 檔案中建立預先建構的目標:

      // SDV manifest file prebuilt.
      prebuilt_etc {
          name: "com.sdv.oem.apex_and_module_name.service_bundles_manifest",
          // The source filename of the manifest file.
          src: "service_bundle.manifest.textproto",
          // The name of the installed file needs be `sdv_service_bundles_manifest.textproto`.
          filename: "sdv_service_bundles_manifest.textproto",
          // Disable direct installation of the prebuilt to one of the partitions.
          // The manifest is used only inside of an apex.
          installable: false,
      }
      // The linker config to allow libraries for the apex to be linkable.
      linker_config {
          name: "com.sdv.oem.apex_and_module_name. linker_config",
          src: "linker.config.json",
          // Disable direct installation of the prebuilt to one of the partitions.
          // The linker configuration is used only inside of an apex.
          installable: false,
      }
      // Key to be used for signing the apex.
      apex_key {
          name: "apex_name.apex_key",
          public_key: "apex_name.apex_key.avbpubkey",
          private_key: "apex_name.apex_key.pem",
      }
      
    7. 在新的或現有的 Android.bp 檔案中建立新的 APEX 模組。請使用 SDV 套件名稱做為 APEX 模組名稱。

      apex {
          name: "com.sdv.oem.apex_and_module_name",
          // The service bundle(s) to be included in the apex.
          native_shared_libs: [
              "libservice_bundle",
          ],
          prebuilts: [
              // SDV service bundles manifest file.
              "com.sdv.oem.apex_and_module_name.service_bundles_manifest",
              // Linker configuration to enable loading library from apex.
              "com.sdv.oem.apex_and_module_name.linker_config",
          ],
          // Json manifest file describes metadata of the APEX package.
          // The 'name' field from the JSON is used as a mounting point.
          manifest: "apex_manifest.json",
          // Setting the security contexts to files in this APEX bundle.
          file_contexts: "apex_file_contexts",
          // Name of the apex_key module that provides the private key to sign the APEX bundle.
          key: "apex_name.apex_key",
          // Mark apex as non-updatable for now, this might be revisited going forward.
          updatable: false,
          // Service bundle package is installed into /product partition.
          product_specific: true,
      }
      
  2. 如要在 SDV 映像檔中加入新的 makefile,請將新的 APEX 模組新增至產品 makefile 中的 PRODUCT_PACKAGES。舉例來說,請參閱 sdv_samples_core_services.mk

  3. 如果您使用 Cuttlefish,請執行下列指令來啟動裝置:

    sdv-cf create --instance_name=instance1
    
  4. 在系統啟動時執行服務套件:

    # Grant root access.
    adb root
    # Launch the new service bundle.
    adb shell sdv_service_bundle start \
      local-vm:com.sdv.oem.apex_and_module_name.ServiceBundleName/instance-1
    

服務套裝組合依附元件管理

在某些情況下,您可以靜態連結服務套件依附元件,藉此縮減 APEX 大小和服務套件記憶體用量,並縮短服務套件的啟動時間。這些情況包括具有下列特性的 APEX:

  • 單一服務套裝組合
  • 多個服務套件,但共用的常見依附元件不多

如要啟用靜態連結,請將下列屬性新增至服務套件程式庫定義:

// Service bundle library.
rust_ffi_shared {
  // See rust_ffi_shared basic template.
  ...
  // uses static linking for the dependencies
  prefer_rlib: true,
  // needed to correctly resolve commstack deps
  ld_flags: ["-Wl,--no-as-needed"],
}

在每種情況下,建議您確認靜態連結至依附元件是否能改善服務套件的記憶體用量和啟動時間。

偵錯 (dumpsys)

生命週期管理工具會實作 dumpsys 介面。這個介面會向使用者顯示處於 createdstarted 狀態的服務套件清單,也會顯示服務套件程序的 FQIN 或 UID。

如要查看服務套裝組合的目前狀態和 ID,請執行下列指令:

# Grant root access.
adb root

# Execute dumpsys to see service bundles state
adb shell dumpsys google.sdv.lifecycle.ILifecycleManager/default

後續步驟

如要自動執行 vsidlc,並讓 IDE 外掛程式處理依附元件,請參閱「自動更新目錄和整合 LSP」。