اندروید 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
پیوند بزنند. تلاش برای پیوند دادن به هر ماژول دیگری غیر از اینها باعث می شود که سیستم ساخت یک خطای بررسی نوع پیوند ایجاد کند.
اجرای زمان اجرا
When native interface enforcement is enabled, the linker configuration for the bionic linker doesn't allow system processes to use product
libraries, creating a product
section for the product
processes that can't link to libraries outside the product
partition (however, such processes can پیوند به کتابخانه های VNDK). تلاش برای نقض پیکربندی پیوند زمان اجرا باعث می شود که فرآیند با شکست مواجه شود و پیام خطای CANNOT LINK EXECUTABLE
ایجاد شود.
واسط های جاوا را اجرا کنید
برای فعال کردن اجرای رابط جاوا، PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
را روی true
تنظیم کنید. (وقتی سطح API ارسال برای هدف بیشتر از 29 باشد، مقدار به طور خودکار روی true
تنظیم میشود.) هنگامی که فعال باشد، اعمال دسترسی زیر را مجاز یا غیرمجاز میکند:
API | /سیستم | /system_ext | /محصول | /فروشنده | /داده |
---|---|---|---|---|---|
API عمومی | |||||
@SystemApi | |||||
@hide API |
As in the vendor
partition, an app or a Java library in the product
partition is allowed to use only public and system APIs; پیوند دادن به کتابخانه ای که از API های پنهان استفاده می کند مجاز نیست. این محدودیت شامل پیوند در زمان ساخت و بازتاب در زمان اجرا می شود.
اجرای زمان را بسازید
در زمان ساخت، Make و Soong با بررسی فیلدهای platform_apis
و sdk_version
تأیید میکنند که ماژولهای جاوا در پارتیشن product
از APIهای پنهان استفاده نمیکنند. sdk_version
برنامهها در پارتیشن product
باید با نسخه current
، system_current
یا عددی API پر شود و قسمت platform_apis
باید خالی باشد.
اجرای زمان اجرا
The Android runtime verifies that apps in the product
partition don't use hidden APIs, including reflection. برای جزئیات، به محدودیتهای رابطهای غیر SDK مراجعه کنید.
اجرای رابط محصول را فعال کنید
از مراحل این بخش برای فعال کردن اجرای رابط محصول استفاده کنید.
مرحله | وظیفه | مورد نیاز |
---|---|---|
1 | فایل سازنده سیستم خود را تعریف کنید که بستههای مربوط به پارتیشن system را مشخص میکند، سپس بررسی مورد نیاز مسیر مصنوعات را در device.mk تنظیم کنید (برای جلوگیری از نصب ماژولهای غیر سیستمی در پارتیشن system ). | ن |
2 | لیست مجاز را پاک کنید. | ن |
3 | واسط های بومی را اجرا کنید و خرابی های لینک زمان اجرا را شناسایی کنید (می تواند به موازات اجرای جاوا اجرا شود). | Y |
4 | رابط های جاوا را اجرا کنید و رفتار زمان اجرا را تأیید کنید (می تواند به موازات اجرای بومی اجرا شود). | Y |
5 | رفتارهای زمان اجرا را بررسی کنید. | Y |
6 | به روز رسانی device.mk با اجرای رابط محصول. | Y |
مرحله 1: ایجاد فایل ایجاد کنید و بررسی مسیر مصنوع را فعال کنید
در این مرحله میک فایل system
را تعریف می کنید.
یک 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),)
در فایل
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
درباره الزامات مسیر مصنوع
When PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
is set to true
or strict
, the build system prevents packages defined in other makefiles from installing to the paths defined in require-artifacts-in-path
and prevents packages defined in the current makefile from installing artifacts outside the paths defined in 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
را تنظیم کرده، سپس به دنبال خطاهای ساخت و زمان اجرا بگردید و آنها را برطرف کنید. برای بررسی بوت و لاگ های دستگاه و یافتن و رفع خرابی لینک های زمان اجرا:
PRODUCT_PRODUCT_VNDK_VERSION := current
را تنظیم کنید.دستگاه را بسازید و به دنبال خطاهای ساخت بگردید. احتمالاً برای انواع محصول یا انواع اصلی، چند وقفه ساخت مشاهده خواهید کرد. استراحت های رایج عبارتند از:
- هر ماژول
hidl_interface
که دارایproduct_specific: true
باشد برای ماژول های سیستم در دسترس نخواهد بود. برای رفع مشکل،product_specific: true
را باsystem_ext_specific: true
جایگزین کنید. - ممکن است ماژولها نوع محصول مورد نیاز برای ماژولهای محصول را نداشته باشند. برای رفع مشکل، آن ماژول را با تنظیم
product_available: true
در دسترس پارتیشنproduct
قرار دهید یا با تنظیمproduct_specific: true
ماژول را به پارتیشنproduct
منتقل کنید.
- هر ماژول
خطاهای ساخت را برطرف کنید و اطمینان حاصل کنید که دستگاه با موفقیت ساخته می شود.
تصویر را فلش کنید و به دنبال خطاهای زمان اجرا در بوت دستگاه و لاگ ها بگردید.
- اگر تگ
linker
از گزارش مورد آزمایشی پیامCANNOT LINK EXECUTABLE
را نشان دهد، فایل make وابستگی ندارد (و در زمان ساخت ضبط نشده است). - برای بررسی آن از سیستم ساخت، کتابخانه مورد نیاز را به قسمت
shared_libs:
یاrequired:
اضافه کنید.
- اگر تگ
وابستگی های از دست رفته را با استفاده از راهنمایی ارائه شده در بالا حل کنید.
مرحله 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 پنهان را با استفاده از گزارش ثبت کنید. Alternatively, you can use the veridex static analysis tool to get the type of usage (linking or reflection), restriction level, and call stack.
نحو 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