אתה יכול להשתמש בפורמט הקובץ 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 של ספקים, ועוד מתווספים.
דוגמאות:
- XML הצהרת תכונות
- חיישנים כוללים XMLs כמובנים מראש ב-APEX של ספק HAL חיישנים
- קלט קבצי תצורה
- מסך מגע מוגדר כמובנה מראש ב-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 של ספקים, ועוד מתווספים.
דוגמאות:
- XML הצהרת תכונות
- חיישנים כוללים XMLs כמובנים מראש ב-APEX של ספק HAL חיישנים
- קלט קבצי תצורה
- מסך מגע מוגדר כמובנה מראש ב-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 של ספקים, ועוד מתווספים.
דוגמאות:
- XML הצהרת תכונות
- חיישנים כוללים XMLs כמובנים מראש ב-APEX של ספק HAL חיישנים
- קלט קבצי תצורה
- מסך מגע מוגדר כמובנה מראש ב-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";