اجرای واسط های پارتیشن محصول

اندروید 11 پارتیشن product را جدا می‌کند و آن را از system و پارتیشن‌های vendor مستقل می‌کند. به عنوان بخشی از این تغییرات، اکنون می‌توانید دسترسی پارتیشن product به رابط‌های بومی و جاوا را کنترل کنید (که شبیه نحوه عملکرد اجرای رابط برای پارتیشن‌های vendor است).

اجرای رابط های بومی

برای فعال کردن اجرای رابط بومی، PRODUCT_PRODUCT_VNDK_VERSION را روی current تنظیم کنید. (زمانی که سطح API ارسال برای هدف بیشتر از 29 باشد، نسخه به طور خودکار روی current تنظیم می شود.) اجرا اجازه می دهد:

  • ماژول های بومی در پارتیشن 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 پیوند داده شوند.

جدول زیر ویژگی های 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 N/A محصول اصلی
vendor_available: true AND product_available: true N/A هسته، محصول، فروشنده
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 ایجاد شود.

اجرای رابط های جاوا

برای فعال کردن اجرای رابط جاوا، PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE را روی true تنظیم کنید. (وقتی سطح API ارسال برای هدف بیشتر از 29 باشد، مقدار به طور خودکار روی true تنظیم می‌شود.) هنگامی که فعال باشد، اعمال دسترسی زیر را مجاز/غیر مجاز می‌کند.

API /سیستم /system_ext /تولید - محصول /فروشنده /داده ها
API عمومی
@SystemApi
@hide API

همانطور که در پارتیشن vendor ، یک برنامه یا کتابخانه جاوا در پارتیشن product مجاز است فقط از APIهای عمومی و سیستمی استفاده کند. پیوند دادن به کتابخانه ای که از API های پنهان استفاده می کند مجاز نیست. این محدودیت شامل پیوند در زمان ساخت و بازتاب در زمان اجرا می شود.

اجرای زمان را بسازید

در زمان ساخت، Make و Soong با بررسی فیلدهای platform_apis و sdk_version تأیید می‌کنند که ماژول‌های جاوا در پارتیشن product از APIهای پنهان استفاده نمی‌کنند. sdk_version برنامه‌ها در پارتیشن product باید با نسخه current ، system_current یا عددی API پر شود و قسمت platform_apis باید خالی باشد.

اجرای زمان اجرا

زمان اجرا اندروید تأیید می‌کند که برنامه‌های موجود در پارتیشن product از APIهای پنهان از جمله بازتاب استفاده نمی‌کنند. برای جزئیات، به محدودیت‌های رابط‌های غیر SDK مراجعه کنید.

فعال کردن اجرای رابط محصول

از مراحل این بخش برای فعال کردن اجرای رابط محصول استفاده کنید.

گام وظیفه ضروری
1 فایل سازنده سیستم خود را تعریف کنید که بسته‌های مربوط به پارتیشن system را مشخص می‌کند، سپس بررسی مورد نیاز مسیر مصنوعات را در device.mk تنظیم کنید (برای جلوگیری از نصب ماژول‌های غیر سیستمی در پارتیشن system ). ن
2 لیست مجاز را پاک کنید. ن
3 واسط های بومی را اجرا کنید و خرابی های لینک زمان اجرا را شناسایی کنید (می تواند به موازات اجرای جاوا اجرا شود). Y
4 رابط های جاوا را اجرا کنید و رفتار زمان اجرا را تأیید کنید (می تواند به موازات اجرای بومی اجرا شود). Y
5 رفتارهای زمان اجرا را بررسی کنید. Y
6 به روز رسانی device.mk با اجرای رابط محصول. Y

مرحله 1: ایجاد فایل ایجاد کنید و بررسی مسیر مصنوع را فعال کنید

در این مرحله میک فایل 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 تنظیم می شود، سیستم ساخت از نصب بسته های تعریف شده در فایل های دیگر در مسیرهای تعریف شده در require-artifacts-in-path جلوگیری می کند و از نصب بسته های تعریف شده در makefile فعلی، مصنوعات خارج از مسیرهای تعریف شده در require-artifacts-in-path جلوگیری می کند. require-artifacts-in-path

در مثال بالا، وقتی PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS روی strict تنظیم شده است، فایل های ساخت خارج از oem_system.mk نمی توانند شامل ماژول های نصب شده در پارتیشن root یا system باشند. برای گنجاندن این ماژول ها، باید آنها را در خود فایل oem_system.mk یا در یک makefile موجود تعریف کنید. تلاش برای نصب ماژول ها در مسیرهای غیرمجاز باعث خرابی ساخت می شود. برای رفع خرابی ها، یکی از موارد زیر را انجام دهید:

  • گزینه 1: ماژول سیستم را در فایل های موجود در oem_system.mk قرار دهید. این امر باعث می‌شود که نیاز مسیر مصنوع برآورده شود (زیرا ماژول‌ها اکنون در یک فایل ایجاد شده موجود هستند) و بنابراین امکان نصب مجموعه مسیرها در «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_available: true در دسترس پارتیشن product قرار دهید یا با تنظیم product_specific: true ماژول را به پارتیشن product منتقل کنید.
  3. خطاهای ساخت را برطرف کنید و اطمینان حاصل کنید که دستگاه با موفقیت ساخته می شود.

  4. تصویر را فلش کنید و به دنبال خطاهای زمان اجرا در بوت دستگاه و لاگ ها بگردید.

    • اگر تگ linker از گزارش مورد آزمایشی پیام CANNOT LINK EXECUTABLE را نشان دهد، فایل make وابستگی ندارد (و در زمان ساخت ضبط نشده است).
    • برای بررسی آن از سیستم ساخت، کتابخانه مورد نیاز را به قسمت shared_libs: یا required: اضافه کنید.
  5. وابستگی های از دست رفته را با استفاده از راهنمایی ارائه شده در بالا حل کنید.

مرحله 4: رابط های جاوا را اجرا کنید

در این مرحله، PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true را تنظیم می کنید، سپس خطاهای ساخت حاصل را پیدا کرده و رفع می کنید. به دنبال دو نوع خاص از خطا باشید:

  • خطاهای نوع پیوند این خطا نشان می‌دهد که یک برنامه به ماژول‌های جاوا که دارای 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: رفتارهای زمان اجرا را بررسی کنید

در این مرحله، بررسی می‌کنید که رفتارهای زمان اجرا مطابق انتظار هستند. برای برنامه‌هایی که قابل اشکال‌زدایی هستند، می‌توانید با استفاده از StrictMode.detectNonSdkApiUsage (که زمانی که برنامه از یک API مخفی استفاده می‌کند، گزارشی ایجاد می‌کند) استفاده از 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