סקירה כללית על Vendor Native Development Kit ‏ (VNDK)

ערכת הפיתוח המקומית לספק (VNDK) היא קבוצה של ספריות שמשמשות ספריות או קבצים בינאריים אחרים במחיצת הספק או המוצר, בזמן הריצה של dlopen.

הוצאה משימוש

‫Vendor NDK הוצג ב-Android 8.0 כדי לספק ממשקי API בין ה-framework לבין קוד הספק. ה-VNDK נמצא בשימוש כבר הרבה שנים, אבל יש לו כמה חסרונות:
  • אחסון
    • חבילת APEX אחת של VNDK כוללת את כל ספריות ה-VNDK, גם אם נעשה בהן שימוש מהמכשיר וגם אם לא.
    • ‫GSI מכיל כמה גרסאות של VNDK APEX כדי לתמוך בכמה גרסאות של תמונות ספקים.
  • אפשרות לקבל עדכונים
    • קשה לעדכן קובצי VNDK APEX בנפרד מעדכון הפלטפורמה.
    • תמונות של ספקים מתעדכנות לעיתים קרובות דרך האוויר (OTA), ולכן היתרונות של אריזת VNDK בתוך תמונת המערכת מצטמצמים.
בעקבות הבעיות האלה, החלטנו להוציא משימוש את VNDK החל מ-Android 15.

פרטים על הוצאה משימוש של VNDK

כל ספריות ה-VNDK נארזות ב-VNDK APEX ומוגדרות להתקנה בתמונת המערכת (-ext). עם הוצאת VNDK משימוש, ספריות VNDK קודמות מותקנות בתמונת הספק (או המוצר), כמו ספריות אחרות שזמינות לספק. התכונות האלה יוסרו יחד עם הוצאת VNDK משימוש:
  • ‫VNDK APEX ל-Android 15
  • מאפייני מערכת שמציינים את הגרסה של ה-VNDK של היעד מוסרים אם מחיצות הספק או המוצר נוצרות עבור Android 15:
    • ro.vndk.version
    • ro.product.vndk.version
  • האופטימיזציות של VNDK לא יהיו זמינות כי אין VNDK:
    • TARGET_VNDK_USING_CORE_VARIANT למכשירי Android Go
    • use_vndk_as_stable Vendor APEXes
  • תמונת מצב של הספק, שתלויה מאוד ב-VNDK

חריגים להוצאה משימוש

התכונות האלה לא ישתנו עם הוצאת ה-VNDK משימוש:
  • חבילות VNDK APEX עם VNDK גרסה 14 ומטה, שנדרשות לתמיכה בתמונות ספקים קיימות.
  • ‫LL-NDK לא נכלל ב-VNDK.

למה כדאי להשתמש ב-VNDK?

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

עדכונים של המסגרת בלבד כוללים את האתגרים הבאים:

  • תלות בין מודולים של מסגרת ומודולים של ספק. לפני Android 8.0, מודולים במחיצת הספק ובמחיצת המערכת יכלו לקשר זה לזה. עם זאת, יחסי תלות ממודולים של ספקים הטילו מגבלות לא רצויות על פיתוח מודולים של מסגרות.
  • תוספים לספריות AOSP. ב-Android, כל מכשירי Android צריכים לעבור את בדיקת CTS כשמחיצת המערכת מוחלפת בתמונת מערכת גנרית (GSI) רגילה. עם זאת, ספקים מרחיבים את ספריות ה-AOSP כדי לשפר את הביצועים או להוסיף פונקציות נוספות להטמעות ה-HIDL שלהם, ולכן יכול להיות שהפעלת ה-GSI הרגיל במחיצת המערכת תשבור את הטמעת ה-HIDL של הספק. הנחיות למניעת בעיות כאלה זמינות במאמר בנושא תוספי VNDK.

כדי להתמודד עם האתגרים האלה, מערכת Android כוללת כמה תכונות כמו VNDK (שמתוארת בקטע הזה),‏ HIDL,‏ hwbinder,‏ device tree overlay ו-sepolicy overlay.

תנאים ספציפיים ל-VNDK

במסמכים שקשורים ל-VNDK נעשה שימוש במינוח הבא:
  • מודולים הם ספריות משותפות או קבצים הפעלה. מודולים יוצרים יחסי תלות בזמן ה-build.
  • תהליכים הם משימות של מערכת ההפעלה שנוצרות מקבצים הפעלה. תהליכים יוצרים תלויות בזמן ריצה.
  • מונחים שעומדים בדרישות המסגרת קשורים למחיצה system:
    • קובצי הפעלה של המסגרת הם קובצי הפעלה ב-/system/bin או ב-/system/xbin.
    • ספריות משותפות של מסגרות הן ספריות משותפות שנמצאות בתיקייה /system/lib[64].
    • מודולים של מסגרות מתייחסים גם לספריות משותפות של מסגרות וגם לקבצים הפעלה של מסגרות.
    • תהליכי Framework הם תהליכים שנוצרים מקובצי הפעלה של Framework, כמו /system/bin/app_process.
  • המונחים שקשורים לספקים מתייחסים לחלוקה לvendor מחיצות:
    • קבצים הפעלה של ספקים הם קבצים הפעלה ב-/vendor/bin
    • ספריות משותפות של ספקים הן ספריות משותפות שנמצאות בקטע /vendor/lib[64].
    • מודולים של ספקים מתייחסים גם לקובצי הפעלה של ספקים וגם לספריות משותפות של ספקים.
    • תהליכי ספקים הם תהליכים שנוצרים מקובצי הפעלה של ספקים, כמו /vendor/bin/android.hardware.camera.provider@2.4-service.

מושגים שקשורים ל-VNDK

בעולם אידיאלי של Android 8.0 ואילך, תהליכי framework לא טוענים ספריות משותפות של ספקים, כל תהליכי הספקים טוענים רק ספריות משותפות של ספקים (וחלק מהספריות המשותפות של framework), והתקשורת בין תהליכי framework ותהליכי ספקים מנוהלת על ידי HIDL ו-hardware binder.

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

בקטעים הבאים מוסבר איך VNDK מטפל בספריות משותפות של מסגרות לספקים וב-HALs באותו תהליך (SP-HALs).

ספריות משותפות של מסגרות לספקים

בקטע הזה מתוארים הקריטריונים לסיווג ספריות משותפות שאפשר לגשת אליהן בתהליכי ספק. יש שתי גישות לתמיכה במודולים של ספקים בכמה גרסאות של Android:

  1. ייצוב של ממשקי ה-ABI/API של הספריות המשותפות של המסגרת. מודולים חדשים של מסגרת ומודולים ישנים של ספקים יכולים להשתמש באותה ספרייה משותפת כדי לצמצם את טביעת הרגל בזיכרון ואת גודל האחסון. בנוסף, ספרייה משותפת ייחודית מונעת כמה בעיות שקשורות לטעינה כפולה. עם זאת, עלות הפיתוח של שמירה על ממשקי ABI/API יציבים היא גבוהה, ולא ריאלי לייצב את כל ממשקי ה-ABI/API שמיוצאים על ידי כל ספרייה משותפת של מסגרת.
  2. העתקה של ספריות משותפות ישנות של מסגרות. הוא כולל הגבלה חזקה נגד ערוצים צדדיים, שמוגדרים ככל המנגנונים לתקשורת בין מודולים של מסגרות ומודולים של ספקים, כולל (אבל לא רק) binder,‏ socket,‏ pipe,‏ shared memory,‏ shared file ומאפייני מערכת. אסור שתהיה תקשורת אלא אם פרוטוקול התקשורת קפוא ויציב (למשל HIDL דרך hwbinder). טעינה כפולה של ספריות משותפות עלולה גם לגרום לבעיות. לדוגמה, אם אובייקט שנוצר על ידי הספרייה החדשה מועבר לפונקציות מהספרייה הישנה, יכולה להתרחש שגיאה כי יכול להיות שהספריות האלה יפרשו את האובייקט בצורה שונה.

הגישות השונות משמשות בהתאם למאפיינים של הספריות המשותפות. כתוצאה מכך, ספריות משותפות של מסגרות מסווגות לשלוש קטגוריות משנה:

  • ספריות LL-NDK הן ספריות משותפות של Framework שידוע שהן יציבות. המפתחים שלהם מחויבים לשמור על יציבות ה-API/ABI.
    • ‫LL-NDK כולל את הספריות הבאות: libEGL.so, libGLESv1_CM.so, libGLESv2.so, libGLESv3.so, libandroid_net.so, libc.so, libdl.so, liblog.so, libm.so, libnativewindow.so, libneuralnetworks.so, libsync.so, libvndksupport.so ו-libvulkan.so,
  • ספריות VNDK (ספריית VNDK) שעומדות בדרישות הן ספריות משותפות של Framework שאפשר להעתיק פעמיים בלי בעיות. מודולים של מסגרת ומודולים של ספקים יכולים להיות מקושרים לעותקים שלהם. ספרייה משותפת של מסגרת יכולה להיות ספריית VNDK מתאימה רק אם היא עומדת בקריטריונים הבאים:
    • הוא לא שולח או מקבל IPCs אל/מהמסגרת.
    • הוא לא קשור למכונה הווירטואלית של ART.
    • היא לא קוראת/כותבת קבצים/מחיצות עם פורמטים לא יציבים של קבצים.
    • אין לו רישיון תוכנה מיוחד שדורש בדיקות משפטיות.
    • לבעלים של הקוד אין התנגדות לשימוש בו על ידי ספקים.
  • ספריות Framework-Only (FWK-ONLY) הן ספריות Framework Shared שלא שייכות לקטגוריות שצוינו למעלה. הספריות האלה:
    • נחשבים לפרטי הטמעה פנימיים של המסגרת.
    • אסור למודולים של ספקים לגשת אליהם.
    • יש להם ממשקי API או ABI לא יציבים, ואין ערבויות לתאימות של API או ABI.
    • לא מועתקים.

HAL באותו תהליך (SP-HAL)

Same-Process HAL‏ (SP-HAL) הוא קבוצה של HAL שנקבעו מראש ומיושמים כ-Vendor Shared Libraries (ספריות משותפות של ספקים) ונטענים לתוך Framework Processes (תהליכי מסגרת). ספריות SP-HAL מבודדות על ידי מרחב שמות של מקשר (שולט בספריות ובסמלים שגלויים לספריות המשותפות). ספריות SP-HAL חייבות להיות תלויות רק ב-LL-NDK וב-VNDK-SP.

‫VNDK-SP היא קבוצת משנה מוגדרת מראש של ספריות VNDK שעומדות בדרישות. ספריות VNDK-SP נבדקות בקפידה כדי לוודא שטעינה כפולה של ספריות VNDK-SP לתהליכי framework לא גורמת לבעיות. ‫Google מגדירה את שניהם: SP-HALs ו-VNDK-SPs.

הספריות הבאות הן SP-HAL מאושרות:

  • libGLESv1_CM_${driver}.so
  • libGLESv2_${driver}.so
  • libGLESv3_${driver}.so
  • libEGL_${driver}.so
  • vulkan.${driver}.so
  • android.hardware.renderscript@1.0-impl.so
  • android.hardware.graphics.mapper@2.0-impl.so

ספריות VNDK-SP מציינות vndk: { support_system_process: true } בקובצי Android.bp שלהן. אם מציינים גם את vndk: {private:true}, הספריות האלה נקראות VNDK-SP-Private והן לא גלויות ל-SP-HALS.

אלה ספריות של framework בלבד עם חריגים של RS‏ (FWK-ONLY-RS):

  • libft2.so (Renderscript)
  • libmediandk.so (Renderscript)

ניהול גרסאות של VNDK

הספריות המשותפות של VNDK הן בעלות גרסאות:

  • נכס המערכת ro.vndk.version נוסף אוטומטית אל /vendor/default.prop.
  • ספריות משותפות של VNDK ו-VNDK-SP מותקנות כ-VNDK apex com.android.vndk.v${ro.vndk.version} ומצורפות ל-/apex/com.android.vndk.v${ro.vndk.version}.

הערך של ro.vndk.version נבחר על ידי האלגוריתם שמופיע בהמשך:

  • אם BOARD_VNDK_VERSION לא שווה ל current, משתמשים ב-BOARD_VNDK_VERSION.
  • אם BOARD_VNDK_VERSION שווה ל current:
    • אם PLATFORM_VERSION_CODENAME הוא REL, משתמשים ב-PLATFORM_SDK_VERSION (למשל, 28).
    • אחרת, משתמשים ב-PLATFORM_VERSION_CODENAME (לדוגמה: P).

חבילת בדיקות לספקים (VTS)

ב-Android Vendor Test Suite‏ (VTS) נדרש מאפיין ro.vndk.version לא ריק. גם במכשירים חדשים וגם במכשירים שמשדרגים, צריך להגדיר את ro.vndk.version. חלק ממקרי הבדיקה של VNDK (למשל, VtsVndkFilesTest ו-VtsVndkDependencyTest) מסתמכים על המאפיין ro.vndk.version כדי לטעון את מערכי הנתונים התואמים של ספריות VNDK שעומדות בדרישות.