کاهش اندازه OTA

این صفحه تغییرات اضافه‌شده به AOSP را برای کاهش تغییرات غیرضروری فایل بین ساخت‌ها شرح می‌دهد. پیاده‌سازان دستگاه که سیستم‌های ساخت خودشان را دارند می‌توانند از این اطلاعات به‌عنوان راهنمایی برای کاهش اندازه به‌روزرسانی‌های ازطریق هوا (OTA) استفاده کنند.

به‌روزرسانی‌های Android OTA گاهی حاوی فایل‌های تغییریافته‌ای است که با تغییرات کد مطابقت ندارد. آن‌ها درواقع بروندادهای سیستم ساخت هستند. این وضعیت زمانی پیش می‌آید که کد یکسانی که در زمان‌های مختلف، از دایرکتوری‌های مختلف، یا در ماشین‌های مختلف ساخته شده است تعداد زیادی فایل تغییریافته تولید کند. چنین فایل‌های اضافی اندازه وصله OTA را افزایش می‌دهند و تعیین اینکه کدام کد تغییر کرده است را دشوار می‌کنند.

برای شفاف‌تر کردن محتوای OTA،‏ AOSP تغییراتی در سیستم ساختار ایجاد کرده است که برای کاهش اندازه وصله‌های OTA طراحی شده‌اند. تغییرات غیرضروری فایل بین ساخت‌ها حذف شده است و فقط فایل‌های مربوط به وصله در به‌روزرسانی‌های OTA وجود دارد. ‫AOSP همچنین شامل ابزار تفاوت ساخت است که تغییرات فایل مربوط به ساخت مشترک را فیلتر می‌کند تا تفاوت فایل ساخت پاک‌تری ارائه دهد، و ابزار نگاشت بلوک که به شما کمک می‌کند تخصیص بلوک را ثابت نگه دارید.

سیستم ساخت می‌تواند به چند روش وصله‌های بزرگ غیرضروری ایجاد کند. برای کاهش این مشکل، در Android 8.0 و نسخه‌های بالاتر، ویژگی‌های جدیدی برای کاهش اندازه وصله برای هر تفاوت فایل پیاده‌سازی شده است. بهبودهایی که اندازه بسته به‌روزرسانی OTA را کاهش داده‌اند شامل موارد زیر است:

  • استفاده از ZSTD، یک الگوریتم فشرده‌سازی بدون افت کیفیت و با هدف عمومی برای تصاویر کامل در به‌روزرسانی‌های دستگاه‌های غیر A/B. ZSTD را می‌توان با افزایش سطح فشرده‌سازی برای نسبت‌های فشرده‌سازی بالاتر سفارشی‌سازی کرد. سطح فشرده‌سازی در زمان تولید OTA تنظیم می‌شود و با ارسال پرچم --vabc_compression_param=zstd,$COMPRESSION_LEVEL قابل تنظیم است
  • افزایش اندازه پنجره فشرده‌سازی استفاده‌شده درطول OTA. حداکثر اندازه پنجره فشرده‌سازی را می‌توان با سفارشی‌سازی پارامتر ساخت در فایل .mk دستگاه تنظیم کرد. این متغیر به‌عنوان PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144 تنظیم شده است
  • استفاده از فشرده‌سازی مجدد Puffin، ابزار وصله‌سازی قطعیتی برای جریان‌های deflate که عملکردهای فشرده‌سازی و تفاوت را برای تولید به‌روزرسانی A/B OTA مدیریت می‌کند.
  • تغییرات در استفاده از ابزار تولید دلتا، مثلاً نحوه استفاده از کتابخانه bsdiff برای فشرده‌سازی وصله‌ها. در Android نسخه ۹ و بالاتر، ابزار bsdiff الگوریتم فشرده‌سازی‌ای را انتخاب می‌کند که بهترین نتایج فشرده‌سازی را برای وصله ارائه دهد.
  • بهبودهای update_engine منجر به مصرف حافظه کمتر هنگام اعمال وصله‌ها برای به‌روزرسانی‌های دستگاه A/B شد.

بخش‌های زیر به بررسی مسائل مختلفی می‌پردازند که بر اندازه به‌روزرسانی‌های OTA تأثیر می‌گذارند، راه‌حل‌های آن‌ها، و نمونه‌هایی از پیاده‌سازی در AOSP.

ترتیب فایل

مشکل: سیستم‌های فایل هنگام درخواست فهرست فایل‌ها در یک دایرکتوری، ترتیب فایل‌ها را تضمین نمی‌کنند، اگرچه معمولاً برای همان بررسی یکسان است. ابزارهایی مثل ls نتایج را به‌طور پیش‌فرض مرتب می‌کنند، اما تابع نویسه عام که توسط فرمان‌هایی مثل find و make استفاده می‌شود مرتب نمی‌کند. قبل‌از استفاده از این ابزارها، باید بروندادها را مرتب کنید.

راه‌حل: وقتی از ابزارهایی مثل find و make با تابع کاراکتر عام استفاده می‌کنید، برونداد این فرمان‌ها را قبل‌از استفاده از آن‌ها مرتب کنید. هنگام استفاده از $(wildcard) یا $(shell find) در فایل‌های Android.mk، آن‌ها را نیز مرتب کنید. برخی‌از ابزارها، مثل Java، ورودی‌ها را مرتب می‌کنند، بنابراین قبل‌از مرتب کردن فایل‌ها، مطمئن شوید ابزاری که استفاده می‌کنید قبلاً این کار را انجام نداده باشد.

مثال‌ها: بسیاری از نمونه‌ها در سیستم ساخت اصلی بااستفاده از کلان‌دستور داخلی all-*-files-under اصلاح شد، که شامل all-cpp-files-under می‌شود (زیرا چندین تعریف در فایل‌های ساخت دیگر پخش شده بود). برای جزئیات، به موارد زیر مراجعه کنید:

ساختن فهرست راهنما

مشکل: تغییر دادن دایرکتوری که در آن چیزها ساخته می‌شوند می‌تواند باعث شود باینری‌ها متفاوت باشند. اکثر مسیرها در ساخت Android مسیرهای نسبی هستند، بنابراین __FILE__ در C/C++‎ مشکلی ایجاد نمی‌کند. بااین‌حال، نمادهای اشکال‌زدایی به‌طور پیش‌فرض نام مسیر کامل را کدبندی می‌کنند، و .note.gnu.build-id از درهم‌سازی باینری پیش‌حذف‌شده تولید می‌شود، بنابراین اگر نمادهای اشکال‌زدایی تغییر کند، این مقدار نیز تغییر خواهد کرد.

راه‌حل: اکنون AOSP مسیرهای اشکال‌زدایی را نسبی می‌کند. برای جزئیات، به CL مراجعه کنید: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02.

مهرهای زمان

مشکل: مهرهای زمان در برونداد ساخت منجر به تغییرات غیرضروری در فایل می‌شود. این اتفاق احتمالاً در مکان‌های زیر رخ می‌دهد:

  • ‫__DATE__/__TIME__/__TIMESTAMP__ کلان‌دستور در کد C یا C++‎.
  • مُهرهای زمان جاسازی‌شده در بایگانی‌های مبتنی بر zip.

راه‌حل‌ها/مثال‌ها: برای برداشتن مُهر زمان از برونداد ساخت، از دستورالعمل‌های زیر در __DATE__/__TIME__/__TIMESTAMP__ در C/C++‎ و مُهرهای زمان جاسازی‌شده در بایگانی‌ها استفاده کنید.

‫__DATE__/__TIME__/__TIMESTAMP__ در C/C++‎

این کلان‌ها همیشه بروندادهای متفاوتی برای ساخت‌های مختلف تولید می‌کنند، بنابراین از آن‌ها استفاده نکنید. در اینجا چند گزینه برای حذف این ماکروها ارائه شده است:

مُهرهای زمان جاسازی‌شده در بایگانی‌ها (zip،‏ jar)

‫Android 7.0 مشکل مُهرهای زمان جاسازی‌شده در بایگانی‌های zip را با افزودن -X به همه موارد استفاده از فرمان zip برطرف کرد. با این کار، UID/GID سازنده و مُهر زمان Unix توسعه‌یافته از فایل zip برداشته شد.

ابزار جدیدی به‌نام ziptime (واقع در /platform/build/+/android17-release/tools/ziptime/) مُهرهای زمان عادی را در سرایندهای zip بازنشانی می‌کند. برای جزئیات بیشتر، به فایل README مراجعه کنید.

ابزار signapk مُهرهای زمان را برای فایل‌های APK تنظیم می‌کند که ممکن است بسته به منطقه زمانی سرور متفاوت باشد. برای جزئیات بیشتر، به CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 مراجعه کنید.

ابزار signapk مُهرهای زمان را برای فایل‌های APK تنظیم می‌کند که ممکن است بسته به منطقه زمانی سرور متفاوت باشد. برای جزئیات بیشتر، به CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 مراجعه کنید.

رشته‌های نسخه

مشکل: رشته‌های نسخه APK اغلب BUILD_NUMBER را به نسخه‌های کدبندی‌شده خود اضافه می‌کردند. حتی اگر هیچ چیز دیگری در APK تغییر نکرده باشد، درنتیجه، APK همچنان متفاوت خواهد بود.

راهکار: شماره ساخت را از رشته نسخه APK بردارید.

نمونه:

فعال کردن محاسبه درستی‌سنجی درون‌دستگاهی

اگر dm-verity در دستگاهتان فعال باشد، ابزارهای OTA به‌طور خودکار پیکربندی درستی‌سنجی شما را دریافت می‌کنند و محاسبه درستی‌سنجی در دستگاه را فعال می‌کنند. این کار باعث می‌شود بلوک‌های درستی‌سنجی در دستگاه‌های Android محاسبه شود، به‌جای اینکه به‌عنوان بایت‌های خام در بسته OTA شما ذخیره شود. بلوک‌های Verity می‌توانند تقریباً ۱۶ مگابایت برای پارتیشن ۲ گیگابایتی استفاده کنند.

بااین‌حال، محاسبه درستی‌سنجی در دستگاه ممکن است زمان زیادی ببرد. به‌طور دقیق، کد «اصلاح خطا» در «انتقال» می‌تواند زمان زیادی طول بکشد. در دستگاه‌های Pixel، معمولاً تا ۱۰ دقیقه طول می‌کشد. در دستگاه‌های پایین‌رده ممکن است بیشتر طول بکشد. اگر می‌خواهید محاسبه درستی‌سنجی درون‌دستگاهی را غیرفعال کنید، اما همچنان dm-verity را فعال نگه دارید، می‌توانید این کار را با ارسال --disable_fec_computation به ابزار ota_from_target_files هنگام تولید به‌روزرسانی OTA انجام دهید. این پرچم محاسبات درستی‌سنجی درون‌دستگاهی را درطول به‌روزرسانی‌های OTA غیرفعال می‌کند. این گزینه زمان نصب OTA را کاهش می‌دهد، اما اندازه بسته OTA را افزایش می‌دهد. اگر dm-verity در دستگاهتان فعال نباشد، ارسال این پرچم تأثیری ندارد.

ابزارهای ساخت سازگار

مشکل: ابزارهایی که فایل‌های نصب‌شده تولید می‌کنند باید یکسان باشند (یک ورودی معین باید همیشه برونداد یکسانی تولید کند).

راه‌حل‌ها/نمونه‌ها: تغییراتی در ابزارهای ساخت زیر لازم بود:

استفاده از ابزار تفاوت ساخت

در مواردی که حذف تغییرات فایل مربوط به ساخت امکان‌پذیر نیست، AOSP شامل ابزار تفاوت ساخت target_files_diff.py برای استفاده در مقایسه دو بسته فایل است. این ابزار تفاوت بازگشتی بین دو ساختار ایجاد می‌کند و تغییرات فایل مربوط به ساختار مشترک را مستثنا می‌کند، مثل

  • تغییرات موردانتظار در برونداد ساخت (برای مثال، به‌دلیل تغییر شماره ساخت).
  • تغییرات ناشی از مشکلات شناخته‌شده در سیستم ساخت کنونی.

برای استفاده از ابزار تفاوت ساخت، فرمان زیر را اجرا کنید:

target_files_diff.py dir1 dir2

‫dir1 و dir2 فهرست‌های پایه هستند که حاوی فایل‌های هدف استخراج‌شده برای هر ساختار هستند.

تخصیص بلوک را ثابت نگه دارید

برای یک فایل معین، اگرچه محتوای آن بین دو ساخت یکسان باقی می‌ماند، اما بلوک‌های واقعی که داده‌ها را در خود نگه می‌دارند ممکن است تغییر کرده باشند. در نتیجه، به‌روزرسان باید ورودی/خروجی غیرضروری انجام دهد تا بلوک‌ها را برای به‌روزرسانی ازطریق هوا جابه‌جا کند.

در به‌روزرسانی «مجازی A/B OTA»، ورودی/خروجی غیرضروری می‌تواند فضای ذخیره‌سازی موردنیاز برای ذخیره کردن نمای فوری کپی‌درنوشتن را به‌شدت افزایش دهد. در به‌روزرسانی OTA غیر A/B، جابه‌جایی بلوک‌ها برای به‌روزرسانی OTA به زمان به‌روزرسانی اضافه می‌کند زیرا به‌دلیل جابه‌جایی بلوک‌ها، I/O بیشتری وجود دارد.

برای رسیدگی به این مشکل، در Android 7.0، Google ابزار make_ext4fs را برای حفظ تخصیص بلوک سازگار در سراسر ساختارها گسترش داد. ابزار make_ext4fs یک پرچم اختیاری -d base_fs را می‌پذیرد که تلاش می‌کند فایل‌ها را هنگام تولید تصویر ext4 به بلوک‌های یکسان اختصاص دهد. می‌توانید فایل‌های نگاشت بلوک (مثل فایل‌های نگاشت base_fs) را از فایل zip فایل‌های هدف ساخت قبلی استخراج کنید. برای هر بخش ext4، یک فایل .map در فهرست راهنمای IMAGES وجود دارد (برای مثال، IMAGES/system.map مربوط به بخش system است). سپس این فایل‌های base_fs را می‌توان ازطریق PRODUCT_<partition>_BASE_FS_PATH بررسی و مشخص کرد، مانند این مثال:

  PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map
  PRODUCT_SYSTEM_EXT_BASE_FS_PATH := path/to/base_fs_files/base_system_ext.map
  PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map
  PRODUCT_PRODUCT_BASE_FS_PATH := path/to/base_fs_files/base_product.map
  PRODUCT_ODM_BASE_FS_PATH := path/to/base_fs_files/base_odm.map

اگرچه این کار به کاهش اندازه کلی بسته OTA کمک نمی‌کند، اما با کاهش مقدار ورودی/خروجی، عملکرد به‌روزرسانی OTA را بهبود می‌بخشد. برای به‌روزرسانی‌های مجازی A/B، مقدار فضای ذخیره‌سازی موردنیاز برای اعمال OTA را به‌شدت کاهش می‌دهد.

از به‌روزرسانی برنامه‌ها خودداری کنید

علاوه‌بر به‌حداقل رساندن تفاوت‌های ساخت، می‌توانید با کنار گذاشتن به‌روزرسانی‌های برنامه‌هایی که ازطریق فروشگاه‌های برنامه به‌روزرسانی دریافت می‌کنند، اندازه به‌روزرسانی‌های OTA را کاهش دهید. فایل‌های APK اغلب بخش قابل‌توجهی از بخش‌های مختلف دستگاه را تشکیل می‌دهند. افزودن جدیدترین نسخه‌های برنامه‌هایی که ازطریق فروشگاه‌های برنامه در به‌روزرسانی OTA به‌روز می‌شوند ممکن است تأثیر زیادی بر اندازه بسته‌های OTA داشته باشد و مزایای کمی برای کاربر داشته باشد. تا زمانی که کاربران بسته OTA را دریافت کنند، ممکن است قبلاً برنامه به‌روزشده یا حتی نسخه جدیدتری را مستقیماً از فروشگاه‌های برنامه دریافت کرده باشند.