اجرای رابط‌های بخش محصول

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

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

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

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

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

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

در Android 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)
core
(شامل /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 پیوند داده شود. تلاش برای پیوند دادن به هر مدول دیگری غیراز این‌ها باعث می‌شود سیستم ساخت خطای بررسی نوع پیوند تولید کند.

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

وقتی اجرای واسط بومی فعال باشد، پیکربندی پیونددهنده برای پیونددهنده bionic به فرایندهای سیستم اجازه نمی‌دهد از کتابخانه‌های product استفاده کنند، و بخش product را برای فرایندهای product ایجاد می‌کند که نمی‌توانند به کتابخانه‌های خارج از پارتیشن product پیوند دهند (بااین‌حال، چنین فرایندهایی می‌توانند به کتابخانه‌های VNDK پیوند دهند). تلاش برای نقض پیکربندی پیوند زمان اجرا باعث می‌شود فرایند ناموفق باشد و پیام خطای CANNOT LINK EXECUTABLE تولید شود.

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

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

API /system /system_ext /product /vendor /data
میانای برنامه‌سازی کاربردی عمومی
‎@SystemApi
@hide API

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

اجرای زمان ساخت

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

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

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

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

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

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

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

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

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

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

  • گزینه ۱: واحد سیستم را در فایل‌های ساخت موجود در oem_system.mk بگنجانید. This makes it so the artifact path requirement is met (as the modules now exist in an included makefile) and thus allows installation to the set of paths in `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 فایل بسازید اضافه کنید. این مرحله اختیاری است زیرا تعریف تصویر 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 را نشان دهد، فایل ساخت فاقد وابستگی است (و در زمان ساخت ضبط نشده است).
    • برای بررسی آن از سیستم ساخت، کتابخانه موردنیاز را به فیلد shared_libs: یا required: اضافه کنید.
  5. بااستفاده از راهنمایی‌های ارائه‌شده در بالا، وابستگی‌های ازدست‌رفته را برطرف کنید.

مرحله ۴: اعمال کردن میاناهای Java

در این مرحله، 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 پنهان است. برای رفع این مشکل، از میانای برنامه‌سازی کاربردی نمایان (غیرپنهان) استفاده کنید یا جایگزینی پیدا کنید. خطای نمونه:

    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 مراجعه کنید.

مرحله ۶: به‌روزرسانی device.mk

پس‌از رفع همه خطاهای ساخت و زمان اجرا، و درستی‌سنجی اینکه عملکردهای زمان اجرا همان‌طور که انتظار می‌رود هستند، موارد زیر را در device.mk تنظیم کنید:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true