אפשר להשתמש בפורמט הקובץ APEX כדי לארוז ו להתקין מודולים של Android OS ברמה נמוכה יותר. היא מאפשרת לבנות באופן עצמאי רכיבים כמו ספריות ושירותים מקוריים, HAL יישומים, קושחה, קובצי תצורה וכו'.
שרתי APEX של הספק מותקנים באופן אוטומטי על ידי מערכת ה-build ב-/vendor
ולהפעיל את המחיצה בזמן הריצה על ידי apexd
, בדיוק כמו במודלים אחרים של APEX
מחיצות.
תרחישים לדוגמה
מודולריזציה של תמונות ספקים
APEX מאפשר קיבוץ טבעי ומודולריזציה של תכונות בתמונות של ספקים.
כאשר תמונות של ספקים נוצרות כשילוב של ספק שנוצר באופן עצמאי APEX, יצרני המכשירים יכולים לבחור בקלות של ספקים שרוצים לבצע במכשיר שלהם. יצרנים יכולים גם ליצור APEX חדש של ספק אם אף אחד מה-APEX שסופקו לא מתאים לצרכים שלהם, או אם יש להם חומרה מותאמת אישית חדשה לגמרי.
לדוגמה, יכול להיות שיצרן הציוד המקורי יבחר לחבר את המכשיר שלו לרשת ה-Wi-Fi של AOSP APEX, הטמעת Bluetooth של SoC APEX ויצרן ציוד מקורי בהתאמה אישית שימוש בטכנולוגיית טלפוניה APEX.
ללא APEX של ספקים, הטמעה עם כל כך הרבה יחסי תלות בין מרכיבי הספק דורשים תיאום ומעקב קפדניים. על ידי גלישת טקסט (כולל קובצי תצורה וספריות נוספות) ב-APEX עם בממשקים מוגדרים בבירור בכל שלב של תקשורת בין תכונות, ורכיבים שונים יכולים להיות ניתנים להחלפה.
חזרה על תהליך הפיתוח
ספקי APEX של ספקים עוזרים למפתחים לבצע איטרציה מהר יותר תוך כדי פיתוח מודולים של ספקים קיבוץ כל של הטמעת התכונה, כמו Wi-Fi HAL, בתוך ספק APEX. לאחר מכן המפתחים יכולים ליצור ולדחוף כל אחד בנפרד את APEX של הספק לבדיקה במקום ליצור מחדש את כל התמונה של הספק.
כך מפתחים שעובדים בעיקר בתחום תכונות אחד ורוצים לבצע שינויים רק בתחום הזה יכולים לפשט ולהאיץ את מחזור החזרות שלהם.
הקיבוץ הטבעי של אזור פיצ'ר ל-APEX גם מפשט את התהליך של בנייה, דחיפה ובדיקה של שינויים בתחום התכונה הזו. לדוגמה, התקנה מחדש של APEX מעדכנת באופן אוטומטי את כל קובצי ההגדרות והספריות בחבילה ש-APEX כולל.
הקיפול של אזור תכונות ל-Apex גם מפשט את ניפוי הבאגים או החזרה למצב הקודם כשמתגלה התנהגות לא תקינה במכשיר. לדוגמה, אם פעילות הטלפוניה לא תקינה או גרסת build חדשה, ואז המפתחים יכולים לנסות להתקין מערכת טלפוניה ישנה יותר. להטמיע APEX במכשיר (ללא צורך ב-Flash מלא) כדי לבדוק אם זוהתה התנהגות טובה.
תהליך עבודה לדוגמה:
# 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
ואת הספריות LLNDK. יחסי התלות האלה מוחרגים
האריזה ויחסי התלות מתועדים במניפסט של APEX. המניפסט הוא
מעובד על ידי linkerconfig
כך שיחסי התלות במקור חיצוני
בזמן הריצה.
בקטע הקוד הבא, ה-APEX מכיל גם את הקובץ הבינארי (my_service
) וגם את יחסי התלות הלא יציבים שלו (קבצי *.so
).
apex {
..
vendor: true,
binaries: ["my_service"],
..
}
בקטע הקוד הבא, ה-APEX מכיל את הספרייה המשותפת my_standalone_lib
ואת כל יחסי התלות הלא יציבים שלה (כפי שמתואר למעלה).
apex {
..
vendor: true,
native_shared_libs: ["my_standalone_lib"],
..
}
הקטנה של APEX
קובץ ה-APEX עשוי לגדול כי הוא כולל יחד יחסי תלות לא יציבים. מומלץ להשתמש בקישור סטטי. אפשר לקשר באופן סטטי ספריות נפוצות כמו libc++.so
ו-libbase.so
לקובצי ה-HAL הבינאריים. אפשרות נוספת היא ליצור יחסי תלות כדי לספק ממשק יציב. התלות לא תצורף ל-APEX.
הטמעות של HAL
כדי להגדיר הטמעת HAL, יש לספק את הקבצים הבינאריים והספריות המתאימים ב-APEX של ספק, בדומה לדוגמאות הבאות:
כדי לבצע הטמעה מלאה של HAL, ב-APEX צריך גם לציין מקטעי VINTF רלוונטיים ואתחול סקריפטים.
קטעי 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",
}
ממשקי API של שאילתות
כשמוסיפים מקטעי VINTF ל-APEX, צריך להשתמש בממשקי API של libbinder_ndk
כדי לקבל
של ממשקי HAL ושמות APEX.
AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default")
:true
אם מכונת HAL מוגדרת ב-APEX.AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...)
: הפונקציה מקבלת את השם ב-APEX שמגדיר את מכונה ה-HAL.AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...)
: משתמשים בה כדי לפתוח HAL של העברה.
סקריפטים של Init
קבצי APEX יכולים לכלול סקריפטים של init בשתי דרכים: (א) קובץ טקסט שנוצר מראש בתוך עומס העבודה של ה-APEX, או (ב) סקריפט init רגיל ב-/vendor/etc
. אפשר להגדיר את שתי ההגדרות
לאותו APEX.
סקריפט איפוס ב-APEX:
prebuilt_etc {
name: "myinit.rc",
src: "myinit.rc"
}
apex {
..
vendor: true,
prebuilts: ["myinit.rc"],
..
}
סקריפטים של Init ב-APEX של ספקים יכולים לכלול הגדרות service
והוראות on <property or event>
.
צריך לוודא שהגדרת service
מצביעה על קובץ בינארי באותו APEX.
לדוגמה, com.android.foo
APEX יכול להגדיר שירות בשם foo-service
.
on foo-service /apex/com.android.foo/bin/foo
...
חשוב להיזהר כשמשתמשים בהוראות on
. מאחר שסקריפטים של init ב-Apexes מנותחים ומבוצעים אחרי הפעלת ה-Apexes, אי אפשר להשתמש בחלק מהאירועים או מהמאפיינים. יש להשתמש ב-apex.all.ready=true
כדי לבצע פעולות מוקדם ככל האפשר.
Bootstrap APEX יכול להשתמש ב-on init
, אבל לא
on early-init
קושחה
דוגמה:
הטמעת קושחה ב-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 צריך להוסיף תוויות לרשומות של המטען הייעודי (payload) של הקושחה
כדי לוודא שהקבצים האלה נגישים ל-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
צריך להתקין מודולים של ליבה באופן מפורש. דוגמה לסקריפט ההתחלתי
במחיצת הספק מוצגת התקנה דרך 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 של ספקים תומכות בקובצי תצורה אחרים שאפשר למצוא בדרך כלל במחיצה של הספק כקובצי build מוכנים מראש בתוך סביבות APEX של ספקים, ואנחנו מוסיפים עוד.
דוגמאות:
- קובצי XML של הצהרת תכונות
- החיישנים מציגים קובצי XML בתור מובנה מראש בספק HAL של חיישן APEX
- קבצי תצורה להזנה
- מסך המגע מוגדר כ- מובנה מראש ב-APEX של ספק עם הגדרות אישיות
Bootstrap Vendor APEXes
חלק משירותי HAL כמו keymint
אמורים להיות זמינים לפני ש-APEX
הופעל. עדכוני ה-HAL האלה בדרך כלל מגדירים early_hal
בהגדרת השירות
init סקריפט. דוגמה נוספת היא המחלקה animation
, שמתחילה בדרך כלל לפני האירוע post-fs-data
. כששירות HAL מוקדם כזה ארוז ב-APEX של הספק, צריך ליצור את ה-apex "vendorBootstrap": true
במניפסט APEX שלו כדי שניתן יהיה להפעיל אותו מוקדם יותר. שימו לב שפריטי APEX של אתחול יכולים להיות
מופעלת רק מהמיקום שהוגדר מראש, כמו /vendor/apex
, ולא מהמיקום
/data/apex
.
מאפייני מערכת
אלה מאפייני המערכת שה-framework קורא כדי לתמוך בספק APEX:
input_device.config_file.apex=<apex name>
– כשהיא מוגדרת, החיפוש של קובצי התצורה של הקלט (*.idc
,*.kl
ו-*.kcm
) מתבצע בספרייה/etc/usr
של APEX.ro.vulkan.apex=<apex name>
– כשהיא מוגדרת, מנהל ההתקן של Vulkan נטען מ-APEX. מאחר שמנהלי HAL מוקדמים משתמשים ב-Vulkan driver, צריך ליצור את ה-APEX Bootstrap APEX ולהגדיר את מרחב השמות של ה-linker כך שיהיה גלוי.
הגדרת מאפייני המערכת בסקריפטים התחלתיים באמצעות setprop
הפקודה.
תכונות פיתוח נוספות
בחירת APEX בזמן האתחול
דוגמה:
המפתחים יכולים גם להתקין מספר גרסאות של APEX של ספקים שחולקים את
אותו שם ומפתח APEX, ואז בוחרים איזו גרסה תופעל
באמצעות מערכת syspros מתמידה. בתרחישי שימוש מסוימים למפתחים, האפשרות הזו עשויה להיות פשוטה יותר מאשר התקנה של עותק חדש של APEX באמצעות adb install
.
תרחישים לדוגמה:
- התקנה של 3 גרסאות של APEX של WiFi HAL vendor: צוותי בקרת איכות יכולים להריץ בדיקה ידנית או אוטומטית באמצעות גרסה אחת, ואז להפעיל מחדש גרסה אחרת ולהריץ מחדש את הבדיקות, ולאחר מכן להשוות בין התוצאות הסופיות.
- התקנה של 2 גרסאות של APEX של ספק ה-HAL של המצלמה, גרסה נוכחית וגרסה ניסיונית: משתמשים בתוכנית Dogfooding יכולים להשתמש בגרסה הניסיונית בלי להוריד ולהתקין קובץ נוסף, כך שהם יכולים לחזור לגרסה הקודמת בקלות.
במהלך האתחול, apexd
מחפש sysprops בפורמט ספציפי כדי להפעיל את גרסת APEX המתאימה.
הפורמטים הנדרשים למפתח המאפיין הם:
- Bootconfig
- משמש להגדרת ערך ברירת המחדל ב-
BoardConfig.mk
. androidboot.vendor.apex.<apex name>
- משמש להגדרת ערך ברירת המחדל ב-
- מערכת מתמידה (sysp)
- משמש לשינוי ערך ברירת המחדל, שמוגדר במכשיר שכבר הופעל.
- משנה את הערך של 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,
..
}
צריך להגדיר גם את גרסת ברירת המחדל באמצעותbooconfig
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";