يزيل نظام التشغيل Android 11 حِزم القسم product
، ما يجعله
مستقلاً عن القسمَين system
وvendor
. وفي إطار هذه التغييرات،
يمكنك الآن التحكّم في إمكانية وصول قسم product
إلى واجهات Java
المضمّنة وواجهات Java (وهو ما يشبه آلية فرض الواجهات على أقسام vendor
).
فرض استخدام الواجهات الأصلية
لتفعيل فرض استخدام الواجهة الأصلية، اضبط PRODUCT_PRODUCT_VNDK_VERSION
على current
. (يتم ضبط الإصدار تلقائيًا على current
عندما يكون مستوى shipping
API للهدف أكبر من 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 | الأسعار المتغيرة التي تم إنشاؤها | |
---|---|---|
قبل التنفيذ | بعد التنفيذ | |
تلقائي (بدون) | الأساسية
(تشمل /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
أخرى. تؤدي محاولة الربط بأي
وحدات أخرى غير هذه إلى أن يُنشئ نظام الإنشاء خطأً في التحقّق من نوع الرابط.
فرض وقت التشغيل
عند تفعيل فرض استخدام الواجهات الأصلية، لا تسمح إعدادات الرابط ل
رابط 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 | حدِّد ملف make الخاص بالنظام الذي يحدِّد الحِزم للقسيمة
system ، ثم اضبط عملية التحقّق من متطلبات مسار العناصر
في device.mk (لمنع تثبيت وحدات غير نظامية
على قسم system ). |
N |
2 | تنظيف القائمة المسموح بها | N |
3 | فرض الواجهات الأصلية وتحديد حالات تعذُّر ربط وقت التشغيل (يمكن تشغيله في وقت متزامن مع فرض Java) | Y |
4 | فرض واجهات Java والتحقّق من سلوك وقت التشغيل (يمكن تشغيله بشكل موازٍ مع فرض الإصدار الأصلي) | Y |
5 | التحقّق من سلوكيات وقت التشغيل | Y |
6 | تعديل device.mk مع فرض واجهة المنتج |
Y |
الخطوة 1: إنشاء ملف makefile وتفعيل التحقّق من مسار العنصر
في هذه الخطوة، يمكنك تحديد ملف الإنشاء 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
لمحة عن متطلبات مسار العنصر
عند ضبط PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
على true
أو strict
،
يمنع نظام الإنشاء الحِزم المحدّدة في ملفات makefile الأخرى من التثبيت في
المسارات المحدّدة في require-artifacts-in-path
ويمنع الحِزم
المحدّدة في ملف makefile الحالي من تثبيت العناصر خارج المسارات
المحدّدة في require-artifacts-in-path
.
في المثال أعلاه، عند ضبط PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
على
strict
، لا يمكن أن تتضمّن ملفات الإنشاء خارج oem_system.mk
وحدات تم تثبيتها في
القسم root
أو system
. لتضمين هذه الوحدات، عليك إما
تحديدها في ملف oem_system.mk
نفسه أو في ملف make مضمّن.
تؤدي محاولات تثبيت الوحدات في مسارات غير مسموح بها إلى حدوث أعطال في عملية الإنشاء. لحلّ مشكلة المقاطعات، نفِّذ أحد الإجراءات التالية:
الخيار 1: تضمين وحدة النظام في ملفات makefiles المضمّنة في
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
، يعني ذلك أنّ ملف make لا يتضمّن عنصرًا تابعًا (لم يتم تسجيله في وقت compiling). - للتحقّق من ذلك من نظام الإنشاء، أضِف المكتبة المطلوبة إلى الحقل
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 smaller 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