פיתוח ופריסה של חבילות שירות

אחרי שיוצרים את תוכנת הביניים וכותבים את הקוד המותאם אישית, אפשר לפרוס את חבילות השירות כקובצי APEX.

  1. יוצרים קובצי תצורה של SDV:

    חלודה

    1. מריצים את הפקודה הבאה כדי ליצור קובצי תצורה של SDV:

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

      כשמריצים את vsidlc עם הדגל --apex, כל קובצי התצורה הנדרשים נוצרים באופן אוטומטי, כולל:

      • קובץ מניפסט של APEX (apex_manifest.json)
      • מניפסט של מטא-נתונים של SDV ‏ (sdv_service_bundles_manifest.textproto)
      • הגדרת הכלי Linker (linker.config.json)
      • הקשרים של קובצי SELinux (file_contexts)
      • מפתחות ציבוריים ופרטיים (.avbpubkey ו-.pem)
      • הצהרות לגבי הרשאות והגדרות תזמור
      • קובץ Android.bp שמגדיר את כל מודולי Soong הנדרשים.

      אפשר למצוא את ההגדרות שנוצרו בקטע:

      /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,‏ linker.config.json:

      { "visible": true }
      
    3. יוצרים קובץ חדש עם השדות הבאים:apex_manifest.json

      • שם חבילה ייחודי של SDV
      • גרסת ה-APEX
      • תלות בספריות התקשורת של SDV
      {
        "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. יוצרים מודול APEX חדש בקובץ Android.bp חדש או קיים. משתמשים בשם החבילה של ה-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. כדי לכלול את קובץ ה-Makefile החדש בתמונת SDV, מוסיפים את מודול ה-APEX החדש אל PRODUCT_PACKAGES בקובץ ה-Makefile של המוצר. לדוגמה, אפשר לעיין ב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. בממשק הזה מוצגת למשתמש רשימה של חבילות שירותים שנמצאות במצב created או started. בממשק מוצג גם ה-FQIN או ה-UID של תהליך חבילת השירות.

כדי לראות את המצב הנוכחי ואת המזהים של חבילות השירותים, מריצים את הפקודה:

# Grant root access.
adb root

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

המאמרים הבאים

כדי להריץ את vsidlc באופן אוטומטי ולאפשר לתוסף IDE לעבוד עם תלות, אפשר לעיין במאמר עדכונים אוטומטיים של קטלוג ושילוב של LSP.