فروشنده APEX

می توانید از فرمت فایل APEX برای بسته بندی و نصب ماژول های سطح پایین سیستم عامل اندروید استفاده کنید. این امکان ساخت و نصب مستقل اجزایی مانند خدمات و کتابخانه های بومی، پیاده سازی HAL، سیستم عامل، فایل های پیکربندی و غیره را فراهم می کند.

APEX های فروشنده توسط سیستم ساخت به طور خودکار در پارتیشن /vendor نصب می شوند و در زمان اجرا توسط apexd فعال می شوند درست مانند APEX ها در سایر پارتیشن ها.

موارد استفاده کنید

مدولار کردن تصاویر فروشنده

APEX ها یک بسته بندی طبیعی و مدولارسازی پیاده سازی ویژگی ها در تصاویر فروشنده را تسهیل می کنند.

هنگامی که تصاویر فروشنده به عنوان ترکیبی از APEXهای فروشنده مستقل ساخته می شوند، سازندگان دستگاه می توانند به راحتی پیاده سازی های فروشنده خاصی را که در دستگاه خود می خواهند انتخاب و انتخاب کنند. حتی اگر هیچ یک از APEX های ارائه شده مطابق با نیاز آنها نباشد، یا سخت افزار سفارشی کاملاً جدیدی داشته باشند، حتی می توانند یک APEX فروشنده جدید ایجاد کنند.

به عنوان مثال، یک OEM ممکن است تصمیم بگیرد دستگاه خود را با اجرای وای فای AOSP APEX، APEX اجرای بلوتوث SoC و APEX پیاده سازی تلفنی OEM سفارشی بسازد.

بدون APEX های فروشنده، پیاده سازی با وابستگی های بسیار بین اجزای فروشنده نیاز به هماهنگی و ردیابی دقیق دارد. با قرار دادن تمام مؤلفه ها (از جمله فایل های پیکربندی و کتابخانه های اضافی) در APEX با رابط های واضح تعریف شده در هر نقطه از ارتباط بین ویژگی ها، اجزای مختلف قابل تعویض می شوند.

تکرار توسعه دهنده

APEXهای فروشنده به توسعه‌دهندگان کمک می‌کنند در حین توسعه ماژول‌های فروشنده، با یکپارچه‌سازی اجرای کامل ویژگی، مانند 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 ، ndk_library ، یا llndk_library . این وابستگی ها از بسته بندی حذف می شوند و وابستگی ها در مانیفست APEX ثبت می شوند. مانیفست توسط linkerconfig پردازش می‌شود تا وابستگی‌های بومی خارجی در زمان اجرا در دسترس باشند.

برخلاف APEX ها در پارتیشن /system ، APEX های فروشنده معمولاً به یک نسخه VNDK خاص گره خورده اند. کتابخانه‌های VNDK پایداری ABI را در نسخه تضمین می‌کنند، بنابراین می‌توانیم کتابخانه‌های VNDK را به‌عنوان پایدار در نظر بگیریم و با استفاده از ویژگی use_vndk_as_stable ، اندازه APEXهای فروشنده را با حذف آنها از APEXها کاهش دهیم.

در قطعه زیر، 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 مربوطه و اسکریپت‌های init را نیز مشخص کند.

قطعات VINTF

وقتی قطعات در etc/vintf APEX قرار دارند، قطعات VINTF را می توان از یک APEX فروشنده ارائه کرد.

از ویژگی prebuilts برای جاسازی قطعات VINTF در APEX استفاده کنید.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

اسکریپت های Init

APEX ها می توانند اسکریپت های init را به دو صورت شامل شوند: (الف) یک فایل متنی از پیش ساخته شده در APEX payload، یا (ب) یک اسکریپت init معمولی در /vendor/etc . می توانید هر دو را برای یک APEX تنظیم کنید.

شروع اسکریپت در APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

اسکریپت های Init در APEX ها فقط می توانند تعاریف service داشته باشند. اسکریپت‌های Init در Vendor APEXها می‌توانند دستورالعمل‌های on <property> نیز داشته باشند.

هنگام استفاده on دستورالعمل ها مراقب باشید. از آنجایی که اسکریپت های init در APEX ها پس از فعال شدن 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 در پارتیشن فروشنده، نصب از طریق insmod را نشان می دهد:

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

همپوشانی منابع زمان اجرا

مثال:

با استفاده از ویژگی rros پوشش‌های منابع زمان اجرا را در APEX فروشنده جاسازی کنید.

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 در هنگام راه اندازی

مثال:

توسعه‌دهندگان همچنین می‌توانند چندین نسخه از APEXهای فروشنده را نصب کنند که نام و کلید APEX یکسانی دارند، و سپس انتخاب کنند که کدام نسخه در طول هر بار راه‌اندازی با استفاده از sysprops دائمی فعال شود. برای برخی موارد استفاده از توسعه دهندگان، این ممکن است ساده تر از نصب یک نسخه جدید از APEX با استفاده از adb install باشد.

موارد استفاده مثال:

  • نصب 3 نسخه از APEX فروشنده وای فای HAL: تیم‌های QA می‌توانند آزمایش دستی یا خودکار را با استفاده از یک نسخه انجام دهند، سپس در نسخه دیگری راه‌اندازی مجدد کنند و آزمایش‌ها را دوباره اجرا کنند، سپس نتایج نهایی را مقایسه کنند.
  • نصب 2 نسخه از دوربین HAL فروشنده APEX، فعلی و آزمایشی : Dogfooders می‌توانند از نسخه آزمایشی بدون دانلود و نصب فایل اضافی استفاده کنند، بنابراین می‌توانند به راحتی آن را تعویض کنند.

در طول راه‌اندازی، apexd به دنبال sysprops با فرمت خاصی می‌گردد تا نسخه مناسب APEX را فعال کند.

فرمت های مورد انتظار برای کلید ویژگی عبارتند از:

  • بوت کانفیگ
    • برای تنظیم مقدار پیش فرض در BoardConfig.mk استفاده می شود.
    • androidboot.vendor.apex.<apex name>
  • سیسپروپ ماندگار
    • برای تغییر مقدار پیش‌فرض استفاده می‌شود که روی دستگاهی که از قبل راه‌اندازی شده تنظیم شده است.
    • در صورت وجود، مقدار bootconfig را لغو می کند.
    • 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

پس از بوت شدن دستگاه، نسخه فعال شده را با تنظیم sysprop دائمی تغییر دهید:

$ 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 چند نصب‌شده، نسخه فعال‌شده در راه‌اندازی نیز تغییر می‌کند.

برای دستگاه‌های مرجع مجازی مبتنی بر Cuttlefish ، می‌توانید از دستور --extra_bootconfig_args برای تنظیم مستقیم ویژگی bootconfig هنگام راه‌اندازی استفاده کنید. مثلا:

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

می توانید از فرمت فایل APEX برای بسته بندی و نصب ماژول های سطح پایین سیستم عامل اندروید استفاده کنید. این امکان ساخت و نصب مستقل اجزایی مانند خدمات و کتابخانه های بومی، پیاده سازی HAL، سیستم عامل، فایل های پیکربندی و غیره را فراهم می کند.

APEX های فروشنده توسط سیستم ساخت به طور خودکار در پارتیشن /vendor نصب می شوند و در زمان اجرا توسط apexd فعال می شوند درست مانند APEX ها در سایر پارتیشن ها.

موارد استفاده کنید

مدولار کردن تصاویر فروشنده

APEX ها یک بسته بندی طبیعی و مدولارسازی پیاده سازی ویژگی ها در تصاویر فروشنده را تسهیل می کنند.

هنگامی که تصاویر فروشنده به عنوان ترکیبی از APEXهای فروشنده مستقل ساخته می شوند، سازندگان دستگاه می توانند به راحتی پیاده سازی های فروشنده خاصی را که در دستگاه خود می خواهند انتخاب و انتخاب کنند. حتی اگر هیچ یک از APEX های ارائه شده مطابق با نیاز آنها نباشد، یا سخت افزار سفارشی کاملاً جدیدی داشته باشند، حتی می توانند یک APEX فروشنده جدید ایجاد کنند.

به عنوان مثال، یک OEM ممکن است تصمیم بگیرد دستگاه خود را با اجرای وای فای AOSP APEX، APEX اجرای بلوتوث SoC و APEX پیاده سازی تلفنی OEM سفارشی بسازد.

بدون APEX های فروشنده، پیاده سازی با وابستگی های بسیار بین اجزای فروشنده نیاز به هماهنگی و ردیابی دقیق دارد. با قرار دادن تمام مؤلفه ها (از جمله فایل های پیکربندی و کتابخانه های اضافی) در APEX با رابط های واضح تعریف شده در هر نقطه از ارتباط بین ویژگی ها، اجزای مختلف قابل تعویض می شوند.

تکرار توسعه دهنده

APEXهای فروشنده به توسعه‌دهندگان کمک می‌کنند در حین توسعه ماژول‌های فروشنده، با یکپارچه‌سازی اجرای کامل ویژگی، مانند 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 ، ndk_library ، یا llndk_library . این وابستگی ها از بسته بندی حذف می شوند و وابستگی ها در مانیفست APEX ثبت می شوند. مانیفست توسط linkerconfig پردازش می‌شود تا وابستگی‌های بومی خارجی در زمان اجرا در دسترس باشند.

برخلاف APEX ها در پارتیشن /system ، APEX های فروشنده معمولاً به یک نسخه VNDK خاص گره خورده اند. کتابخانه‌های VNDK پایداری ABI را در نسخه تضمین می‌کنند، بنابراین می‌توانیم کتابخانه‌های VNDK را به‌عنوان پایدار در نظر بگیریم و با استفاده از ویژگی use_vndk_as_stable ، اندازه APEXهای فروشنده را با حذف آنها از APEXها کاهش دهیم.

در قطعه زیر، 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 مربوطه و اسکریپت‌های init را نیز مشخص کند.

قطعات VINTF

وقتی قطعات در etc/vintf APEX قرار دارند، قطعات VINTF را می توان از یک APEX فروشنده ارائه کرد.

از ویژگی prebuilts برای جاسازی قطعات VINTF در APEX استفاده کنید.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

اسکریپت های Init

APEX ها می توانند اسکریپت های init را به دو صورت شامل شوند: (الف) یک فایل متنی از پیش ساخته شده در APEX payload، یا (ب) یک اسکریپت init معمولی در /vendor/etc . می توانید هر دو را برای یک APEX تنظیم کنید.

شروع اسکریپت در APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

اسکریپت های Init در APEX ها فقط می توانند تعاریف service داشته باشند. اسکریپت‌های Init در Vendor APEXها می‌توانند دستورالعمل‌های on <property> نیز داشته باشند.

هنگام استفاده on دستورالعمل ها مراقب باشید. از آنجایی که اسکریپت های init در APEX ها پس از فعال شدن 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 در پارتیشن فروشنده، نصب از طریق insmod را نشان می دهد:

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

همپوشانی منابع زمان اجرا

مثال:

با استفاده از ویژگی rros پوشش‌های منابع زمان اجرا را در APEX فروشنده جاسازی کنید.

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 در هنگام راه اندازی

مثال:

توسعه‌دهندگان همچنین می‌توانند چندین نسخه از APEXهای فروشنده را نصب کنند که نام و کلید APEX یکسانی دارند، و سپس انتخاب کنند که کدام نسخه در طول هر بار راه‌اندازی با استفاده از sysprops دائمی فعال شود. برای برخی موارد استفاده از توسعه دهندگان، این ممکن است ساده تر از نصب یک نسخه جدید از APEX با استفاده از adb install باشد.

موارد استفاده مثال:

  • نصب 3 نسخه از APEX فروشنده وای فای HAL: تیم‌های QA می‌توانند آزمایش دستی یا خودکار را با استفاده از یک نسخه انجام دهند، سپس در نسخه دیگری راه‌اندازی مجدد کنند و آزمایش‌ها را دوباره اجرا کنند، سپس نتایج نهایی را مقایسه کنند.
  • نصب 2 نسخه از دوربین HAL فروشنده APEX، فعلی و آزمایشی : Dogfooders می‌توانند از نسخه آزمایشی بدون دانلود و نصب فایل اضافی استفاده کنند، بنابراین می‌توانند به راحتی آن را تعویض کنند.

در طول راه‌اندازی، apexd به دنبال sysprops با فرمت خاصی می‌گردد تا نسخه مناسب APEX را فعال کند.

فرمت های مورد انتظار برای کلید ویژگی عبارتند از:

  • بوت کانفیگ
    • برای تنظیم مقدار پیش فرض در BoardConfig.mk استفاده می شود.
    • androidboot.vendor.apex.<apex name>
  • سیسپروپ ماندگار
    • برای تغییر مقدار پیش‌فرض استفاده می‌شود که روی دستگاهی که از قبل راه‌اندازی شده تنظیم شده است.
    • در صورت وجود، مقدار bootconfig را لغو می کند.
    • 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

پس از بوت شدن دستگاه، نسخه فعال شده را با تنظیم sysprop دائمی تغییر دهید:

$ 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 چند نصب‌شده، نسخه فعال‌شده در راه‌اندازی نیز تغییر می‌کند.

برای دستگاه‌های مرجع مجازی مبتنی بر Cuttlefish ، می‌توانید از دستور --extra_bootconfig_args برای تنظیم مستقیم ویژگی bootconfig هنگام راه‌اندازی استفاده کنید. مثلا:

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

می توانید از فرمت فایل APEX برای بسته بندی و نصب ماژول های سطح پایین سیستم عامل اندروید استفاده کنید. این امکان ساخت و نصب مستقل اجزایی مانند خدمات و کتابخانه های بومی، پیاده سازی HAL، سیستم عامل، فایل های پیکربندی و غیره را فراهم می کند.

APEX های فروشنده توسط سیستم ساخت به طور خودکار در پارتیشن /vendor نصب می شوند و در زمان اجرا توسط apexd فعال می شوند درست مانند APEX ها در سایر پارتیشن ها.

موارد استفاده کنید

مدولار کردن تصاویر فروشنده

APEX ها یک بسته بندی طبیعی و مدولارسازی پیاده سازی ویژگی ها در تصاویر فروشنده را تسهیل می کنند.

هنگامی که تصاویر فروشنده به عنوان ترکیبی از APEXهای فروشنده مستقل ساخته می شوند، سازندگان دستگاه می توانند به راحتی پیاده سازی های فروشنده خاصی را که در دستگاه خود می خواهند انتخاب و انتخاب کنند. حتی اگر هیچ یک از APEX های ارائه شده مطابق با نیاز آنها نباشد، یا سخت افزار سفارشی کاملاً جدیدی داشته باشند، حتی می توانند یک APEX فروشنده جدید ایجاد کنند.

به عنوان مثال، یک OEM ممکن است تصمیم بگیرد دستگاه خود را با اجرای وای فای AOSP APEX، APEX اجرای بلوتوث SoC و APEX پیاده سازی تلفنی OEM سفارشی بسازد.

بدون APEX های فروشنده، پیاده سازی با وابستگی های بسیار بین اجزای فروشنده نیاز به هماهنگی و ردیابی دقیق دارد. با قرار دادن تمام مؤلفه ها (از جمله فایل های پیکربندی و کتابخانه های اضافی) در APEX با رابط های واضح تعریف شده در هر نقطه از ارتباط بین ویژگی ها، اجزای مختلف قابل تعویض می شوند.

تکرار توسعه دهنده

APEXهای فروشنده به توسعه‌دهندگان کمک می‌کنند در حین توسعه ماژول‌های فروشنده، با یکپارچه‌سازی اجرای کامل ویژگی، مانند 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 ، ndk_library ، یا llndk_library . این وابستگی ها از بسته بندی حذف می شوند و وابستگی ها در مانیفست APEX ثبت می شوند. مانیفست توسط linkerconfig پردازش می‌شود تا وابستگی‌های بومی خارجی در زمان اجرا در دسترس باشند.

برخلاف APEX ها در پارتیشن /system ، APEX های فروشنده معمولاً به یک نسخه VNDK خاص گره خورده اند. کتابخانه‌های VNDK پایداری ABI را در نسخه تضمین می‌کنند، بنابراین می‌توانیم کتابخانه‌های VNDK را به‌عنوان پایدار در نظر بگیریم و با استفاده از ویژگی use_vndk_as_stable ، اندازه APEXهای فروشنده را با حذف آنها از APEXها کاهش دهیم.

در قطعه زیر، 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 مربوطه و اسکریپت‌های init را نیز مشخص کند.

قطعات VINTF

وقتی قطعات در etc/vintf APEX قرار دارند، قطعات VINTF را می توان از یک APEX فروشنده ارائه کرد.

از ویژگی prebuilts برای جاسازی قطعات VINTF در APEX استفاده کنید.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

اسکریپت های Init

APEX ها می توانند اسکریپت های init را به دو صورت شامل شوند: (الف) یک فایل متنی از پیش ساخته شده در APEX payload، یا (ب) یک اسکریپت init معمولی در /vendor/etc . می توانید هر دو را برای یک APEX تنظیم کنید.

شروع اسکریپت در APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

اسکریپت های Init در APEX ها فقط می توانند تعاریف service داشته باشند. اسکریپت‌های Init در Vendor APEXها می‌توانند دستورالعمل‌های on <property> نیز داشته باشند.

هنگام استفاده on دستورالعمل ها مراقب باشید. از آنجایی که اسکریپت های init در APEX ها پس از فعال شدن 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 در پارتیشن فروشنده، نصب از طریق insmod را نشان می دهد:

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

همپوشانی منابع زمان اجرا

مثال:

با استفاده از ویژگی rros پوشش‌های منابع زمان اجرا را در APEX فروشنده جاسازی کنید.

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 در هنگام راه اندازی

مثال:

توسعه‌دهندگان همچنین می‌توانند چندین نسخه از APEXهای فروشنده را نصب کنند که نام و کلید APEX یکسانی دارند، و سپس انتخاب کنند که کدام نسخه در طول هر بار راه‌اندازی با استفاده از sysprops دائمی فعال شود. برای برخی موارد استفاده از توسعه دهندگان، این ممکن است ساده تر از نصب یک نسخه جدید از APEX با استفاده از adb install باشد.

موارد استفاده مثال:

  • نصب 3 نسخه از APEX فروشنده وای فای HAL: تیم‌های QA می‌توانند آزمایش دستی یا خودکار را با استفاده از یک نسخه انجام دهند، سپس در نسخه دیگری راه‌اندازی مجدد کنند و آزمایش‌ها را دوباره اجرا کنند، سپس نتایج نهایی را مقایسه کنند.
  • نصب 2 نسخه از دوربین HAL فروشنده APEX، فعلی و آزمایشی : Dogfooders می‌توانند از نسخه آزمایشی بدون دانلود و نصب فایل اضافی استفاده کنند، بنابراین می‌توانند به راحتی آن را تعویض کنند.

در طول راه‌اندازی، apexd به دنبال sysprops با فرمت خاصی می‌گردد تا نسخه مناسب APEX را فعال کند.

فرمت های مورد انتظار برای کلید ویژگی عبارتند از:

  • بوت کانفیگ
    • برای تنظیم مقدار پیش فرض در BoardConfig.mk استفاده می شود.
    • androidboot.vendor.apex.<apex name>
  • سیسپروپ ماندگار
    • برای تغییر مقدار پیش‌فرض استفاده می‌شود که روی دستگاهی که از قبل راه‌اندازی شده تنظیم شده است.
    • در صورت وجود، مقدار bootconfig را لغو می کند.
    • 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

پس از بوت شدن دستگاه، نسخه فعال شده را با تنظیم sysprop دائمی تغییر دهید:

$ 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 چند نصب‌شده، نسخه فعال‌شده در راه‌اندازی نیز تغییر می‌کند.

برای دستگاه‌های مرجع مجازی مبتنی بر Cuttlefish ، می‌توانید از دستور --extra_bootconfig_args برای تنظیم مستقیم ویژگی bootconfig هنگام راه‌اندازی استفاده کنید. مثلا:

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