APEX للمورّد

يمكنك استخدام تنسيق ملف APEX لتجميع تثبيت وحدات نظام تشغيل Android منخفضة المستوى. إنها تسمح بالبناء المستقل تثبيت المكونات مثل الخدمات والمكتبات الأصلية، وHAL وعمليات التنفيذ والبرامج الثابتة وملفات التهيئة، وما إلى ذلك

يُثبِّت نظام الإنشاء وحدات APEX الخاصة بالمورّدين تلقائيًا في القسم /vendor ويفعّلها apexd أثناء التشغيل تمامًا مثل وحدات APEX في الأقسام الأخرى.

حالات الاستخدام

تجميع صور المورّدين في وحدات

تسهِّل حِزم APEX تجميع عمليات تنفيذ الميزات وتصميمها بشكل طبيعي على صور المورّدين.

عندما يتم إنشاء صور البائع كمزيج من البائعين الذين تم إنشاؤهم بشكل مستقل لأجهزتهم الرئيسية، يمكن للشركات المصنّعة للأجهزة أن تختار بسهولة عمليات التنفيذ والتنفيذ المطلوبة على أجهزتهم. يمكن للشركات المصنّعة أيضًا إنشاء APEX للبائع الجديد في حالة عدم ملاءمة أي من الواجهات المقدمة لاحتياجاته، أو إذا كان لديه أجهزة مخصصة جديدة تمامًا.

على سبيل المثال، قد يختار المصنّع الأصلي للجهاز إنشاء جهازه باستخدام حِزمة APEX لتطبيق WiFi في AOSP وحِزمة APEX لتطبيق البلوتوث في شريحة المعالجة SoC وحِزمة APEX مخصّصة لتطبيق الهاتف في المصنّع الأصلي للجهاز.

بدون APEXT للبائع، فإن التنفيذ مع العديد من التبعيات بين مكونات البائعين تنسيقًا وتتبعًا دقيقين. من خلال التفاف الكل (بما في ذلك ملفات الإعداد والمكتبات الإضافية) في APEX مع واضحة ومحددة بوضوح في أي نقطة من مراحل الاتصال عبر الميزات، تصبح المكونات المختلفة قابلة للتبديل.

التكرار التحسيني للمطوّر

تساعد واجهات برمجة التطبيقات (APEX) للمورّدين في إصدار تطبيقاتهم بشكل أسرع وتطوير وحدات المورّدين من خلال تجميع تنفيذ ميزة بالكامل، مثل HAL wifi، داخل بائع ملف 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 للمورِّدين cc_library مع المكتبات stubs وLLNDK. ويتم استبعاد هذه التبعيات من عملية التجميع، ويتم تسجيل التبعيات في بيان APEX. تتم معالجة البيان من خلال linkerconfig لكي تكون التبعيات الأصلية الخارجية متوفرة أثناء التشغيل.

في المقتطف التالي، تحتوي APEX على كلٍ من البرنامج الثنائي (my_service) الاعتماديات غير الثابتة (*.so ملف).

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.

عمليات تنفيذ 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 للمرور.

النصوص البرمجية لبدء التشغيل

يمكن أن تتضمن ملفات APEX نصوصًا برمجية بطريقتين: (A) ملف نصي مُنشأ مسبقًا داخل حمولة APEX أو (B) نص برمجي init عادي في /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 نفسه. على سبيل المثال، يمكن أن تحدِّد com.android.foo APEX خدمة باسم foo-service.

on foo-service /apex/com.android.foo/bin/foo
  ...

لذا، يُرجى توخي الحذر عند استخدام توجيهات on. بما أنّ نصوص التشغيل المبدئي في وحدات APEX يتم تحليلها وتنفيذها بعد تفعيل وحدات APEX، لا يمكن استخدام بعض الأحداث أو السمات. استخدِم apex.all.ready=true لبدء الإجراءات في أقرب وقت ممكن. يمكن أن تستخدم عمليات Bootstrap 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

وحدات النواة

يمكنك تضمين وحدات kernel في 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

يجب تثبيت وحدات kernel بشكل صريح. المثال التالي init script في قسم المورّد، يتم التثبيت من خلال 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) للمورِّدين، وتُضاف المزيد منها.

أمثلة:

عناوين URL لبرنامج Bootstrap Vendor APEX

يجب أن تكون بعض خدمات HAL، مثل keymint، متاحة قبل تفعيل عناوين APEX. وعادةً ما تضبط واجهات HAL هذه القيمة early_hal في تعريف الخدمة في ملف برمجة بدء التشغيل . هناك مثال آخر وهو صف animation يبدأ عادةً. قبل حدث post-fs-data. عند تجميع خدمة HAL في مرحلة مبكرة في حزمة APEX الخاصة بالبائع، يجب ضبط القيمة "vendorBootstrap": true في بيان APEX ليكون بالإمكان تفعيلها في وقت أبكر. يُرجى العِلم أنّه لا يمكن سوى تفعيل نطاقات APEX لبدء التشغيل من الموقع الجغرافي المُنشئ مسبقًا، مثل /vendor/apex، وليس من /data/apex.

خصائص النظام

في ما يلي خصائص النظام التي يقرأها إطار العمل لدعم المورِّد. الأهداف:

  • input_device.config_file.apex=<apex name> - عند الضبط، يتمّ إدخال الإدخال يتم البحث في ملفات الإعداد (*.idc و*.kl و*.kcm) من الدليل /etc/usr الخاص بـ APEX.
  • ro.vulkan.apex=<apex name>: عند ضبط هذا الخيار، يتم تحميل برنامج تشغيل Vulkan من APEX. نظرًا لاستخدام سائق Vulkan من قِبل HALs في البداية، اجعل APEX شغِّل APEX واضبط مساحة اسم رابط هذه. مرئية.

اضبط خصائص النظام في نصوص التشغيل باستخدام الأمر setprop .

ميزات تطوير إضافية

اختيار APEX عند بدء التشغيل

مثال:

يمكن للمطوّرين أيضًا تثبيت إصدارات متعددة من واجهات برمجة التطبيقات (APEX) الخاصة بالمورّدين التي تشترك في نفس اسم ومفتاح APEX، ثم اختيار الإصدار الذي يتم تفعيله خلال كل منها بدء التشغيل باستخدام حزمات النظم الثابتة. وبالنسبة إلى بعض حالات الاستخدام المتاحة لمطوّري البرامج، قد يكون ذلك أقل من تثبيت نسخة جديدة من ملف APEX باستخدام "adb install".

أمثلة على حالات الاستخدام:

  • تثبيت 3 إصدارات من حزمة APEX الخاصة بمورّد HAL لشبكة Wi-Fi: يمكن لفِرق ضمان الجودة إجراء اختبار يدوي أو آلي باستخدام إصدار واحد، ثم إعادة التشغيل إلى إصدار آخر و إعادة إجراء الاختبارات، ثم مقارنة النتائج النهائية.
  • تثبيت إصدارين من APEX لمورِّد HAL للكاميرا، الحالي تجريبي: يمكن للمستخدمين التجريبيين استخدام الإصدار التجريبي بدون تنزيل ملف إضافي وتثبيته، حتى يمكنهم التبديل مرة أخرى بسهولة.

أثناء تشغيل الجهاز، يبحث apexd عن دعائم النظام التي تتبع تنسيقًا محددًا تفعيل إصدار APEX الصحيح.

التنسيقات المتوقّعة لمفتاح السمة هي:

  • Bootconfig
    • تُستخدَم لضبط القيمة التلقائية، في BoardConfig.mk.
    • androidboot.vendor.apex.<apex name>
  • السمة sysprop الثابتة
    • تُستخدَم لتغيير القيمة التلقائية التي يتم ضبطها على جهاز تم تشغيله من قبل.
    • تلغي هذه السياسة قيمة الضبط الأوّلي في حال توفّرها.
    • persist.vendor.apex.<apex name>

يجب أن تكون قيمة السمة هي اسم ملف 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,
  ..
}

يجب أيضًا ضبط الإصدار التلقائي باستخدام bootconfig في 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;

إذا كان الجهاز يتيح تعديل bootconfig بعد الفلاش (مثلاً من خلال أوامر fastboot oem)، يؤدي تغيير سمة bootconfig لملف APEX المثبَّت بشكل متعدّد أيضًا إلى تغيير الإصدار الذي يتم تفعيله عند بدء التشغيل.

بالنسبة إلى الأجهزة المرجعية الافتراضية المستندة إلى حبَّار، يمكنك استخدام الأمر --extra_bootconfig_args لضبط خاصية Bootconfig مباشرةً أثناء إطلاقه. مثلاً:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";