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

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

رابط‌های بومی را اجرا کنید

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

  • ماژول‌های بومی در پارتیشن product برای پیوند دادن:
    • به صورت ایستا یا پویا به ماژول‌های دیگر در پارتیشن product که شامل کتابخانه‌های ایستا، مشترک یا هدر هستند.
    • به صورت پویا به کتابخانه‌های VNDK در پارتیشن system .
  • کتابخانه‌های JNI در APKهای غیربسته‌بندی‌شده در پارتیشن product برای پیوند به کتابخانه‌های موجود در /product/lib یا /product/lib64 (این علاوه بر کتابخانه‌های NDK است).

اجرای قانون اجازه نمی‌دهد پیوندهای دیگری به پارتیشن‌هایی غیر از پارتیشن product وجود داشته باشد.

اجرای زمان ساخت (Android.bp)

در اندروید ۱۱، ماژول‌های سیستم می‌توانند علاوه بر انواع تصویر هسته و فروشنده، یک نوع تصویر محصول نیز ایجاد کنند. هنگامی که اجرای رابط بومی فعال باشد ( PRODUCT_PRODUCT_VNDK_VERSION روی current تنظیم شده باشد):

  • ماژول‌های بومی در پارتیشن product ، به جای نوع اصلی، در نوع محصول قرار دارند.

  • ماژول‌هایی که در فایل‌های Android.bp خود product_available: true دارند، برای نوع محصول در دسترس هستند.

  • کتابخانه‌ها یا فایل‌های باینری که product_specific: true مشخص می‌کنند، می‌توانند به کتابخانه‌های دیگری که product_specific: true یا product_available: true در فایل‌های Android.bp خود مشخص می‌کنند، پیوند دهند.

  • کتابخانه‌های VNDK باید در فایل‌های Android.bp خود دارای product_available: true باشند تا فایل‌های باینری 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 ناموجود هسته، محصول
vendor_available: true و product_available: true ناموجود هسته، محصول، فروشنده
system_ext_specific: true و vendor_available: true هسته، فروشنده هسته، فروشنده
product_specific: true و 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 ارسال برای هدف بیشتر از ۲۹ باشد، این مقدار به طور خودکار روی true تنظیم می‌شود.) وقتی فعال باشد، اجرای رابط دسترسی‌های زیر را مجاز یا غیرمجاز می‌کند:

رابط برنامه‌نویسی کاربردی /سیستم /system_extension /محصول /فروشنده /داده‌ها
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های پنهان، از جمله reflection، استفاده نمی‌کنند. برای جزئیات بیشتر، به محدودیت‌ها در رابط‌های غیر SDK مراجعه کنید.

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

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

قدم وظیفه مورد نیاز
۱ فایل سیستم خودتان را که بسته‌های مربوط به پارتیشن system را مشخص می‌کند، تعریف کنید، سپس بررسی نیاز به مسیر مصنوعات را در device.mk تنظیم کنید (برای جلوگیری از نصب ماژول‌های غیرسیستمی در پارتیشن system ). ن
۲ لیست مجاز را پاک کنید. ن
۳ رابط‌های بومی را اجرا کنید و خرابی‌های لینک زمان اجرا را شناسایی کنید (می‌تواند به صورت موازی با اجرای جاوا اجرا شود). ی
۴ رابط‌های جاوا را اجرا کنید و رفتار زمان اجرا را تأیید کنید (می‌تواند به صورت موازی با اجرای بومی اجرا شود). ی
۵ رفتارهای زمان اجرا را بررسی کنید. ی
۶ device.mk با اجرای رابط محصول به‌روزرسانی کنید. ی

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

در این مرحله، فایل system makefile را تعریف می‌کنید.

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

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

  • گزینه ۱: ماژول سیستم را در فایل‌های makefile موجود در oem_system.mk قرار دهید. این کار باعث می‌شود که الزام مسیر مصنوع برآورده شود (زیرا ماژول‌ها اکنون در یک فایل makefile موجود هستند) و بنابراین امکان نصب در مجموعه مسیرهای موجود در `require-artifacts-in-path` فراهم می‌شود.

  • گزینه ۲: ماژول‌ها را در پارتیشن system_ext یا product نصب کنید (و ماژول‌ها را در پارتیشن system نصب نکنید).

  • گزینه ۳: ماژول‌ها را به PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST اضافه کنید. این لیست، ماژول‌های مجاز برای نصب را نشان می‌دهد.

مرحله ۲: خالی کردن لیست مجاز

در این مرحله، PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST را خالی می‌کنید تا همه دستگاه‌هایی که oem_system.mk را به اشتراک می‌گذارند، بتوانند یک تصویر system واحد را نیز به اشتراک بگذارند. برای خالی کردن لیست مجاز، هر ماژول موجود در لیست را به system_ext یا پارتیشن product منتقل کنید یا آنها را به فایل‌های system make اضافه کنید. این مرحله اختیاری است زیرا تعریف یک تصویر system مشترک برای فعال کردن اجرای رابط محصول لازم نیست. با این حال، خالی کردن لیست مجاز برای تعریف مرز system با system_ext مفید است.

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

در این مرحله، شما PRODUCT_PRODUCT_VNDK_VERSION := current را تنظیم می‌کنید، سپس به دنبال خطاهای ساخت و زمان اجرا می‌گردید و آنها را برطرف می‌کنید. برای بررسی بوت و لاگ‌های دستگاه و یافتن و رفع خطاهای لینک زمان اجرا:

  1. PRODUCT_PRODUCT_VNDK_VERSION := current تنظیم کنید.

  2. دستگاه را بسازید و به دنبال خطاهای ساخت بگردید. احتمالاً چند وقفه در ساخت برای انواع محصول یا انواع اصلی از دست رفته مشاهده خواهید کرد. وقفه‌های رایج عبارتند از:

    • هر ماژول hidl_interface که دارای product_specific: true باشد، برای ماژول‌های سیستم در دسترس نخواهد بود. برای رفع این مشکل، product_specific: true را با system_ext_specific: true جایگزین کنید.
    • ممکن است ماژول‌ها فاقد نوع محصول مورد نیاز برای ماژول‌های محصول باشند. برای رفع این مشکل، با تنظیم product_available: true ، آن ماژول را در دسترس پارتیشن product قرار دهید یا با تنظیم product_specific: true ، ماژول را به پارتیشن product منتقل کنید.
  3. خطاهای ساخت را برطرف کنید و از ساخت موفقیت‌آمیز دستگاه اطمینان حاصل کنید.

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

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

مرحله ۴: اعمال رابط‌های جاوا

در این مرحله، شما 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
    

مرحله ۵: بررسی رفتارهای زمان اجرا

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