يمكنك استخدام تنسيق ملف APEX لتجميع و تثبيت وحدات نظام التشغيل Android ذات المستوى الأدنى. ويسمح ذلك بإنشاء وتثبيت المكوّنات بشكل مستقل، مثل الخدمات والمكتبات الأصلية وعمليات تنفيذ HAL والبرامج الثابتة وملفات الإعداد وما إلى ذلك.
تثبِّت نظام التصميم تلقائيًا ملفات APEX الخاصة بالمورّد في قسم /vendor ويتم تفعيلها في وقت التشغيل من خلال apexd تمامًا مثل ملفات APEX في الأقسام الأخرى.
حالات الاستخدام
تصميم صور المورّد بنظام الوحدات
تسهّل ملفات APEX عملية تجميع وتنظيم عمليات تنفيذ الميزات في صور المورّد بنظام الوحدات.
عند إنشاء صور المورّد كمجموعة من ملفات APEX الخاصة بالمورّد التي تم إنشاؤها بشكل مستقل، يمكن لمصنّعي الأجهزة اختيار عمليات التنفيذ المحدّدة للمورّد التي يريدونها على أجهزتهم بسهولة. يمكن للمصنّعين حتى إنشاء ملف APEX جديد للمورّد إذا لم يكن أي من ملفات APEX المقدّمة مناسبًا لاحتياجاتهم، أو إذا كان لديهم جهاز مخصّص جديد تمامًا.
على سبيل المثال، قد تختار شركة OEM تجميع جهازها باستخدام ملف APEX لتنفيذ شبكة Wi-Fi في AOSP، وملف APEX لتنفيذ البلوتوث في SoC، وملف APEX مخصّص لتنفيذ الاتصال الهاتفي من شركة OEM.
بدون ملفات APEX الخاصة بالمورّد، يتطلّب تنفيذ يتضمّن العديد من التبعيات بين مكوّنات المورّد تنسيقًا وتتبُّعًا دقيقَين. من خلال تجميع جميع المكوّنات (بما في ذلك ملفات الإعداد والمكتبات الإضافية) في ملفات APEX مع واجهات محدّدة بوضوح في أي نقطة من نقاط التواصل بين الميزات، تصبح المكوّنات المختلفة قابلة للتبديل.
تكرار عملية التطوير
تساعد ملفات APEX الخاصة بالمورّد المطوّرين على تكرار عملية التطوير بشكل أسرع أثناء تطوير وحدات المورّد من خلال تجميع عملية تنفيذ ميزة كاملة، مثل wifi HAL، داخل ملف APEX خاص بالمورّد. يمكن للمطوّرين بعد ذلك إنشاء ملف APEX الخاص بالمورّد ونقله بشكل فردي لاختبار التغييرات، بدلاً من إعادة إنشاء صورة المورّد بالكامل.
يؤدي ذلك إلى تبسيط وتسريع دورة تكرار عملية التطوير للمطوّرين الذين يعملون بشكل أساسي في مجال ميزة واحدة ويريدون تكرار عملية التطوير في هذا المجال فقط.
يؤدي التجميع الطبيعي لمجال ميزة في ملف APEX أيضًا إلى تبسيط عملية إنشاء التغييرات ونقلها واختبارها في مجال الميزة هذا. على سبيل المثال، تؤدي إعادة تثبيت ملف APEX إلى تعديل أي مكتبة أو ملفات إعداد مجمّعة يتضمّنها ملف APEX تلقائيًا.
يؤدي تجميع مجال ميزة في ملف APEX أيضًا إلى تبسيط عملية تصحيح الأخطاء أو الرجوع إلى الإصدار السابق عند ملاحظة سلوك غير جيد للجهاز. على سبيل المثال، إذا كان الاتصال الهاتفي يعمل بشكل سيئ في إصدار جديد، يمكن للمطوّرين محاولة تثبيت ملف APEX لإصدار أقدم من عملية تنفيذ الاتصال الهاتفي على جهاز (بدون الحاجة إلى تثبيت إصدار كامل) ومعرفة ما إذا تم استعادة السلوك الجيد.
مثال على سير العمل:
# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w
# Test the device.
... testing ...
# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...
# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...
أمثلة
القواعد الأساسية
يُرجى الاطّلاع على صفحة تنسيق ملف APEX الرئيسية للحصول على معلومات عامة عن ملفات APEX ، بما في ذلك متطلبات الجهاز وتفاصيل تنسيق الملف و خطوات التثبيت.
في Android.bp، يؤدي ضبط السمة vendor: true إلى تحويل وحدة APEX إلى ملف APEX خاص بالمورّد.
apex {
..
vendor: true,
..
}
الملفات الثنائية والمكتبات المشتركة
يتضمّن ملف APEX التبعيات المتعدية داخل حمولة ملف APEX ما لم تكن لها واجهات ثابتة.
تشمل الواجهات الأصلية الثابتة لتبعيات ملف APEX الخاص بالمورّد cc_library مع stubs ومكتبات LLNDK. يتم استبعاد هذه التبعيات من التجميع، ويتم تسجيل التبعيات في بيان ملف APEX. تتم معالجة البيان من خلال linkerconfig حتى تكون التبعيات الأصلية الخارجية متاحة في وقت التشغيل.
في المقتطف التالي، يحتوي ملف APEX على الملف الثنائي (my_service) وتبعياته غير الثابتة (*.so files).
apex {
..
vendor: true,
binaries: ["my_service"],
..
}
في المقتطف التالي، يحتوي ملف APEX على المكتبة المشتركة my_standalone_lib وأي من تبعياتها غير الثابتة (كما هو موضّح أعلاه).
apex {
..
vendor: true,
native_shared_libs: ["my_standalone_lib"],
..
}
تصغير حجم ملف APEX
قد يصبح ملف APEX أكبر حجمًا لأنه يجمع تبعيات غير ثابتة. ننصحك باستخدام الربط الثابت. يمكن ربط المكتبات الشائعة، مثل libc++.so وlibbase.so، بشكل ثابت بالملفات الثنائية HAL. يمكن أن يكون توفير واجهة ثابتة لتبعيات ملف APEX خيارًا آخر. لن يتم تجميع التبعية في ملف APEX.
عمليات تنفيذ HAL
لتحديد عملية تنفيذ HAL، يجب توفير الملفات الثنائية والمكتبات المقابلة داخل ملف APEX خاص بالمورّد على نحو مشابه للأمثلة التالية:
لتغليف عملية تنفيذ HAL بالكامل، يجب أن يحدّد ملف APEX أيضًا أي أجزاء VINTF ذات صلة ونصوص برمجية للتشغيل.
أجزاء VINTF
يمكن عرض أجزاء VINTF من ملف APEX خاص بالمورّد عندما تكون الأجزاء موجودة في etc/vintf من ملف APEX.
استخدِم السمة prebuilts لتضمين أجزاء VINTF في ملف APEX.
apex {
..
vendor: true,
prebuilts: ["fragment.xml"],
..
}
prebuilt_etc {
name: "fragment.xml",
src: "fragment.xml",
sub_dir: "vintf",
}
واجهات برمجة التطبيقات للاستعلام
عند إضافة أجزاء VINTF إلى ملف APEX، استخدِم واجهات برمجة التطبيقات libbinder_ndk للحصول على عمليات الربط بين واجهات HAL وأسماء ملفات APEX.
AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default"):trueإذا تم تحديد مثيل HAL في ملف APEX.AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...): تحصل على اسم ملف APEX الذي يحدّد مثيل HAL.AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...): استخدِم هذه الواجهة لفتح HAL من نوع passthrough.
نصوص برمجية للتشغيل
يمكن أن تتضمّن ملفات APEX نصوصًا برمجية للتشغيل بطريقتَين: (أ) ملف نصي تم إنشاؤه مسبقًا داخل حمولة ملف APEX، أو (ب) نص برمجي عادي للتشغيل في /vendor/etc. يمكنك ضبط كلتا الطريقتَين لملف APEX نفسه.
نص برمجي للتشغيل في ملف APEX:
prebuilt_etc {
name: "myinit.rc",
src: "myinit.rc"
}
apex {
..
vendor: true,
prebuilts: ["myinit.rc"],
..
}
يمكن أن تتضمّن نصوص التشغيل في ملفات APEX الخاصة بالمورّد service تعريفات و
on <property or event> توجيهات.
تأكَّد من أنّ تعريف service يشير إلى ملف ثنائي في ملف APEX نفسه.
على سبيل المثال، قد يحدّد ملف APEX باسم com.android.foo خدمة باسم foo-service.
on foo-service /apex/com.android.foo/bin/foo
...
يُرجى توخي الحذر عند استخدام توجيهات on. بما أنّه يتم تحليل نصوص التشغيل في ملفات APEX وتنفيذها بعد تفعيل ملفات APEX، لا يمكن استخدام بعض الأحداث أو السمات. استخدِم apex.all.ready=true لتفعيل الإجراءات في أقرب وقت ممكن.
يمكن أن تستخدم ملفات APEX للتشغيل on init، ولكن ليس
on early-init.
البرامج الثابتة
مثال:
يمكنك تضمين البرامج الثابتة في ملف APEX خاص بالمورّد باستخدام نوع وحدة prebuilt_firmware على النحو التالي.
prebuilt_firmware {
name: "my.bin",
src: "path_to_prebuilt_firmware",
vendor: true,
}
apex {
..
vendor: true,
prebuilts: ["my.bin"], // installed inside APEX as /etc/firmware/my.bin
..
}
يتم تثبيت وحدات prebuilt_firmware في دليل <apex name>/etc/firmware
الخاص بملف APEX. يفحص ueventd الأدلة /apex/*/etc/firmware للعثور على وحدات البرامج الثابتة.
يجب أن تصنّف file_contexts لملف APEX أي إدخالات لحمولة البرامج الثابتة بشكل صحيح لضمان إمكانية وصول ueventd إلى هذه الملفات في وقت التشغيل، وعادةً ما يكون التصنيف vendor_file كافيًا. على سبيل المثال:
(/.*)? u:object_r:vendor_file:s0
وحدات النواة
يمكنك تضمين وحدات النواة في ملف APEX خاص بالمورّد كوحدات تم إنشاؤها مسبقًا على النحو التالي.
prebuilt_etc {
name: "my.ko",
src: "my.ko",
vendor: true,
sub_dir: "modules"
}
apex {
..
vendor: true,
prebuilts: ["my.ko"], // installed inside APEX as /etc/modules/my.ko
..
}
يجب أن تصنّف file_contexts لملف APEX أي إدخالات لحمولة وحدة النواة بشكل صحيح. على سبيل المثال:
/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0
يجب تثبيت وحدات النواة بشكل صريح. يوضّح مثال نص التشغيل التالي في قسم المورّد عملية التثبيت من خلال insmod:
my_init.rc:
on early-boot
insmod /apex/myapex/etc/modules/my.ko
..
تراكبات الموارد في وقت التشغيل
مثال:
يمكنك تضمين تراكبات الموارد في وقت التشغيل في ملف APEX خاص بالمورّد
باستخدام السمة rros.
runtime_resource_overlay {
name: "my_rro",
soc_specific: true,
}
apex {
..
vendor: true,
rros: ["my_rro"], // installed inside APEX as /overlay/my_rro.apk
..
}
ملفات إعداد أخرى
تتوافق ملفات APEX الخاصة بالمورّد مع ملفات إعداد أخرى متنوعة توجد عادةً في قسم المورّد كملفات تم إنشاؤها مسبقًا داخل ملفات APEX الخاصة بالمورّد، ويتم إضافة المزيد منها.
أمثلة:
- ملفات XML لإعلان الميزات
- ملفات XML لميزة أدوات الاستشعار كـ ملفات تم إنشاؤها مسبقًا في ملف APEX خاص بالمورّد لـ Sensor HAL
- ملفات إعداد الإدخال
- إعدادات شاشة اللمس كـ ملفات تم إنشاؤها مسبقًا في ملف APEX خاص بالمورّد للإعدادات فقط
ملفات APEX الخاصة بالمورّد للتشغيل
يجب أن تتوفّر بعض خدمات HAL، مثل keymint، قبل تفعيل ملفات APEX. عادةً ما تضبط واجهات HAL هذه early_hal في تعريف الخدمة في نص التشغيل. مثال آخر هو فئة animation التي يتم تشغيلها عادةً قبل حدث post-fs-data. عند تجميع خدمة HAL مبكرة من هذا النوع في ملف APEX خاص بالمورّد، اضبط `apex "vendorBootstrap": true` في بيان ملف APEX
حتى يمكن تفعيله في وقت سابق. يُرجى العِلم أنّه لا يمكن تفعيل ملفات APEX للتشغيل إلا من الموقع الجغرافي الذي تم إنشاؤها فيه مسبقًا، مثل /vendor/apex، وليس من /data/apex.
سمات النظام
في ما يلي سمات النظام التي يقرأها الإطار لدعم ملفات APEX الخاصة بالمورّد:
input_device.config_file.apex=<apex name>: عند ضبط هذه السمة، يتم البحث عن ملفات إعداد الإدخال (*.idcو*.klو*.kcm) من دليل/etc/usrالخاص بملف APEX.ro.vulkan.apex=<apex name>: عند ضبط هذه السمة، يتم تحميل برنامج تشغيل Vulkan من ملف APEX. بما أنّ برامج تشغيل Vulkan تستخدمها واجهات HAL المبكرة، يجب تحويل ملف APEX إلى ملف APEX للتشغيل وجعل مساحة اسم الرابط هذه مرئية.
يمكنك ضبط سمات النظام في نصوص التشغيل باستخدام setprop
الأمر.
ميزات إضافية
اختيار ملف APEX عند بدء التشغيل
مثال:
يمكن تفعيل ملفات APEX الخاصة بالمورّد اختياريًا أثناء بدء التشغيل.
إذا حدّدت اسم ملف باستخدام سمة النظام
ro.vendor.apex.<apex name>، يتم تفعيل ملف APEX الذي يطابق اسم الملف فقط لـ
المحدّد <apex name>.
يتم تجاهل ملف APEX الذي يحمل الاسم <apex name> (لا يتم تفعيله) إذا تم ضبط سمة النظام هذه
على none. يمكنك استخدام هذه الميزة لتثبيت نُسخ متعددة من ملف APEX بالاسم نفسه. إذا كانت هناك إصدارات متعددة من ملف APEX نفسه، يجب أن تشترك في المفتاح نفسه.
أمثلة على حالات الاستخدام:
- تثبيت 3 إصدارات من ملف APEX الخاص بالمورّد لـ wifi HAL: يمكن لفِرق ضمان الجودة إجراء اختبار يدوي أو آلي باستخدام إصدار واحد، ثم إعادة التشغيل إلى إصدار آخر وإعادة إجراء الاختبارات، ثم مقارنة النتائج النهائية.
- تثبيت إصدارَين من ملف APEX الخاص بالمورّد لـ camera HAL، وهما current و experimental: يمكن للمستخدمين الذين يختبرون الإصدارات التجريبية استخدام الإصدار التجريبي بدون تنزيل ملف إضافي وتثبيته، ما يسهّل عليهم الرجوع إلى الإصدار السابق.
أثناء بدء التشغيل، يبحث apexd عن سمات النظام التي تتّبع تنسيقًا معيّنًا لتفعيل إصدار ملف APEX المناسب.
التنسيقات المتوقّعة لمفتاح السمة هي:
- إعدادات بدء التشغيل
- تُستخدَم لضبط القيمة التلقائية في
BoardConfig.mk. androidboot.vendor.apex.<apex name>
- تُستخدَم لضبط القيمة التلقائية في
- سمة نظام ثابتة
- تُستخدَم لتغيير القيمة التلقائية، ويتم ضبطها على جهاز تم تشغيله من قبل.
- تتجاوز قيمة إعدادات بدء التشغيل إذا كانت متوفّرة.
persist.vendor.apex.<apex name>
يجب أن تكون قيمة السمة هي اسم ملف APEX الذي يجب تفعيله، أو none لإيقاف ملف APEX.
// Default version.
apex {
name: "com.oem.camera.hal.my_apex_default",
vendor: true,
..
}
// Non-default version.
apex {
name: "com.oem.camera.hal.my_apex_experimental",
vendor: true,
..
}
يجب أيضًا ضبط الإصدار التلقائي باستخدام إعدادات بدء التشغيل في BoardConfig.mk:
# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default
بعد تشغيل الجهاز، يمكنك تغيير الإصدار المفعّل من خلال ضبط سمة النظام الثابتة:
$ adb root;
$ adb shell setprop \
persist.vendor.apex.com.oem.camera.hal \
com.oem.camera.hal.my_apex_experimental;
$ adb reboot;
إذا كان الجهاز يتيح تعديل إعدادات بدء التشغيل بعد التثبيت (مثل استخدام أوامر fastboot
oem)، يؤدي تغيير سمة إعدادات بدء التشغيل لملف APEX الذي تم تثبيته عدة مرات
إلى تغيير الإصدار المفعّل عند بدء التشغيل أيضًا.
بالنسبة إلى الأجهزة المرجعية الافتراضية المستندة إلى Cuttlefish،
يمكنك استخدام الأمر --extra_bootconfig_args لضبط سمة إعدادات بدء التشغيل
مباشرةً أثناء التشغيل. على سبيل المثال:
launch_cvd --noresume \
--extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";