APEX للمورّد

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

يتم تثبيت ملفات APK للمورّد من خلال نظام التصميم تلقائيًا في /vendor. ويتم تفعيلها في وقت التشغيل من خلال apexd تمامًا مثل حِزم APK في الأقسام.

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

تقسيم صور المورّدين إلى وحدات تنظيمية

تُسهل APEXT التجميع الطبيعي والتقسيم إلى وحدات للخصائص عمليات التنفيذ على صور البائعين.

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

على سبيل المثال، قد يختار المصنّع الأصلي للجهاز إنشاء جهازه باستخدام شبكة Wi-Fi التي تعمل بتقنية AOSP. وواجهة برمجة التطبيقات APEX وواجهة برمجة التطبيقات 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 ما لم تكن تحتوي على واجهات مستقرة.

تتضمن الواجهات الأصلية الثابتة لتبعيات APEX للمورِّدين cc_library مع stubs أو ndk_library أو llndk_library يتم استبعاد هذه التبعيات من والحزمة والتبعيات في بيان APEX. البيان هو تتم معالجتها بواسطة linkerconfig بحيث يتم التعامل مع التبعيات الأصلية الخارجية يكون متاحًا في وقت التشغيل

على عكس ملفات APEX في قسم /system، ترتبط عادةً ملفات APK للمورّدين بـ إصدار VNDK المحدد. تضمن مكتبات VNDK ثبات واجهة التطبيق الثنائية (ABI) ضمن إذًا، يمكننا التعامل مع مكتبات VNDK كثابتة وخفض حجم ملفات الموردين امتدادات البيانات عن طريق استبعادها من امتدادات الملف (APEX) باستخدام use_vndk_as_stable الموقع.

في المقتطف أدناه، سيحتوي ملف APEX على كل من البرنامج الثنائي (my_service) اعتمادياتها غير الثابتة (*.so ملف). لن يحتوي على مكتبات VNDK، حتى إذا تم إنشاء my_service باستخدام مكتبات VNDK مثل libbase. بدلاً من ذلك، في سيستخدم my_service بيئة التشغيل libbase من مكتبات VNDK التي يوفرها .

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

في المقتطف أدناه، سيحتوي ملف APEX على المكتبة المشتركة my_standalone_libوأي من تبعياتها غير الثابتة (كما هو موضح أعلاه).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

عمليات تنفيذ 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",
}

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

يمكن أن تتضمن ملفات 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 تعريف فقط. بدء النصوص البرمجية في واجهات برمجة التطبيقات (APEX) الخاصة بالمورّد، قد تحتوي أيضًا على أوامر on <property>.

لذا، يُرجى توخي الحذر عند استخدام توجيهات on. نظرًا لأن نصوص init في APEXs هي تحليلها وتنفيذها بعد تفعيل APEX، وبعض الأحداث أو السمات والاستخدام. يمكنك استخدام apex.all.ready=true لإطلاق الإجراءات في أقرب وقت ممكن.

البرامج الثابتة

مثال:

يمكنك تضمين البرامج الثابتة في 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

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

أمثلة:

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

اختيار ملف APEX عند التشغيل

مثال:

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

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

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

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

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

  • Bootconfig
    • يُستخدَم لضبط القيمة التلقائية في BoardConfig.mk.
    • androidboot.vendor.apex.<apex name>
  • تحليل النظام باستمرار
    • تُستخدَم لتغيير القيمة التلقائية التي يتم ضبطها على جهاز تم تشغيله من قبل.
    • تلغي هذه السياسة قيمة الضبط الأوّلي في حال توفّرها.
    • 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;

إذا كان الجهاز يتيح تحديث إعدادات التمهيد بعد وميض (مثلاً من خلال أوامر fastboot oem)، يجب تغيير سمة الضبط في التطبيقات المثبّتة على أجهزة متعددة يغيّر ملف 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";