این سند، طراحی یک راهکار ذخیرهسازی APK را برای نصب سریع برنامههای از پیش بارگذاری شده روی دستگاهی که از پارتیشنهای A/B پشتیبانی میکند، شرح میدهد.
تولیدکنندگان اصلی تجهیزات (OEM) میتوانند پیشبارگذاریها و برنامههای محبوب را در حافظه پنهان APK ذخیره شده در پارتیشن B که عمدتاً خالی است، در دستگاههای جدید با پارتیشن A/B قرار دهند، بدون اینکه هیچ تأثیری بر فضای داده کاربر داشته باشد. با داشتن حافظه پنهان APK در دستگاه، دستگاههای جدید یا دستگاههایی که اخیراً تنظیمات کارخانه را انجام دادهاند، تقریباً بلافاصله و بدون نیاز به دانلود فایلهای APK از Google Play آماده استفاده هستند.
موارد استفاده
- برنامههای از پیش بارگذاری شده را برای راهاندازی سریعتر در پارتیشن B ذخیره کنید
- برنامههای محبوب را برای بازیابی سریعتر در پارتیشن B ذخیره کنید
پیشنیازها
برای استفاده از این ویژگی، دستگاه به موارد زیر نیاز دارد:
- نسخه اندروید ۸.۱ (O MR1) نصب شده است
- پارتیشن A/B پیادهسازی شد
محتوای از پیش بارگذاری شده فقط در اولین بوت قابل کپی شدن است. دلیل این امر این است که در دستگاههایی که از بهروزرسانیهای سیستم A/B پشتیبانی میکنند، پارتیشن B در واقع فایلهای ایمیج سیستم را ذخیره نمیکند، بلکه محتوای از پیش بارگذاری شده مانند منابع نمایشی خردهفروشی، فایلهای OAT و حافظه پنهان APK را در خود جای میدهد. پس از کپی شدن منابع در پارتیشن /data (این اتفاق در اولین بوت رخ میدهد)، پارتیشن B توسط بهروزرسانیهای بیسیم (OTA) برای دانلود نسخههای بهروز شده از ایمیج سیستم استفاده خواهد شد.
بنابراین، حافظه پنهان APK را نمیتوان از طریق OTA بهروزرسانی کرد؛ فقط میتوان آن را در کارخانه از قبل بارگذاری کرد. تنظیم مجدد کارخانه فقط بر روی پارتیشن /data تأثیر میگذارد. پارتیشن سیستم B تا زمانی که تصویر OTA دانلود شود، همچنان محتوای از پیش بارگذاری شده را دارد. پس از تنظیم مجدد کارخانه، سیستم دوباره بوت اول را طی میکند. این بدان معناست که اگر تصویر OTA در پارتیشن B دانلود شود و سپس دستگاه به تنظیمات کارخانه بازگردد، ذخیره APK در دسترس نخواهد بود.
پیادهسازی
رویکرد ۱. محتوا در پارتیشن system_other
مزایا : محتوای از پیش بارگذاری شده پس از تنظیم مجدد کارخانه از بین نمیرود - پس از راهاندازی مجدد، از پارتیشن B کپی میشود.
معایب : به فضای زیادی در پارتیشن B نیاز دارد. بوت شدن پس از تنظیم مجدد کارخانه به زمان بیشتری برای کپی کردن محتوای از پیش بارگذاری شده نیاز دارد.
برای اینکه پیشبارگذاریها در اولین بوت کپی شوند، سیستم اسکریپتی را در /system/bin/preloads_copy.sh فراخوانی میکند. این اسکریپت با یک آرگومان واحد (مسیر به نقطه اتصال فقط خواندنی برای پارتیشن system_b ) فراخوانی میشود:
برای پیادهسازی این ویژگی، این تغییرات خاص دستگاه را اعمال کنید. در اینجا مثالی از Marlin آورده شده است:
- اسکریپتی که کپی را انجام میدهد به فایل
device-common.mk(در این مورد،device/google/marlin/device-common.mk) مانند زیر اضافه کنید: سورس اسکریپت نمونه را در آدرس زیر بیابید: device/google/marlin/preloads_copy.sh# Script that copies preloads directory from system_other to data partition PRODUCT_COPY_FILES += \ device/google/marlin/preloads_copy.sh:system/bin/preloads_copy.sh - فایل
init.common.rcرا ویرایش کنید تا دایرکتوری و زیرشاخههای لازم/data/preloadsایجاد شود: منبع فایلmkdir /data/preloads 0775 system systemmkdir /data/preloads/media 0775 system systemmkdir /data/preloads/demo 0775 system systeminitنمونه را در آدرس زیر بیابید: device/google/marlin/init.common.rc - یک دامنه جدید SELinux را در فایل
preloads_copy.teتعریف کنید: یک نمونه فایل دامنه SELinux را در آدرس زیر بیابید: /device/google/marlin/+/android16-qpr1-release/sepolicy/preloads_copy.tetype preloads_copy, domain, coredomain; type preloads_copy_exec, exec_type, vendor_file_type, file_type; init_daemon_domain(preloads_copy) allow preloads_copy shell_exec:file rx_file_perms; allow preloads_copy toolbox_exec:file rx_file_perms; allow preloads_copy preloads_data_file:dir create_dir_perms; allow preloads_copy preloads_data_file:file create_file_perms; allow preloads_copy preloads_media_file:dir create_dir_perms; allow preloads_copy preloads_media_file:file create_file_perms; # Allow to copy from /postinstall allow preloads_copy system_file:dir r_dir_perms;
- ثبت دامنه در یک دامنه جدید
فایل/sepolicy/file_contexts :/sepolicy/file_contexts یک نمونه از فایل زمینههای SELinux را در آدرس زیر بیابید: device/google/marlin/sepolicy/preloads_copy.te/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
- در زمان ساخت، دایرکتوری حاوی محتوای از پیش بارگذاری شده باید در پارتیشن
system_otherکپی شود: این نمونهای از تغییر در Makefile است که امکان کپی کردن منابع کش APK از مخزن Git فروشنده (در مورد ما vendor/google_devices/marlin/preloads بود) را به مکانی در پارتیشن system_other فراهم میکند که بعداً هنگام اولین بوت دستگاه در /data/preloads کپی خواهد شد. این اسکریپت در زمان ساخت اجرا میشود تا تصویر system_other را آماده کند. انتظار دارد محتوای از پیش بارگذاری شده در vendor/google_devices/marlin/preloads موجود باشد. OEM در انتخاب نام/مسیر مخزن واقعی آزاد است.# Copy contents of preloads directory to system_other partition PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,vendor/google_devices/marlin/preloads,system_other/preloads) - حافظه پنهان APK در مسیر
/data/preloads/file_cacheقرار دارد و طرحبندی آن به صورت زیر است: این ساختار دایرکتوری نهایی روی دستگاهها است. تولیدکنندگان اصلی تجهیزات (OEM) میتوانند هر رویکرد پیادهسازی را انتخاب کنند، مادامی که ساختار فایل نهایی، ساختار توضیح داده شده در بالا را تکرار کند./data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
رویکرد ۲. محتوای تصویر دادههای کاربر در کارخانه فلش شد
این رویکرد جایگزین فرض میکند که محتوای از پیش بارگذاریشده از قبل در دایرکتوری /data/preloads در پارتیشن /data قرار دارد.
مزایا : به صورت آماده کار میکند - نیازی به سفارشیسازی دستگاه برای کپی کردن فایلها در اولین بوت نیست. محتوا از قبل در پارتیشن /data وجود دارد.
معایب : محتوای از پیش بارگذاری شده پس از تنظیم مجدد کارخانه از بین میرود. اگرچه این ممکن است برای برخی قابل قبول باشد، اما ممکن است همیشه برای تولیدکنندگان اصلی تجهیزات (OEM) که پس از انجام بازرسیهای کنترل کیفیت، دستگاهها را به تنظیمات کارخانه باز میگردانند، کار نکند.
یک متد جدید @SystemApi getPreloadsFileCache() به android.content.Context اضافه شده است. این متد یک مسیر مطلق به دایرکتوری مخصوص برنامه در حافظه پنهان از پیش بارگذاری شده برمیگرداند.
یک متد جدید، IPackageManager.deletePreloadsFileCache ، اضافه شده است که امکان حذف دایرکتوری preloads را برای آزادسازی کل فضا فراهم میکند. این متد فقط توسط برنامههایی با SYSTEM_UID، یعنی سرور سیستم یا تنظیمات، قابل فراخوانی است.
آمادهسازی برنامه
فقط برنامههای دارای مجوز میتوانند به دایرکتوری کش preloads دسترسی داشته باشند. برای این دسترسی، برنامهها باید در دایرکتوری /system/priv-app نصب شوند.
اعتبارسنجی
- پس از اولین بوت، دستگاه باید دارای محتوایی در دایرکتوری
/data/preloads/file_cacheباشد. - اگر فضای ذخیرهسازی دستگاه کم شود، محتوای موجود در دایرکتوری
file_cache/باید حذف شود.
برای آزمایش حافظه پنهان APK از برنامه ApkCacheTest به عنوان مثال استفاده کنید.
- با اجرای این دستور از دایرکتوری ریشه، برنامه را بسازید:
make ApkCacheTest - برنامه را به عنوان یک برنامه ممتاز نصب کنید. (به یاد داشته باشید، فقط برنامههای ممتاز میتوانند به حافظه پنهان APK دسترسی داشته باشند.) این کار به یک دستگاه روت شده نیاز دارد:
adb root && adb remountadb shell mkdir /system/priv-app/ApkCacheTestadb push $ANDROID_PRODUCT_OUT/data/app/ApkCacheTest/ApkCacheTest.apk /system/priv-app/ApkCacheTest/adb shell stop && adb shell start - در صورت نیاز، دایرکتوری کش فایل و محتوای آن را شبیهسازی کنید (همچنین به امتیازات ریشه نیاز دارد):
adb shell mkdir -p /data/preloads/file_cache/com.android.apkcachetestadb shell restorecon -r /data/preloadsadb shell "echo "Test File" > /data/preloads/file_cache/com.android.apkcachetest/test.txt" - برنامه را تست کنید. پس از نصب برنامه و ایجاد دایرکتوری test
file_cache، برنامه ApkCacheTest را باز کنید. باید یک فایلtest.txtو محتویات آن را نشان دهد. برای مشاهده نحوه نمایش این نتایج در رابط کاربری، به این تصویر مراجعه کنید.
شکل 1. نتایج ApkCacheTest.