הספק APEX

אתה יכול להשתמש בפורמט הקובץ APEX כדי לארוז ולהתקין מודולי מערכת הפעלה אנדרואיד ברמה נמוכה יותר. זה מאפשר בנייה והתקנה עצמאית של רכיבים כמו שירותים וספריות מקוריות, יישומי HAL, קושחה, קבצי תצורה וכו'.

APEX של ספקים מותקנים על ידי מערכת ה-build באופן אוטומטי במחיצת /vendor ומופעלים בזמן ריצה על ידי apexd בדיוק כמו APEXs במחיצות אחרות.

מקרי שימוש

מודולריזציה של תמונות ספקים

APEXs מאפשרים צרור טבעי ומודולריזציה של הטמעות תכונות בתמונות של ספקים.

כאשר תמונות ספק בנויות כשילוב של APEX של ספקים שנבנו באופן עצמאי, יצרני מכשירים יכולים לבחור בקלות את ההטמעות הספציפיות של ספקים הרצויות במכשיר שלהם. יצרנים יכולים אפילו ליצור ספק חדש APEX אם אף אחד מה-APEXs המסופקים לא מתאים לצרכיהם, או שיש להם חומרה מותאמת אישית חדשה לגמרי.

לדוגמה, יצרן OEM יכול לבחור להרכיב את המכשיר שלו עם יישום AOSP wifi APEX, יישום ה-SoC Bluetooth APEX ויישום טלפוניה OEM מותאם אישית APEX.

ללא APEXs של ספקים, יישום עם כל כך הרבה תלות בין רכיבי הספק דורש תיאום ומעקב זהירים. על ידי עטיפת כל הרכיבים (כולל קבצי תצורה וספריות נוספות) ב-APEXs עם ממשקים מוגדרים בבירור בכל נקודה של תקשורת בין תכונות, הרכיבים השונים הופכים להחלפה.

איטרציה של מפתחים

APEXs של ספקים עוזרים למפתחים לבצע איטרציה מהירה יותר תוך פיתוח מודולי ספקים על ידי שילוב של יישום תכונות שלם, כמו wifi HAL, בתוך ספק APEX. מפתחים יכולים אז לבנות ולדחוף את הספק APEX בנפרד כדי לבדוק שינויים, במקום לבנות מחדש את כל תמונת הספק.

זה מפשט ומזרז את מחזור האיטרציה של מפתחים עבור מפתחים שעובדים בעיקר באזור תכונה אחד ורוצים לחזור על אזור תכונה זה בלבד.

הצרור הטבעי של אזור תכונה לתוך APEX מפשט גם את תהליך הבנייה, הדחיפה ובדיקת השינויים עבור אותו אזור תכונה. לדוגמה, התקנה מחדש של APEX מעדכנת אוטומטית כל ספרייה או קבצי תצורה מצורפים שה-APEX כולל.

אגירה של אזור תכונה לתוך APEX מפשטת גם איתור באגים או החזרה כאשר נצפית התנהגות רעה של המכשיר. לדוגמה, אם הטלפוניה פועלת בצורה גרועה במבנה חדש, מפתחים יכולים לנסות להתקין יישום טלפוניה ישן יותר APEX במכשיר (ללא צורך להבהב בנייה מלאה) ולראות אם התנהגות טובה משוחזרת.

זרימת עבודה לדוגמה:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

דוגמאות

יסודות

ראה את הדף הראשי של פורמט קובץ APEX למידע כללי על APEX, כולל דרישות המכשיר, פרטי פורמט הקובץ ושלבי ההתקנה.

ב- Android.bp , הגדרת vendor: true הופך את מודול APEX ל-APEX של הספק.

apex {
  ..
  vendor: true,
  ..
}

בינאריים וספריות משותפות

APEX כולל תלות טרנזיטיבית בתוך מטען APEX אלא אם כן יש להם ממשקים יציבים.

ממשקים מקוריים יציבים עבור תלות ב-APEX של ספק כוללים cc_library עם stubs , ndk_library או llndk_library . תלות אלו אינן נכללות באריזה, והתלות נרשמות במניפסט APEX. המניפסט מעובד על ידי linkerconfig כך שהתלות המקורית החיצונית זמינה בזמן ריצה.

שלא כמו APEXs במחיצת /system , APEXs של הספק קשורים בדרך כלל לגרסת VNDK ספציפית. ספריות VNDK מבטיחות יציבות ABI בתוך המהדורה, כך שנוכל להתייחס לספריות VNDK כיציבות ולהקטין את גודלן של APEXs של ספקים על ידי אי הכללתן מה-APEXes באמצעות המאפיין use_vndk_as_stable .

בקטע שלמטה, ה-APEX יכיל גם את הבינארי ( my_service ) וגם את התלות הלא יציבה שלו ( *.so files). הוא לא יכיל ספריות VNDK, אפילו כאשר my_service בנוי עם ספריות VNDK כמו libbase . במקום זאת, בזמן ריצה my_service ישתמש libbase מספריות VNDK המסופקות על ידי המערכת.

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

בקטע שלמטה, ה-APEX יכיל את הספרייה המשותפת my_standalone_lib וכל אחת מהתלות הלא יציבה שלה (כמתואר לעיל).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

יישומי HAL

כדי להגדיר מימוש HAL, ספק את הבינאריות והספריות המתאימות בתוך APEX של ספק בדומה לדוגמאות הבאות:

כדי להקיף באופן מלא את יישום ה-HAL, ה-APEX צריך לציין גם את כל קטעי ה-VINTF הרלוונטיים ותסריטי ה-Init.

שברי VINTF

ניתן להגיש קטעי VINTF מספק APEX כאשר קטעים נמצאים ב- etc/vintf של APEX.

השתמש במאפיין prebuilts כדי להטמיע את קטעי VINTF ב-APEX.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

אינט סקריפטים

APEXs יכולים לכלול סקריפטים של init בשתי דרכים: (א) קובץ טקסט שנבנה מראש בתוך מטען APEX, או (ב) סקריפט init רגיל ב- /vendor/etc . אתה יכול להגדיר את שניהם עבור אותו APEX.

פתח סקריפט ב-APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

סקריפטים של Init בתוך APEXs יכולים להכיל רק הגדרות service . סקריפטים של Init ב-APEX של ספקים יכולים להיות גם on <property> .

היזהר בעת שימוש on . מכיוון שסקריפטים של init ב-APEX מעובדים ומבוצעים לאחר הפעלת APEX, לא ניתן להשתמש בחלק מהאירועים או המאפיינים. השתמש apex.all.ready=true כדי לפטר פעולות מוקדם ככל האפשר.

קושחה

דוגמא:

הטמע קושחה ב-APEX של ספק עם סוג מודול prebuilt_firmware , כדלקמן.

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

מודולי prebuilt_firmware מותקנים בספריית <apex name>/etc/firmware של ה-APEX. ueventd סורק ספריות /apex/*/etc/firmware כדי למצוא מודולי קושחה.

file_contexts של ה-APEX צריך לתייג כל ערכי מטען קושחה כראוי כדי להבטיח שהקבצים האלה נגישים על ידי ueventd בזמן ריצה; בדרך כלל, התווית vendor_file מספיקה. לדוגמה:

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

מודולי ליבה

הטמע מודולי ליבה ב-APEX של ספק כמודולים מובנים מראש, כדלקמן.

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

ה- file_contexts של ה-APEX אמור לתייג כל ערכי מטען של מודול ליבה כראוי. לדוגמה:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

יש להתקין מודולי ליבה במפורש. סקריפט init לדוגמה הבא במחיצת הספק מציג התקנה באמצעות insmod :

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

שכבות-על של משאבי זמן ריצה

דוגמא:

הטמעת שכבות-על של משאבי זמן ריצה ב-APEX של ספק באמצעות המאפיין rros .

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

קבצי תצורה אחרים

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

דוגמאות:

תכונות פיתוח נוספות

בחירת APEX בעת האתחול

דוגמא:

מפתחים יכולים גם להתקין גרסאות מרובות של ספקי APEX שחולקים את אותו שם ומפתח APEX, ולאחר מכן לבחור איזו גרסה תופעל במהלך כל אתחול באמצעות sysprops מתמיד. במקרים מסוימים של שימוש במפתחים, זה עשוי להיות פשוט יותר מאשר התקנת עותק חדש של ה-APEX באמצעות adb install .

מקרי שימוש לדוגמה:

  • התקן 3 גרסאות של ספק ה-WiFi HAL APEX: צוותי QA יכולים להריץ בדיקות ידניות או אוטומטיות באמצעות גרסה אחת, ואז לאתחל מחדש לגרסה אחרת ולהריץ מחדש את הבדיקות, ואז להשוות את התוצאות הסופיות.
  • התקן 2 גרסאות של המצלמה HAL ספק APEX, עדכנית וניסיונית : דוג-פודרס יכולים להשתמש בגרסה הניסיונית מבלי להוריד ולהתקין קובץ נוסף, כך שהם יכולים להחליף בקלות בחזרה.

במהלך האתחול, apexd מחפשת sysprops בעקבות פורמט ספציפי כדי להפעיל את גרסת APEX הנכונה.

הפורמטים הצפויים עבור מפתח המאפיין הם:

  • Bootconfig
    • משמש להגדרת ערך ברירת המחדל, ב- BoardConfig.mk .
    • androidboot.vendor.apex.<apex name>
  • סיספרופ מתמשך
    • משמש לשינוי ערך ברירת המחדל, המוגדר במכשיר שכבר אתחול.
    • עוקף את ערך bootconfig אם קיים.
    • persist.vendor.apex.<apex name>

הערך של המאפיין צריך להיות שם הקובץ של ה-APEX שאמור להיות מופעל.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

יש להגדיר את גרסת ברירת המחדל גם באמצעות bootconfig ב- BoardConfig.mk :

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

לאחר אתחול המכשיר, שנה את הגרסה המופעלת על ידי הגדרת ה-sysprop המתמיד:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

אם ההתקן תומך בעדכון bootconfig לאחר מהבהב (כגון באמצעות פקודות fastboot oem ), שינוי המאפיין bootconfig עבור ה-APEX המותקן מרובה משנה גם את הגרסה שהופעלה בעת האתחול.

עבור התקני התייחסות וירטואליים המבוססים על Cuttlefish , אתה יכול להשתמש בפקודה --extra_bootconfig_args כדי להגדיר את המאפיין bootconfig ישירות בזמן ההשקה. לדוגמה:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";
,

אתה יכול להשתמש בפורמט הקובץ APEX כדי לארוז ולהתקין מודולי מערכת הפעלה אנדרואיד ברמה נמוכה יותר. זה מאפשר בנייה והתקנה עצמאית של רכיבים כמו שירותים וספריות מקוריות, יישומי HAL, קושחה, קבצי תצורה וכו'.

APEX של ספקים מותקנים על ידי מערכת ה-build באופן אוטומטי במחיצת /vendor ומופעלים בזמן ריצה על ידי apexd בדיוק כמו APEXs במחיצות אחרות.

מקרי שימוש

מודולריזציה של תמונות ספקים

APEXs מאפשרים צרור טבעי ומודולריזציה של הטמעות תכונות בתמונות של ספקים.

כאשר תמונות ספק בנויות כשילוב של APEX של ספקים שנבנו באופן עצמאי, יצרני מכשירים יכולים לבחור בקלות את ההטמעות הספציפיות של ספקים הרצויות במכשיר שלהם. יצרנים יכולים אפילו ליצור ספק חדש APEX אם אף אחד מה-APEXs המסופקים לא מתאים לצרכיהם, או שיש להם חומרה מותאמת אישית חדשה לגמרי.

לדוגמה, יצרן OEM יכול לבחור להרכיב את המכשיר שלו עם יישום AOSP wifi APEX, יישום ה-SoC Bluetooth APEX ויישום טלפוניה OEM מותאם אישית APEX.

ללא APEXs של ספקים, יישום עם כל כך הרבה תלות בין רכיבי הספק דורש תיאום ומעקב זהירים. על ידי עטיפת כל הרכיבים (כולל קבצי תצורה וספריות נוספות) ב-APEXs עם ממשקים מוגדרים בבירור בכל נקודה של תקשורת בין תכונות, הרכיבים השונים הופכים להחלפה.

איטרציה של מפתחים

APEXs של ספקים עוזרים למפתחים לבצע איטרציה מהירה יותר תוך פיתוח מודולי ספקים על ידי שילוב של יישום תכונות שלם, כמו wifi HAL, בתוך ספק APEX. מפתחים יכולים אז לבנות ולדחוף את הספק APEX בנפרד כדי לבדוק שינויים, במקום לבנות מחדש את כל תמונת הספק.

זה מפשט ומזרז את מחזור האיטרציה של מפתחים עבור מפתחים שעובדים בעיקר באזור תכונה אחד ורוצים לחזור על אזור תכונה זה בלבד.

הצרור הטבעי של אזור תכונה לתוך APEX מפשט גם את תהליך הבנייה, הדחיפה ובדיקת השינויים עבור אותו אזור תכונה. לדוגמה, התקנה מחדש של APEX מעדכנת אוטומטית כל ספרייה או קבצי תצורה מצורפים שה-APEX כולל.

אגירה של אזור תכונה לתוך APEX מפשטת גם איתור באגים או החזרה כאשר נצפית התנהגות רעה של המכשיר. לדוגמה, אם הטלפוניה פועלת בצורה גרועה במבנה חדש, מפתחים יכולים לנסות להתקין יישום טלפוניה ישן יותר APEX במכשיר (ללא צורך להבהב בנייה מלאה) ולראות אם התנהגות טובה משוחזרת.

זרימת עבודה לדוגמה:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

דוגמאות

יסודות

ראה את הדף הראשי של פורמט קובץ APEX למידע כללי על APEX, כולל דרישות המכשיר, פרטי פורמט הקובץ ושלבי ההתקנה.

ב- Android.bp , הגדרת vendor: true הופך את מודול APEX ל-APEX של הספק.

apex {
  ..
  vendor: true,
  ..
}

בינאריים וספריות משותפות

APEX כולל תלות טרנזיטיבית בתוך מטען APEX אלא אם כן יש להם ממשקים יציבים.

ממשקים מקוריים יציבים עבור תלות ב-APEX של ספק כוללים cc_library עם stubs , ndk_library או llndk_library . תלות אלו אינן נכללות באריזה, והתלות נרשמות במניפסט APEX. המניפסט מעובד על ידי linkerconfig כך שהתלות המקורית החיצונית זמינה בזמן ריצה.

שלא כמו APEXs במחיצת /system , APEXs של הספק קשורים בדרך כלל לגרסת VNDK ספציפית. ספריות VNDK מבטיחות יציבות ABI בתוך המהדורה, כך שנוכל להתייחס לספריות VNDK כיציבות ולהקטין את גודלן של APEXs של ספקים על ידי אי הכללתן מה-APEXes באמצעות המאפיין use_vndk_as_stable .

בקטע שלמטה, ה-APEX יכיל גם את הבינארי ( my_service ) וגם את התלות הלא יציבה שלו ( *.so files). הוא לא יכיל ספריות VNDK, אפילו כאשר my_service בנוי עם ספריות VNDK כמו libbase . במקום זאת, בזמן ריצה my_service ישתמש libbase מספריות VNDK המסופקות על ידי המערכת.

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

בקטע שלמטה, ה-APEX יכיל את הספרייה המשותפת my_standalone_lib וכל אחת מהתלות הלא יציבה שלה (כמתואר לעיל).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

יישומי HAL

כדי להגדיר מימוש HAL, ספק את הבינאריות והספריות המתאימות בתוך APEX של ספק בדומה לדוגמאות הבאות:

כדי להקיף באופן מלא את יישום ה-HAL, ה-APEX צריך לציין גם את כל קטעי ה-VINTF הרלוונטיים ותסריטי ה-Init.

שברי VINTF

ניתן להגיש קטעי VINTF מספק APEX כאשר קטעים נמצאים ב- etc/vintf של APEX.

השתמש במאפיין prebuilts כדי להטמיע את קטעי VINTF ב-APEX.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

אינט סקריפטים

APEXs יכולים לכלול סקריפטים של init בשתי דרכים: (א) קובץ טקסט שנבנה מראש בתוך מטען APEX, או (ב) סקריפט init רגיל ב- /vendor/etc . אתה יכול להגדיר את שניהם עבור אותו APEX.

פתח סקריפט ב-APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

סקריפטים של Init בתוך APEXs יכולים להכיל רק הגדרות service . סקריפטים של Init ב-APEX של ספקים יכולים להיות גם on <property> .

היזהר בעת שימוש on . מכיוון שסקריפטים של init ב-APEX מעובדים ומבוצעים לאחר הפעלת APEX, לא ניתן להשתמש בחלק מהאירועים או המאפיינים. השתמש apex.all.ready=true כדי לפטר פעולות מוקדם ככל האפשר.

קושחה

דוגמא:

הטמע קושחה ב-APEX של ספק עם סוג מודול prebuilt_firmware , כדלקמן.

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

מודולי prebuilt_firmware מותקנים בספריית <apex name>/etc/firmware של ה-APEX. ueventd סורק ספריות /apex/*/etc/firmware כדי למצוא מודולי קושחה.

file_contexts של ה-APEX צריך לתייג כל ערכי מטען קושחה כראוי כדי להבטיח שהקבצים האלה נגישים על ידי ueventd בזמן ריצה; בדרך כלל, התווית vendor_file מספיקה. לדוגמה:

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

מודולי ליבה

הטמע מודולי ליבה ב-APEX של ספק כמודולים מובנים מראש, כדלקמן.

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

ה- file_contexts של ה-APEX אמור לתייג כל ערכי מטען של מודול ליבה כראוי. לדוגמה:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

יש להתקין מודולי ליבה במפורש. סקריפט init לדוגמה הבא במחיצת הספק מציג התקנה באמצעות insmod :

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

שכבות-על של משאבי זמן ריצה

דוגמא:

הטמעת שכבות-על של משאבי זמן ריצה ב-APEX של ספק באמצעות המאפיין rros .

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

קבצי תצורה אחרים

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

דוגמאות:

תכונות פיתוח נוספות

בחירת APEX בעת האתחול

דוגמא:

מפתחים יכולים גם להתקין גרסאות מרובות של ספקי APEX שחולקים את אותו שם ומפתח APEX, ולאחר מכן לבחור איזו גרסה תופעל במהלך כל אתחול באמצעות sysprops מתמיד. במקרים מסוימים של שימוש במפתחים, זה עשוי להיות פשוט יותר מאשר התקנת עותק חדש של ה-APEX באמצעות adb install .

מקרי שימוש לדוגמה:

  • התקן 3 גרסאות של ספק ה-WiFi HAL APEX: צוותי QA יכולים להריץ בדיקות ידניות או אוטומטיות באמצעות גרסה אחת, ואז לאתחל מחדש לגרסה אחרת ולהריץ מחדש את הבדיקות, ואז להשוות את התוצאות הסופיות.
  • התקן 2 גרסאות של המצלמה HAL ספק APEX, עדכנית וניסיונית : דוג-פודרס יכולים להשתמש בגרסה הניסיונית מבלי להוריד ולהתקין קובץ נוסף, כך שהם יכולים להחליף בקלות בחזרה.

במהלך האתחול, apexd מחפשת sysprops בעקבות פורמט ספציפי כדי להפעיל את גרסת APEX הנכונה.

הפורמטים הצפויים עבור מפתח המאפיין הם:

  • Bootconfig
    • משמש להגדרת ערך ברירת המחדל, ב- BoardConfig.mk .
    • androidboot.vendor.apex.<apex name>
  • סיספרופ מתמשך
    • משמש לשינוי ערך ברירת המחדל, המוגדר במכשיר שכבר אתחול.
    • עוקף את ערך bootconfig אם קיים.
    • persist.vendor.apex.<apex name>

הערך של המאפיין צריך להיות שם הקובץ של ה-APEX שאמור להיות מופעל.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

יש להגדיר את גרסת ברירת המחדל גם באמצעות bootconfig ב- BoardConfig.mk :

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

לאחר אתחול המכשיר, שנה את הגרסה המופעלת על ידי הגדרת ה-sysprop המתמיד:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

אם ההתקן תומך בעדכון bootconfig לאחר מהבהב (כגון באמצעות פקודות fastboot oem ), שינוי המאפיין bootconfig עבור ה-APEX המותקן מרובה משנה גם את הגרסה שהופעלה בעת האתחול.

עבור התקני התייחסות וירטואליים המבוססים על Cuttlefish , אתה יכול להשתמש בפקודה --extra_bootconfig_args כדי להגדיר את המאפיין bootconfig ישירות בזמן ההשקה. לדוגמה:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";
,

אתה יכול להשתמש בפורמט הקובץ APEX כדי לארוז ולהתקין מודולי מערכת הפעלה אנדרואיד ברמה נמוכה יותר. זה מאפשר בנייה והתקנה עצמאית של רכיבים כמו שירותים וספריות מקוריות, יישומי HAL, קושחה, קבצי תצורה וכו'.

APEX של ספקים מותקנים על ידי מערכת ה-build באופן אוטומטי במחיצת /vendor ומופעלים בזמן ריצה על ידי apexd בדיוק כמו APEXs במחיצות אחרות.

מקרי שימוש

מודולריזציה של תמונות ספקים

APEXs מאפשרים צרור טבעי ומודולריזציה של הטמעות תכונות בתמונות של ספקים.

כאשר תמונות ספק בנויות כשילוב של APEX של ספקים שנבנו באופן עצמאי, יצרני מכשירים יכולים לבחור בקלות את ההטמעות הספציפיות של ספקים הרצויות במכשיר שלהם. יצרנים יכולים אפילו ליצור ספק חדש APEX אם אף אחד מה-APEXs המסופקים לא מתאים לצרכיהם, או שיש להם חומרה מותאמת אישית חדשה לגמרי.

לדוגמה, יצרן OEM יכול לבחור להרכיב את המכשיר שלו עם יישום AOSP wifi APEX, יישום ה-SoC Bluetooth APEX ויישום טלפוניה OEM מותאם אישית APEX.

ללא APEXs של ספקים, יישום עם כל כך הרבה תלות בין רכיבי הספק דורש תיאום ומעקב זהירים. על ידי עטיפת כל הרכיבים (כולל קבצי תצורה וספריות נוספות) ב-APEXs עם ממשקים מוגדרים בבירור בכל נקודה של תקשורת בין תכונות, הרכיבים השונים הופכים להחלפה.

איטרציה של מפתחים

APEXs של ספקים עוזרים למפתחים לבצע איטרציה מהירה יותר תוך פיתוח מודולי ספקים על ידי שילוב של יישום תכונות שלם, כמו wifi HAL, בתוך ספק APEX. מפתחים יכולים אז לבנות ולדחוף את הספק APEX בנפרד כדי לבדוק שינויים, במקום לבנות מחדש את כל תמונת הספק.

זה מפשט ומזרז את מחזור האיטרציה של מפתחים עבור מפתחים שעובדים בעיקר באזור תכונה אחד ורוצים לחזור על אזור תכונה זה בלבד.

הצרור הטבעי של אזור תכונה לתוך APEX מפשט גם את תהליך הבנייה, הדחיפה ובדיקת השינויים עבור אותו אזור תכונה. לדוגמה, התקנה מחדש של APEX מעדכנת אוטומטית כל ספרייה או קבצי תצורה מצורפים שה-APEX כולל.

אגירה של אזור תכונה לתוך APEX מפשטת גם איתור באגים או החזרה כאשר נצפית התנהגות רעה של המכשיר. לדוגמה, אם הטלפוניה פועלת בצורה גרועה במבנה חדש, מפתחים יכולים לנסות להתקין יישום טלפוניה ישן יותר APEX במכשיר (ללא צורך להבהב בנייה מלאה) ולראות אם התנהגות טובה משוחזרת.

זרימת עבודה לדוגמה:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

דוגמאות

יסודות

ראה את הדף הראשי של פורמט קובץ APEX למידע כללי על APEX, כולל דרישות המכשיר, פרטי פורמט הקובץ ושלבי ההתקנה.

ב- Android.bp , הגדרת vendor: true הופך את מודול APEX ל-APEX של הספק.

apex {
  ..
  vendor: true,
  ..
}

בינאריים וספריות משותפות

APEX כולל תלות טרנזיטיבית בתוך מטען APEX אלא אם כן יש להם ממשקים יציבים.

ממשקים מקוריים יציבים עבור תלות ב-APEX של ספק כוללים cc_library עם stubs , ndk_library או llndk_library . תלות אלו אינן נכללות באריזה, והתלות נרשמות במניפסט APEX. המניפסט מעובד על ידי linkerconfig כך שהתלות המקורית החיצונית זמינה בזמן ריצה.

שלא כמו APEXs במחיצת /system , APEXs של הספק קשורים בדרך כלל לגרסת VNDK ספציפית. ספריות VNDK מבטיחות יציבות ABI בתוך המהדורה, כך שנוכל להתייחס לספריות VNDK כיציבות ולהקטין את גודלן של APEXs של ספקים על ידי אי הכללתן מה-APEXes באמצעות המאפיין use_vndk_as_stable .

בקטע שלמטה, ה-APEX יכיל גם את הבינארי ( my_service ) וגם את התלות הלא יציבה שלו ( *.so files). הוא לא יכיל ספריות VNDK, אפילו כאשר my_service בנוי עם ספריות VNDK כמו libbase . במקום זאת, בזמן ריצה my_service ישתמש libbase מספריות VNDK המסופקות על ידי המערכת.

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

בקטע שלמטה, ה-APEX יכיל את הספרייה המשותפת my_standalone_lib וכל אחת מהתלות הלא יציבה שלה (כמתואר לעיל).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

יישומי HAL

כדי להגדיר מימוש HAL, ספק את הבינאריות והספריות המתאימות בתוך APEX של ספק בדומה לדוגמאות הבאות:

כדי להקיף באופן מלא את יישום ה-HAL, ה-APEX צריך לציין גם את כל קטעי ה-VINTF הרלוונטיים ותסריטי ה-Init.

שברי VINTF

ניתן להגיש קטעי VINTF מספק APEX כאשר קטעים נמצאים ב- etc/vintf של APEX.

השתמש במאפיין prebuilts כדי להטמיע את קטעי VINTF ב-APEX.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

אינט סקריפטים

APEXs יכולים לכלול סקריפטים של init בשתי דרכים: (א) קובץ טקסט שנבנה מראש בתוך מטען APEX, או (ב) סקריפט init רגיל ב- /vendor/etc . אתה יכול להגדיר את שניהם עבור אותו APEX.

פתח סקריפט ב-APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

סקריפטים של Init בתוך APEXs יכולים להכיל רק הגדרות service . סקריפטים של Init ב-APEX של ספקים יכולים להיות גם on <property> .

היזהר בעת שימוש on . מכיוון שסקריפטים של init ב-APEX מעובדים ומבוצעים לאחר הפעלת APEX, לא ניתן להשתמש בחלק מהאירועים או המאפיינים. השתמש apex.all.ready=true כדי לפטר פעולות מוקדם ככל האפשר.

קושחה

דוגמא:

הטמע קושחה ב-APEX של ספק עם סוג מודול prebuilt_firmware , כדלקמן.

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

מודולי prebuilt_firmware מותקנים בספריית <apex name>/etc/firmware של ה-APEX. ueventd סורק ספריות /apex/*/etc/firmware כדי למצוא מודולי קושחה.

file_contexts של ה-APEX צריך לתייג כל ערכי מטען קושחה כראוי כדי להבטיח שהקבצים האלה נגישים על ידי ueventd בזמן ריצה; בדרך כלל, התווית vendor_file מספיקה. לדוגמה:

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

מודולי ליבה

הטמע מודולי ליבה ב-APEX של ספק כמודולים מובנים מראש, כדלקמן.

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

ה- file_contexts של ה-APEX אמור לתייג כל ערכי מטען של מודול ליבה כראוי. לדוגמה:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

יש להתקין מודולי ליבה במפורש. סקריפט init לדוגמה הבא במחיצת הספק מציג התקנה באמצעות insmod :

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

שכבות-על של משאבי זמן ריצה

דוגמא:

הטמעת שכבות-על של משאבי זמן ריצה ב-APEX של ספק באמצעות המאפיין rros .

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

קבצי תצורה אחרים

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

דוגמאות:

תכונות פיתוח נוספות

בחירת APEX בעת האתחול

דוגמא:

מפתחים יכולים גם להתקין גרסאות מרובות של ספקי APEX שחולקים את אותו שם ומפתח APEX, ולאחר מכן לבחור איזו גרסה תופעל במהלך כל אתחול באמצעות sysprops מתמיד. במקרים מסוימים של שימוש במפתחים, זה עשוי להיות פשוט יותר מאשר התקנת עותק חדש של ה-APEX באמצעות adb install .

מקרי שימוש לדוגמה:

  • התקן 3 גרסאות של ספק ה-WiFi HAL APEX: צוותי QA יכולים להריץ בדיקות ידניות או אוטומטיות באמצעות גרסה אחת, ואז לאתחל מחדש לגרסה אחרת ולהריץ מחדש את הבדיקות, ואז להשוות את התוצאות הסופיות.
  • התקן 2 גרסאות של המצלמה HAL ספק APEX, עדכנית וניסיונית : דוג-פודרס יכולים להשתמש בגרסה הניסיונית מבלי להוריד ולהתקין קובץ נוסף, כך שהם יכולים להחליף בקלות בחזרה.

במהלך האתחול, apexd מחפשת sysprops בעקבות פורמט ספציפי כדי להפעיל את גרסת APEX הנכונה.

הפורמטים הצפויים עבור מפתח המאפיין הם:

  • Bootconfig
    • משמש להגדרת ערך ברירת המחדל, ב- BoardConfig.mk .
    • androidboot.vendor.apex.<apex name>
  • סיספרופ מתמשך
    • משמש לשינוי ערך ברירת המחדל, המוגדר במכשיר שכבר אתחול.
    • עוקף את ערך bootconfig אם קיים.
    • persist.vendor.apex.<apex name>

הערך של המאפיין צריך להיות שם הקובץ של ה-APEX שאמור להיות מופעל.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

יש להגדיר את גרסת ברירת המחדל גם באמצעות bootconfig ב- BoardConfig.mk :

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

לאחר אתחול המכשיר, שנה את הגרסה המופעלת על ידי הגדרת ה-sysprop המתמיד:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

אם ההתקן תומך בעדכון bootconfig לאחר מהבהב (כגון באמצעות פקודות fastboot oem ), שינוי המאפיין bootconfig עבור ה-APEX המותקן מרובה משנה גם את הגרסה שהופעלה בעת האתחול.

עבור התקני התייחסות וירטואליים המבוססים על Cuttlefish , אתה יכול להשתמש בפקודה --extra_bootconfig_args כדי להגדיר את המאפיין bootconfig ישירות בזמן ההשקה. לדוגמה:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";