يزيل نظام التشغيل Android 11 حزمة القسم product
، ما يجعله مستقلاً عن القسمَين system
وvendor
. في إطار هذه التغييرات، يمكنك الآن التحكّم في إذن وصول قسم product
إلى الواجهات الأصلية وواجهات Java (وهو ما يشبه طريقة عمل فرض الواجهة لأقسام vendor
).
فرض استخدام الواجهات الأصلية
لتفعيل فرض استخدام الواجهة الأصلية، اضبط قيمة PRODUCT_PRODUCT_VNDK_VERSION
على current
. (يتم ضبط الإصدار تلقائيًا على current
عندما يكون مستوى واجهة برمجة التطبيقات للشحن المستهدف أكبر من 29). تتيح ميزة "فرض القيود" ما يلي:
- الوحدات الأصلية في القسم
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 | الخيارات التي تم إنشاؤها | |
---|---|---|
قبل التنفيذ | بعد التنفيذ | |
تلقائي (بلا) | core
(يتضمّن /system و/system_ext و/product ) |
الأساسية
(تشمل /system و/system_ext ولكن ليس
/product ) |
system_ext_specific: true |
أساسي | أساسي |
product_specific: true |
أساسي | المنتج |
vendor: true |
المُورِّد | المُورِّد |
vendor_available: true |
core, vendor | core, vendor |
product_available: true |
لا ينطبق | المنتج الأساسي |
vendor_available: true وproduct_available:
true |
لا ينطبق | الأساسية والمنتج والبائع |
system_ext_specific: true وvendor_available:
true |
core, vendor | core, vendor |
product_specific: true وvendor_available:
true |
core, vendor | المنتج، البائع |
فرض مدة التصميم (Android.mk)
عند تفعيل فرض استخدام الواجهة الأصلية، يكون للوحدات الأصلية المثبَّتة في القسم product
نوع رابط native:product
يمكنه الربط فقط بوحدات native:product
أو native:vndk
أخرى. سيؤدي محاولة الربط بأي وحدات أخرى إلى أن ينشئ نظام الإنشاء خطأ في التحقّق من نوع الرابط.
فرض القيود أثناء التشغيل
عند تفعيل فرض استخدام الواجهة الأصلية، لا يسمح إعداد الرابط لبرنامج الربط bionic لعمليات النظام باستخدام مكتبات product
، ما يؤدي إلى إنشاء قسم product
لعمليات product
التي لا يمكنها الربط بمكتبات خارج قسم product
(ومع ذلك، يمكن لهذه العمليات الربط بمكتبات VNDK). تؤدي محاولات انتهاك إعدادات رابط وقت التشغيل إلى تعذُّر تنفيذ العملية وإنشاء رسالة خطأ CANNOT LINK EXECUTABLE
.
فرض استخدام واجهات Java
لتفعيل فرض استخدام واجهة Java، اضبط
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
على true
. (يتم ضبط القيمة تلقائيًا على true
عندما يكون مستوى واجهة برمجة التطبيقات للشحن المستهدَف أكبر من 29). عند تفعيل خيار فرض القيود، يمكن السماح بالوصول إلى ما يلي أو حظره:
واجهة برمجة التطبيقات | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
واجهة برمجة التطبيقات العامة | |||||
@SystemApi | |||||
@hide API |
كما هو الحال في القسم vendor
، لا يُسمح لتطبيق أو مكتبة Java في القسم product
باستخدام سوى واجهات برمجة التطبيقات العامة وتلك الخاصة بالنظام، ولا يُسمح بالربط بمكتبة تستخدم واجهات برمجة تطبيقات مخفية. يشمل هذا القيد الربط في وقت الإنشاء والانعكاس في وقت التشغيل.
فرض مدة التصميم
أثناء وقت الإنشاء، تتحقّق أداتا Make وSoong من أنّ وحدات Java النمطية في القسم product
لا تستخدم واجهات برمجة تطبيقات مخفية من خلال التحقّق من الحقلَين platform_apis
وsdk_version
. يجب ملء sdk_version
للتطبيقات في القسم product
بالقيمة current
أو system_current
أو الإصدار الرقمي من واجهة برمجة التطبيقات، ويجب أن يكون الحقل platform_apis
فارغًا.
فرض القيود أثناء التشغيل
يتحقّق وقت تشغيل Android من أنّ التطبيقات في قسم product
لا تستخدم واجهات برمجة تطبيقات مخفية، بما في ذلك الانعكاس. لمزيد من التفاصيل، يُرجى الرجوع إلى القيود المفروضة على واجهات برمجة التطبيقات غير التابعة للحزمة SDK.
تفعيل فرض استخدام واجهة المنتج
اتّبِع الخطوات الواردة في هذا القسم لتفعيل فرض استخدام واجهة المنتج.
الخطوة | المهمة | مطلوب |
---|---|---|
1 | حدِّد ملف makefile الخاص بالنظام والذي يحدِّد حِزم
قسم system ، ثم اضبط عملية التحقّق من متطلبات مسار العناصر في
device.mk (لمنع تثبيت الوحدات غير التابعة للنظام في
قسم system ). |
N |
2 | تنظيف القائمة المسموح بها | N |
3 | فرض استخدام الواجهات الأصلية وتحديد أخطاء الربط في وقت التشغيل (يمكن تشغيلها بالتوازي مع فرض استخدام Java). | Y |
4 | فرض استخدام واجهات Java والتحقّق من سلوك وقت التشغيل (يمكن تشغيلها بالتوازي مع عملية الفرض الأصلية) | Y |
5 | التحقّق من سلوكيات وقت التشغيل | Y |
6 | تعديل device.mk من خلال فرض استخدام واجهة المنتج |
Y |
الخطوة 1: إنشاء ملف makefile وتفعيل خيار التحقّق من مسار العنصر
في هذه الخطوة، عليك تحديد system
makefile.
أنشِئ ملف 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
لمحة عن متطلبات مسار العنصر
عند ضبط 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 مضمّن.
تتسبّب محاولات تثبيت الوحدات في مسارات غير مسموح بها في حدوث أخطاء في الإنشاء. لحلّ
مشاكل التقطّع، يُرجى اتّخاذ أحد الإجراءات التالية:
الخيار 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
، ثم البحث عن أخطاء في الإنشاء ووقت التشغيل وحلّها. للتحقّق من عملية تشغيل الجهاز والسجلات
والعثور على أخطاء الربط في وقت التشغيل وإصلاحها، اتّبِع الخطوات التالية:
اضبط
PRODUCT_PRODUCT_VNDK_VERSION := current
.أنشئ الجهاز وابحث عن أخطاء في عملية الإنشاء. من المحتمل أن تظهر بعض الأخطاء في عملية الإنشاء بسبب عدم توفّر خيارات المنتج أو الخيارات الأساسية. تشمل الفواصل الشائعة ما يلي:
- لن تكون أي وحدة
hidl_interface
تتضمّنproduct_specific: true
متاحة لوحدات النظام. لحلّ هذه المشكلة، استبدِلproduct_specific: true
بـsystem_ext_specific: true
. - قد لا تتضمّن الوحدات خيار المنتج المطلوب لوحدات المنتج. لحلّ هذه المشكلة، يجب إتاحة الوحدة النمطية لقسم
product
من خلال ضبطproduct_available: true
أو نقل الوحدة النمطية إلى قسمproduct
من خلال ضبطproduct_specific: true
.
- لن تكون أي وحدة
حلّ أخطاء الإنشاء والتأكّد من إنشاء الجهاز بنجاح
تثبيت الصورة والبحث عن أخطاء وقت التشغيل في عملية تشغيل الجهاز وسجلاته
- إذا كانت العلامة
linker
من سجلّ حالة الاختبار تعرض الرسالةCANNOT LINK EXECUTABLE
، يعني ذلك أنّ ملف الإنشاء يفتقد إلى عنصر تابع (ولم يتم تسجيله في وقت الإنشاء). - للتحقّق من ذلك من نظام الإنشاء، أضِف المكتبة المطلوبة إلى الحقل
shared_libs:
أوrequired:
.
- إذا كانت العلامة
حلّ المشكلة المتعلقة بالموارد الاعتمادية غير المثبَّتة باستخدام الإرشادات الواردة أعلاه
الخطوة 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 sma
ller API set than the source.أخطاء الرموز يشير هذا الخطأ إلى تعذُّر العثور على رمز لأنّه مضمّن في واجهة برمجة تطبيقات مخفية. لحلّ هذه المشكلة، استخدِم واجهة برمجة تطبيقات مرئية (غير مخفية) أو ابحث عن بديل. مثال على الخطأ:
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
(الذي ينشئ سجلّاً عندما يستخدم التطبيق واجهة برمجة تطبيقات مخفية). بدلاً من ذلك، يمكنك استخدام أداة التحليل الثابت 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