אכיפת ממשקי מחיצות מוצרים

אנדרואיד 11 מפרקת את מחיצת product , מה שהופך אותה ללא תלות במחיצות system vendor . כחלק משינויים אלו, כעת תוכל לשלוט בגישה של מחיצת product לממשקי מקור ו-Java (שדומה לאופן שבו פועלת אכיפת ממשק עבור מחיצות vendor ).

אכיפת ממשקים מקוריים

כדי להפעיל את אכיפת הממשק המקורי, הגדר את PRODUCT_PRODUCT_VNDK_VERSION למצב current . (הגרסה מוגדרת אוטומטית current כאשר רמת ה-API למשלוח עבור היעד גדולה מ-29.) האכיפה מאפשרת:

  • מודולים מקוריים במחיצת product לקישור:
    • סטטי או דינמי למודולים אחרים במחיצת product הכוללים ספריות סטטיות, משותפות או כותרות.
    • באופן דינמי לספריות VNDK במחיצת system .
  • ספריות JNI ב-APK מפורקות במחיצת product לקישור לספריות ב- /product/lib או /product/lib64 (זה בנוסף לספריות NDK).

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

בניית אכיפת זמן (Android.bp)

באנדרואיד 11, מודולי מערכת יכולים ליצור גרסת תמונת מוצר בנוסף לגרסת תמונת הליבה והספק. כאשר אכיפה של ממשק מקורי מופעלת ( PRODUCT_PRODUCT_VNDK_VERSION מוגדר current ):

  • מודולים מקוריים במחיצת product נמצאים בגרסה של המוצר במקום בגרסה הליבה.

  • מודולים עם product_available: true בקבצי Android.bp שלהם זמינים לגרסה של המוצר.

  • ספריות או בינאריות המציינות product_specific: true יכולות לקשר לספריות אחרות שמציינות product_specific: true או product_available: true בקבצי Android.bp שלהם.

  • לספריות VNDK חייבות להיות product_available: true בקבצי Android.bp שלהן, כך שבינאריות product יכולות לקשר ל-VNDK libs.

הטבלה הבאה מסכמת את מאפייני Android.bp המשמשים ליצירת גרסאות תמונה.

מאפיינים ב-Android.bp נוצרו גרסאות
לפני האכיפה לאחר אכיפה
ברירת מחדל (אין) הליבה

(כולל /system , /system_ext ו- /product )

הליבה

(כולל /system ו- /system_ext אך לא /product )

system_ext_specific: true הליבה הליבה
product_specific: true הליבה מוצר
vendor: true מוֹכֵר מוֹכֵר
vendor_available: true ליבה, ספק ליבה, ספק
product_available: true לא מוצר ליבה
vendor_available: true AND product_available: true לא ליבה, מוצר, ספק
system_ext_specific: true AND vendor_available: true ליבה, ספק ליבה, ספק
product_specific: true AND vendor_available: true ליבה, ספק מוצר, ספק

בניית אכיפת זמן (Android.mk)

כאשר אכיפה של ממשק מקורי מופעלת, מודולים מקוריים המותקנים במחיצת product הם בעלי סוג קישור native:product שיכול לקשר רק למודול native:product או native:vndk אחרים. ניסיון לקשר למודולים כלשהם מלבד אלה גורם למערכת הבנייה ליצור שגיאת בדיקת סוג קישור.

אכיפה בזמן ריצה

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

אכיפת ממשקי Java

כדי להפעיל את אכיפת ממשק Java, הגדר את PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE ל- true . (הערך מוגדר אוטומטית ל- true כאשר רמת ה-API של המשלוח עבור היעד גדולה מ-29.) כאשר מופעל, האכיפה מאפשרת/אוסרת את הגישה הבאה.

ממשק API /מערכת /system_ext /מוצר /מוֹכֵר /נתונים
API ציבורי
@SystemApi
@hide API

כמו במחיצת vendor , אפליקציה או ספריית Java במחיצת product רשאית להשתמש רק בממשקי API ציבוריים ומערכתיים; קישור לספרייה המשתמשת בממשקי API מוסתרים אינו מותר. הגבלה זו כוללת קישור בזמן בנייה והשתקפות בזמן ריצה.

בנה אכיפת זמן

בזמן הבנייה, Make ו-Soong מוודאים שמודולי Java במחיצת product אינם משתמשים בממשקי API מוסתרים על ידי בדיקת השדות platform_apis ו- sdk_version . יש למלא את sdk_version של אפליקציות במחיצת product בגרסה current , system_current או מספרית של ה-API, והשדה platform_apis חייב להיות ריק.

אכיפה בזמן ריצה

זמן הריצה של Android מאמת שאפליקציות במחיצת product אינן משתמשות בממשקי API מוסתרים, כולל השתקפות. לפרטים, עיין בהגבלות על ממשקים שאינם SDK .

הפעלת אכיפה של ממשק המוצר

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

שלב מְשִׁימָה נדרש
1 הגדירו קובץ make-system משלכם המציין את החבילות עבור מחיצת system , ולאחר מכן הגדר את בדיקת הדרישות של נתיב החפצים ב- device.mk (כדי למנוע התקנה של מודולים שאינם מערכתיים במחיצת system ). נ
2 נקה את הרשימה המותרת. נ
3 לאכוף ממשקים מקוריים ולזהות כשלים בקישור בזמן ריצה (יכול לפעול במקביל לאכיפת Java). י
4 לאכוף ממשקי Java ולאמת התנהגות בזמן ריצה (יכול לפעול במקביל לאכיפה מקורית). י
5 בדוק התנהגויות בזמן ריצה. י
6 עדכן את device.mk עם אכיפת ממשק המוצר. י

שלב 1: צור makefile ואפשר בדיקת נתיב חפץ

בשלב זה, אתה מגדיר את קובץ המייקאפ system .

  1. צור makefile שמגדיר את החבילות עבור מחיצת system . לדוגמה, צור קובץ oem_system.mk עם הדברים הבאים:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
    
    # Applications
    PRODUCT_PACKAGES += \
        CommonSystemApp1 \
        CommonSystemApp2 \
        CommonSystemApp3 \
    
    # Binaries
    PRODUCT_PACKAGES += \
        CommonSystemBin1 \
        CommonSystemBin2 \
        CommonSystemBin3 \
    
    # Libraries
    PRODUCT_PACKAGES += \
        CommonSystemLib1 \
        CommonSystemLib2 \
        CommonSystemLib3 \
    
    PRODUCT_SYSTEM_NAME := oem_system
    PRODUCT_SYSTEM_BRAND := Android
    PRODUCT_SYSTEM_MANUFACTURER := Android
    PRODUCT_SYSTEM_MODEL := oem_system
    PRODUCT_SYSTEM_DEVICE := generic
    
    # For system-as-root devices, system.img should be mounted at /, so we
    # include ROOT here.
    _my_paths := \
     $(TARGET_COPY_OUT_ROOT)/ \
     $(TARGET_COPY_OUT_SYSTEM)/ \
    
    $(call require-artifacts-in-path, $(_my_paths),)
    
  2. בקובץ device.mk , ירשו את ה-makefile הנפוץ עבור מחיצת system ואפשרו את בדיקת הדרישות של נתיב החפץ. לדוגמה:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk)
    
    # Enable artifact path requirements checking
    PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
    

לגבי דרישות נתיב החפץ

כאשר PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS מוגדר כ- true או strict , מערכת ה-build מונעת מחבילות המוגדרות בקבצי makefile אחרים להתקין לנתיבים המוגדרים ב- require-artifacts-in-path ומונעת מחבילות המוגדרות ב-makefile הנוכחי להתקין חפצים מחוץ לנתיבים המוגדרים ב- require-artifacts-in-path .

בדוגמה שלמעלה, כאשר PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS מוגדר ל- strict , קבצי make-מחוץ oem_system.mk אינם יכולים לכלול מודולים המותקנים במחיצת root או system . כדי לכלול את המודולים האלה, עליך להגדיר אותם בקובץ oem_system.mk עצמו או בקובץ makefile כלול. ניסיונות להתקין מודולים בנתיבים לא מורשים גורמים להפסקות בבנייה. כדי לתקן הפסקות, בצע אחת מהפעולות הבאות:

  • אפשרות 1: כלול את מודול המערכת בקבצי makefile הכלולים ב- oem_system.mk . זה הופך את זה כך שדרישת נתיב החפצים מתקיימת (כפי שהמודולים קיימים כעת בקובץ makefile) ובכך מאפשר התקנה לקבוצת הנתיבים ב-`require-artifacts-in-path.

  • אפשרות 2: התקן מודולים למחיצת system_ext או product (ואל תתקין מודולים במחיצת system ).

  • אפשרות 3: הוסף מודולים ל- PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST . זה מפרט שאפשר להתקין מודולים.

שלב 2: רוקן את הרשימה המותרת

בשלב זה, אתה הופך את ה- PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST לריק כך שכל המכשירים החולקים oem_system.mk יוכלו גם לשתף תמונת system אחת. כדי לרוקן את הרשימה המותרת, העבר את כל המודולים ברשימה למחיצת system_ext או product או הוסף אותם לקבצי יצירת system . שלב זה הוא אופציונלי מכיוון שהגדרת תמונת system משותפת אינה נדרשת כדי לאפשר אכיפת ממשק מוצר. עם זאת, ריקון הרשימה המותרת מועיל להגדרת גבול system עם system_ext .

שלב 3: אכיפת ממשקים מקוריים

בשלב זה, אתה מגדיר את PRODUCT_PRODUCT_VNDK_VERSION := current , ולאחר מכן חפש שגיאות בנייה וזמן ריצה ופותר אותן. כדי לבדוק את האתחול והיומנים של המכשיר ולאתר ולתקן כשלים בקישור בזמן ריצה:

  1. הגדר את PRODUCT_PRODUCT_VNDK_VERSION := current .

  2. בנה את המכשיר וחפש שגיאות בנייה. סביר להניח שתראה כמה הפסקות בנייה עבור גרסאות מוצר חסרות או גרסאות ליבה. הפסקות נפוצות כוללות:

    • כל מודול hidl_interface שיש לו product_specific: true לא יהיה זמין עבור מודולי מערכת. כדי לתקן, החלף את product_specific: true ב- system_ext_specfic: true .
    • ייתכן שחסרה במודולים את גרסת המוצר הנדרשת עבור מודולי המוצר. כדי לתקן, הפוך את המודול לזמין למחיצת product על ידי הגדרת product_available: true או העבר את המודול למחיצת product על ידי הגדרת product_specific: true .
  3. פתור שגיאות בנייה והבטח שהמכשיר נבנה בהצלחה.

  4. הבזק את התמונה וחפש שגיאות זמן ריצה באתחול המכשיר וביומנים.

    • אם תג linker מקרה בדיקה מציג הודעת CANNOT LINK EXECUTABLE , חסרה תלות בקובץ ה-make (ולא נקלט בזמן הבנייה).
    • כדי לבדוק זאת ממערכת הבנייה, הוסף את הספרייה הנדרשת לשדה shared_libs: או required:
  5. פתרו את התלות החסרות באמצעות ההנחיות שניתנו לעיל.

שלב 4: אכיפת ממשקי Java

בשלב זה, אתה מגדיר את PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true , ולאחר מכן מצא ותקן שגיאות בנייה כתוצאה מכך. חפש שני סוגים ספציפיים של שגיאות:

  • שגיאות סוג קישור. שגיאה זו מציינת שאפליקציה מקשרת למודולי Java שיש להם גרסה רחבה יותר sdk_version . כדי לתקן, אתה יכול להרחיב את sdk_version של האפליקציה או להגביל את sdk_version של הספרייה. שגיאה לדוגמה:

    error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
    
  • שגיאות סמלים. שגיאה זו מציינת שלא ניתן למצוא סמל מכיוון שהוא נמצא בממשק API מוסתר. כדי לתקן, השתמש בממשק API גלוי (לא מוסתר) או מצא חלופה. שגיאה לדוגמה:

    frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol
                ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
                                               ^
      symbol:   class ProxyAuthenticate
      location: class SipSessionGroup.SipSessionImpl
    

שלב 5: בדוק התנהגויות בזמן ריצה

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

  • תחביר Veridex:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
    
  • תוצאת veridex לדוגמה:

    #1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s):
           Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V
    
    #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s):
           Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
    

לפרטים על השימוש ב-veridex, עיין בבדיקה באמצעות הכלי veridex .

שלב 6: עדכן את device.mk

לאחר תיקון כל כשלי הבנייה וזמן הריצה, וידוא שהתנהגויות זמן הריצה הן כצפוי, הגדר את הדברים הבאים ב- device.mk :

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true