מניפסטים

אובייקט VINTF אוסף נתונים מקובצי manifest של המכשיר ומקובצי manifest של המסגרת (XML). לשני המניפסטים יש פורמט זהה, אבל לא כל הרכיבים רלוונטיים לשניהם (פרטים על הסכימה זמינים במאמר הסכימה של קובץ מניפסט).

מניפסט של מכשיר

המניפסט של המכשיר (שסופק על ידי המכשיר) מורכב מהמניפסט של הספק וממניפסט ה-ODM.

  • המניפסט של הספק מציין HAL, גרסאות של מדיניות SELinux וכו' שמשותפים ל-SoC. מומלץ למקם אותו בעץ המקור של Android בכתובת device/VENDOR/DEVICE/manifest.xml, אבל אפשר להשתמש בכמה קובצי קטעים. פרטים נוספים זמינים במאמרים קטעי מניפסט ויצירת DM מקטעים.
  • ב-manifest של ODM מפורטים ממשקי HAL ספציפיים למוצר במחיצה של ODM. האובייקט VINTF טוען את המניפסט של ODM בסדר הזה:
    1. אם SKU מוגדר (כאשר SKU הוא הערך של המאפיין ro.boot.product.hardware.sku), /odm/etc/vintf/manifest_SKU.xml
    2. /odm/etc/vintf/manifest.xml
    3. אם SKU מוגדר, /odm/etc/manifest_SKU.xml
    4. /odm/etc/manifest.xml
  • מניפסט הספק מפרט את ממשקי ה-HAL הספציפיים למוצר במחיצה של הספק. אובייקט VINTF טוען את המניפסט של הספק בסדר הזה:
    1. אם SKU מוגדר (כאשר SKU הוא הערך של המאפיין ro.boot.product.vendor.sku), /vendor/etc/vintf/manifest_SKU.xml
    2. /vendor/etc/vintf/manifest.xml
  • אובייקט VINTF טוען את המניפסט של המכשיר בסדר הזה:
    1. אם המניפסט של הספק קיים, משלבים את הפריטים הבאים:
      1. המניפסט של הספק
      2. קטעי מניפסט אופציונליים של ספקים
      3. מניפסט ODM אופציונלי
      4. קטעי מניפסט אופציונליים של ODM
    2. אחרת, אם המניפסט של ODM קיים, משלבים את המניפסט של ODM עם קטעי המניפסט האופציונליים של ODM.
    3. /vendor/manifest.xml (דור קודם, ללא קטעים)
    4. לבסוף, משלבים את קטעי המניפסט מכל קבצי ה-APEX של הספקים. קטעי המניפסט נטענים מהספרייה etc/vintf של כל APEX (למשל, /apex/<apex name>/etc/vintf).

    חשוב לזכור:

    • במכשירים מדור קודם, נעשה שימוש במניפסט של הספק הקודם ובמניפסט של ODM. המניפסט של ה-ODM יכול לבטל לגמרי את המניפסט הקודם של הספק.
    • במכשירים שהושקו עם Android 9, המניפסט של ODM משולב עם המניפסט של הספק.
    • כשמשלבים רשימה של מניפסטים, מניפסטים שמופיעים בהמשך הרשימה עשויים לשנות את התגים במניפסטים שמופיעים מוקדם יותר ברשימה, בתנאי שהתגים במניפסט המאוחר יותר כוללים את המאפיין override="true". לדוגמה, המניפסט של ה-ODM עשוי לבטל חלק מהתגים מסוג <hal> מהמניפסט של הספק. אפשר לעיין במסמכים של המאפיין override בהמשך.

ההגדרה הזו מאפשרת למספר מוצרים עם אותה לוח שיתפו את אותה תמונה של הספק (שמספקת HALs משותפים), אבל עם תמונות ODM שונות (שמציינות HALs ספציפיים למוצר).

לפניכם דוגמה למניפסט של ספק.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="2.0" type="device" target-level="1">
    <hal>
        <name>android.hardware.camera</name>
        <transport>hwbinder</transport>
        <version>3.4</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>legacy/0</instance>
            <instance>proprietary/0</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <version>2.0</version>
        <interface>
            <name>INfc</name>
            <instance>nfc_nci</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
        <fqname>@2.0::INfc/default</fqname>
    </hal>
    <hal>
        <name>android.hardware.drm</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ICryptoFactory</name>
            <instance>default</instance>
        </interface>
        <interface>
            <name>IDrmFactory</name>
            <instance>default</instance>
        </interface>
        <fqname>@1.1::ICryptoFactory/clearkey</fqname>
        <fqname>@1.1::IDrmFactory/clearkey</fqname>
    </hal>
    <hal format="aidl">
        <name>android.hardware.light</name>
        <version>1</version>
        <fqname>ILights/default</fqname>
    </hal>
    <hal format="aidl">
        <name>android.hardware.power</name>
        <version>2</version>
        <interface>
            <name>IPower</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal format="native">
        <name>EGL</name>
        <version>1.1</version>
    </hal>
    <hal format="native">
        <name>GLES</name>
        <version>1.1</version>
        <version>2.0</version>
        <version>3.0</version>
    </hal>
    <sepolicy>
        <version>25.0</version>
    </sepolicy>
</manifest>

דוגמה למניפסט ODM.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="device">
    <!-- camera 3.4 in vendor manifest is ignored -->
    <hal override="true">
        <name>android.hardware.camera</name>
        <transport>hwbinder</transport>
        <version>3.5</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>legacy/0</instance>
        </interface>
    </hal>
    <!-- NFC is declared to be disabled -->
    <hal override="true">
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
    </hal>
    <hal>
        <name>android.hardware.power</name>
        <transport>hwbinder</transport>
        <version>1.1</version>
        <interface>
            <name>IPower</name>
            <instance>default</instance>
        </interface>
    </hal>
</manifest>

דוגמה למניפסט של מכשיר בחבילת OTA.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="device" target-level="1">
    <!-- hals ommited -->
    <kernel version="4.4.176">
        <config>
            <key>CONFIG_ANDROID</key>
            <value>y</value>
        </config>
        <config>
            <key>CONFIG_ARM64</key>
            <value>y</value>
        </config>
    <!-- other configs ommited -->
    </kernel>
</manifest>

פרטים נוספים זמינים במאמר פיתוח מניפסט של מכשיר.

מניפסט של Framework

קובץ המניפסט של המסגרת מורכב ממניפסט המערכת, ממניפסט המוצר וממניפסט system_ext.

  • המניפסט של המערכת (שסופק על ידי Google) נוצר באופן ידני וממוקם בעץ המקור של Android בכתובת /system/libhidl/manifest.xml.
  • במניפסט המוצר (שסופק על ידי המכשיר) מפורטים ממשקי HAL שמקבלים שירות ממודולים שמותקנים במחיצה של המוצר.
  • המניפסט system_ext (שסופק על ידי המכשיר) כולל את הפרטים הבאים:
    • ממשקי HAL שמקבלים שירות ממודולים שמותקנים במחיצה system_ext.
    • גרסאות VNDK
    • גרסת ה-SDK של המערכת.

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

זוהי דוגמה למניפסט של מסגרת.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="framework">
    <hal>
        <name>android.hidl.allocator</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IAllocator</name>
            <instance>ashmem</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hidl.memory</name>
        <transport arch="32+64">passthrough</transport>
        <version>1.0</version>
        <interface>
            <name>IMapper</name>
            <instance>ashmem</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hidl.manager</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IServiceManager</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal>
        <name>android.frameworks.sensorservice</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ISensorManager</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal max-level="5">
        <name>android.frameworks.schedulerservice</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ISchedulingPolicyService</name>
            <instance>default</instance>
        </interface>
    </hal>
    <vendor-ndk>
        <version>27</version>
    </vendor-ndk>
    <system-sdk>
        <version>27</version>
    </system-sdk>
</manifest>

קטעי מניפסט

ב-Android מגרסה 10 ואילך, אפשר לשייך רשומה ב-manifest למודול HAL במערכת ה-build. כך קל יותר לכלול את מודול ה-HAL במערכת ה-build באופן מותנה.

דוגמה

בקובץ Android.bp או Android.mk, מוסיפים את הערך vintf_fragments לכל מודול שמותקן במפורש במכשיר, כמו cc_binary או rust_binary. לדוגמה, אפשר לשנות את המודול בהטמעה של HAL (my.package.foo@1.0-service-bar).

... {
    ...
    vintf_fragments: ["manifest_foo.xml"],
    ...
}
LOCAL_MODULE := ...
LOCAL_VINTF_FRAGMENTS := manifest_foo.xml

יוצרים את המניפסט של המודול בקובץ בשם manifest_foo.xml. במהלך ה-build, המניפסט הזה מתווסף למכשיר. הוספת רשומה כאן זהה להוספת רשומה במניפסט הראשי של המכשיר. כך לקוחות יכולים להשתמש בממשק, ו-VTS יכול לזהות אילו הטמעות של HAL נמצאות במכשיר. המניפסט הזה יכול לבצע את כל הפעולות שמניפסט רגיל יכול לבצע.

בדוגמה הבאה מוטמע android.hardware.foo@1.0::IFoo/default, שמתקינים במחיצה vendor או odm. אם הוא מותקן במחיצה system, product או system_ext, צריך להשתמש בסוג framework במקום בסוג device.

<manifest version="1.0" type="device">
    <hal format="hidl">
        <name>android.hardware.foo</name>
        <transport>hwbinder</transport>
        <fqname>@1.0::IFoo/default</fqname>
    </hal>
</manifest>

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

הסכימה של קובץ המניפסט

בקטע הזה מתוארים המשמעות של תגי ה-XML האלה. יכול להיות שחלק מהתגים 'הנדרשים' ייעדרו מקובץ המקור בעץ המקור של Android, ו-assemble_vintf יכתוב אותם בזמן ה-build. התגים הנדרשים חייבים להופיע בקבצים המתאימים במכשיר.

?xml
אופציונלי. מספקת מידע רק למנתח ה-XML.
manifest.version
חובה. גרסת המטא של המניפסט הזה. תיאור הרכיבים הצפויים במניפסט. לא קשור לגרסה של ה-XML.
manifest.type
חובה. סוג המניפסט. הערך שלו הוא device בקובץ המניפסט של המכשיר ו-framework בקובץ המניפסט של המסגרת.
manifest.target-level
חובה במניפסט של המכשיר. מציין את גרסת מטריצת התאימות של המסגרת (FCM) שאליה המניפסט של המכשיר הזה מיועד להיות תואם. הגרסה הזו נקראת גם 'גרסת FCM ששולחים למכשיר'.
manifest.hal
אופציונלי, אפשר לחזור עליו. HAL יחיד (HIDL או מקורי, כמו GL), בהתאם למאפיין format.
manifest.hal.format
אופציונלי. הערך יכול להיות אחד מהערכים הבאים:
  • hidl: ממשקי HAL של HIDL. זוהי ברירת המחדל.
  • aidl: HAL של AIDL. התג תקף רק במטא-גרסה 2.0 ואילך של המניפסט.
  • native: ממשקי HAL מקומיים.
manifest.hal.max-level
אופציונלי. תקף רק במניפסטים של מסגרות. אם ההגדרה הזו מוגדרת, רכיבי HAL עם רמה מקסימלית נמוכה יותר מגרסה היעד של FCM במניפסט של המסגרת יושבתו.
manifest.hal.override
אופציונלי. הערך יכול להיות אחד מהערכים הבאים:
  • true: שינוי של אלמנטים <hal> אחרים עם אותו <name> וגרסה ראשית. אם לא מופיעים הערכים <version> או <fqname> ברכיב <hal>, הרכיב <hal> מצהיר שה-HAL הזה מושבת.
  • false: אין לשנות את הערכים של רכיבי <hal> אחרים עם אותה <name> וגרסה ראשית.
manifest.hal.name
חובה. שם החבילה המלא של ה-HAL. אפשר להשתמש באותו שם בכמה רשומות HAL. דוגמאות:
  • android.hardware.camera (HIDL או AIDL HAL)
  • GLES (HAL מקורי, נדרש שם בלבד)
manifest.hal.transport
חובה כאשר manifest.hal.format == "hidl". אחרת, אסור שיהיה בו תוכן. מציין את סוג התעבורה שבו נעשה שימוש כשנשלחת שאילתה לממשק מהחבילה הזו ממנהל השירות. הערך יכול להיות אחד מהערכים הבאים:
  • hwbinder: מצב Binderized
  • passthrough: מצב העברה ישירה
אופציונלי כשהערך הוא manifest.hal.format == "aidl". אחרת, אסור שיהיה בו תוכן. מציין את סוג התעבורה שבו נעשה שימוש כשממשק מסוים מוצג מרחוק. הערך חייב להיות:
  • inet: שקע Inet
צריך להשתמש ב-manifest.hal.transport.ip וב-manifest.hal.transport.port כדי לציין פרטים נוספים לגבי חיבור ה-Inet.
manifest.hal.transport.arch
נדרש עבור passthrough אסור שיהיה נוכח ב-hwbinder. תיאור של רמת הביטים של שירות העברה (passthrough) שסופק. הערך יכול להיות אחד מהערכים הבאים:
  • 32: מצב 32 ביט
  • 64: מצב 64 ביט
  • 32+64: שניהם
manifest.hal.transport.ip
חובה עבור inet ואסור שיופיע במקרים אחרים. תיאור כתובת ה-IP שממנה הממשק המרוחק מוצג.
manifest.hal.transport.port
חובה עבור inet ואסור שיופיע במקרים אחרים. תיאור היציאה שממנה הממשק המרוחק מוצג.
manifest.hal.version
אופציונלי, אפשר לחזור עליו. גרסה של תגי hal במניפסט.

ב-HIDL וב-HAL מקורי, הפורמט הוא MAJOR.MINOR. לדוגמה, hardware/interfaces,‏ vendor/${VENDOR}/interfaces,‏ frameworks/hardware/interfaces או system/hardware/interfaces.

ב-HIDL וב-HAL מקומיים יכולים להופיע כמה שדות גרסה, כל עוד הם מייצגים גרסאות ראשיות נפרדות, עם גרסה משנית אחת בלבד לכל גרסה ראשית. לדוגמה, לא ניתן לשלב בין 3.1 ל-3.2, אבל אפשר לשלב בין 1.0 ל-3.4. הכלל הזה חל על כל הרכיבים מסוג hal עם אותו שם, אלא אם override="true". הערכים של <version> לא משויכים ל-<fqname> כי <fqname> מכיל גרסה.

ב-HAL של AIDL, <version> לא יכול להופיע במכשירים עם Android מגרסה 11 ומטה. המשתנה <version> חייב להיות מספר שלם יחיד במכשירים עם Android מגרסה 12 ואילך. יכול להיות לכל היותר <version> אחד לכל קבוצת ערכים (tuple) של (package, interface, instance). אם הפרמטר לא מופיע, ברירת המחדל היא 1. הערך של <version> משויך לכל <fqname> באותו <hal> כי <fqname> לא מכיל גרסה.
manifest.hal.interface
חובה, אפשר לחזור עליו בלי עותקים כפולים. מצהירים על ממשק בחבילה שיש לו שם מכונה. אפשר לכלול כמה רכיבי <interface> ב-<hal>, אבל השמות חייבים להיות ייחודיים.
manifest.hal.interface.name
חובה. שם הממשק.
manifest.hal.interface.instance
חובה, אפשר לחזור עליו. שם המכונה של הממשק. יכולות להיות כמה מכונות לממשק, אבל אין רכיבי <instance> כפולים.
manifest.hal.fqname
אופציונלי, אפשר לחזור עליו. דרך חלופית לציין מכונה ל-HAL בשם manifest.hal.name.
  • ב-HIDL HAL, הפורמט הוא @MAJOR.MINOR::INTERFACE/INSTANCE.
  • ב-HAL של AIDL, הפורמט הוא INTERFACE/INSTANCE.
manifest.sepolicy
חובה. מכיל את כל הרשומות שקשורות למדיניות האבטחה.
manifest.sepolicy.version
חובה במניפסט של המכשיר. הצהרה על גרסת SELinux. הפורמט שלו הוא SDK_INT.PLAT_INT.
manifest.vendor-ndk
חובה, אפשר לחזור עליו. חובה למניפסט של המסגרת. אסור שיופיע במניפסט של המכשיר. אם יש כמה רשומות <vendor-ndk>, לכל אחת מהן צריך להיות <version> שונה. תיאור של קבוצת קובצי snapshot של VNDK שסופקו על ידי המסגרת.
manifest.vendor-ndk.version
חובה. זהו מספר שלם חיובי שמייצג את הגרסה של קובץ ה-snapshot של VNDK.
manifest.vendor-ndk.library
אופציונלי, אפשר לחזור עליו בלי כפילויות. תיאור של קבוצת ספריות VNDK שסופקו על ידי המסגרת לתמונת המצב של ספק VNDK. הערך הוא שם הקובץ של הספרייה, למשל libjpeg.so, כולל הקידומת lib והסיומת .so. אסור להשתמש ברכיבי נתיב.
manifest.system-sdk.version
אופציונלי, אפשר לחזור עליו, ללא כפילויות. משמש רק את המניפסט של המסגרת. תיאור של קבוצת גרסאות SDK למערכת שסופקו על ידי המסגרת לאפליקציות של ספקים.
manifest.kernel
אופציונלי. תיאור של מידע סטטי על הליבה.
manifest.kernel.target-level
אופציונלי. תיאור ההסתעפות של הליבה. אם הערך לא מופיע, ערך ברירת המחדל שלו הוא manifest.target-level. הערך חייב להיות גדול מ-manifest.target-level או שווה לו. פרטים נוספים זמינים במאמר כללי התאמה של הליבה.