تقليل حجم التحديثات عبر الهواء

توضّح هذه الصفحة التغييرات التي تمت إضافتها إلى AOSP للحدّ من التغييرات غير الضرورية في الملفات بين الإصدارات. يمكن لمُنفّذِي الأجهزة الذين يحافظون على أنظمة الإنشاء الخاصة بهم استخدام هذه المعلومات كدليل لتقليل حجم التحديثات عبر الهواء (OTA).

تحتوي تحديثات Android OTA أحيانًا على ملفات تم تغييرها ولا تتوافق مع التغييرات في الرموز البرمجية. إنّهم يبنون في الواقع عناصر النظام. يمكن أن يحدث ذلك عندما ينتج الرمز البرمجي نفسه، الذي تم إنشاؤه في أوقات مختلفة أو من أدلة مختلفة أو على أجهزة مختلفة، عددًا كبيرًا من الملفات التي تم تعديلها. تؤدي هذه الملفات الزائدة إلى زيادة حجم تصحيح OTA، وتصعِّب تحديد الرمز البرمجي الذي تم تغييره.

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

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

  • استخدام ZSTD، وهي خوارزمية ضغط بدون فقدان للبيانات للأغراض العامة للصور الكاملة في تحديثات الأجهزة غير المستندة إلى قنوات A/B يمكن تخصيص ZSTD لنسب ضغط أعلى من خلال زيادة مستوى الضغط. يتم ضبط مستوى الضغط أثناء وقت إنشاء OTA ويمكن ضبطه من خلال تمرير العلامة --vabc_compression_param=zstd,$COMPRESSION_LEVEL
  • زيادة حجم نافذة الضغط المستخدَمة أثناء عملية OTA يمكن ضبط الحد الأقصى لحجم نافذة الضغط من خلال تخصيص مَعلمة الإنشاء في ملف .mk الخاص بالجهاز. يتم ضبط هذا المتغيّر على النحو التالي: PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
  • استخدام إعادة الضغط في Puffin، وهي أداة تصحيح محددة لملفات deflate التي تعالج وظائف الضغط والاختلاف لإنشاء تحديثات A/B عبر اتصال لاسلكي
  • التغييرات على استخدام أداة إنشاء الدلائل، مثل كيفية استخدام مكتبة bsdiff في ضغط الرموز البرمجية في الإصدار 9 من نظام التشغيل Android والإصدارات الأحدث، تختار أداة bsdiff خوارزمية الضغط التي تؤدي إلى تحقيق أفضل نتائج ضغط لتطبيق التصحيح.
  • أدّت التحسينات على update_engine إلى استهلاك ذاكرة أقل عند تطبيق الرموز البرمجية الإصلاحية على تحديثات أجهزة اختبار A/B.

تتناول الأقسام التالية المشاكل المختلفة التي تؤثّر في أحجام التحديثات عبر الهواء وحلولها، وأمثلة على التنفيذ في AOSP.

ترتيب الملفات

المشكلة: لا تضمن أنظمة الملفات ترتيب الملفات عند طلب قائمة بالملفّات في دليل معيّن، على الرغم من أنّه يكون عادةً متطابقًا في عملية الفحص نفسها. تُرتّب الأدوات، مثل ls النتائج تلقائيًا، ولكن لا تُرتّب الدالة البدل التي تستخدمها الأوامر، مثل find وmake. قبل استخدام هذه الأدوات، عليك ترتيب النتائج.

الحل: عند استخدام أدوات مثل find و make مع دالة العنصر النائب، يجب ترتيب الناتج من هذه الأوامر قبل استخدام هذه الأوامر. عند استخدام $(wildcard) أو $(shell find) فيملفّات Android.mk، يجب ترتيبها أيضًا. تُرتّب بعض الأدوات الإدخالات، مثل Java، لذلك قبل ترتيب الملفات، تأكَّد من أنّ الأداة التي تستخدمها لم تُجري ذلك من قبل.

أمثلة: تم إصلاح العديد من الحالات في نظام الإنشاء الأساسي باستخدام الماكرو المضمّن all-*-files-under الذي يتضمّن all-cpp-files-under (نظرًا لتوزّع العديد من التعريفات في ملفات makefiles أخرى). لمعرفة التفاصيل، يُرجى الاطّلاع على ما يلي:

دليل الإنشاء

المشكلة: يمكن أن يؤدي تغيير الدليل الذي يتم إنشاء العناصر فيه إلى اختلاف البرامج الثنائية. معظم المسارات في إصدار 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/+/android16-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 تلقائيًا إعدادات ميزة Verity، و ستفعِّل احتساب ميزة Verity على الجهاز. يتيح ذلك احتساب وحدات التحقّق على أجهزة Android بدلاً من تخزينها كوحدات بايت أولية في حزمة OTA. يمكن أن تستخدم كتل Verity حوالي 16 ميغابايت لقسم بسعة 2 غيغابايت.

ومع ذلك، يمكن أن تستغرق عملية احتساب صحة البيانات على الجهاز وقتًا طويلاً. على وجه التحديد، يمكن أن يستغرق رمز تصحيح الخطأ في البث المباشر مدة طويلة. على أجهزة Pixel، يستغرق ذلك عادةً مدة تصل إلى 10 دقائق. قد يستغرق الأمر وقتًا أطول على الأجهزة الأقل تطوّرًا. إذا كنت تريد إيقاف عملية حساب صحة الملفات على الجهاز، مع إبقاء ميزة dm-verity مفعّلة، يمكنك إجراء ذلك من خلال تمرير --disable_fec_computation إلى أداة ota_from_target_files عند إنشاء تحديث عبر الهواء. تعمل هذه العلامة على إيقاف احتساب التصديق على الجهاز أثناء التحديثات عبر الهواء. ويؤدي ذلك إلى تقليل وقت التثبيت عبر الإنترنت، ولكنّه يزيد من حجم حزمة التثبيت عبر الإنترنت. إذا لم يكن لديك dm-verity مفعَّلاً على جهازك، لن يكون لتمرير هذه العلامة أي تأثير.

أدوات إنشاء موحّدة

المشكلة: يجب أن تكون الأدوات التي تُنشئ الملفات المثبَّتة متسقة (يجب أن يؤدي إدخال معيّن إلى النتيجة نفسها دائمًا).

الحلول/الأمثلة: كانت التغييرات مطلوبة في أدوات الإنشاء التالية:

استخدام أداة مقارنة الإصدارات

في الحالات التي لا يمكن فيها إزالة تغييرات الملفات المرتبطة بالإنشاء، يتضمّن AOSP أداة مقارنة الإصدارات، target_files_diff.py للاستخدام في مقارنة حِزم الملفات. تُجري هذه الأداة مقارنة تسلسلية بين اثنين من عمليات الإنشاء، باستثناء التغييرات الشائعة في الملفات المرتبطة بالإنشاء، مثل

  • التغييرات المتوقّعة في نتيجة الإصدار (على سبيل المثال، بسبب تغيير رقم الإصدار)
  • التغييرات بسبب مشاكل معروفة في نظام الإنشاء الحالي

لاستخدام أداة مقارنة الإصدارات، شغِّل الأمر التالي:

target_files_diff.py dir1 dir2

dir1 وdir2 هما دليلان أساسيان يحتويان على ملفات الوجهة التي تم استخراجها لكل إصدار.

الحفاظ على اتساق تخصيص الكتل

بالنسبة إلى ملف معيّن، على الرغم من أنّ محتوى الملف يظلّ كما هو بين إصدارَين، قد تتغيّر الكتل الفعلية التي تحتوي على البيانات. نتيجةً لذلك، يجب أن يُجري أداة التحديث عمليات إدخال/إخراج غير ضرورية لنقل الكتل من أجل إجراء تحديث عبر شبكة غير سلكية.

في تحديث A/B OTA الافتراضي، يمكن أن تؤدي عمليات الإدخال/الإخراج غير الضرورية إلى زيادة كبيرة في مساحة التخزين المطلوبة لتخزين لقطة النسخ عند الكتابة. في التحديثات غير المُدارة من خلال تقنية A/B عبر الهواء، يؤدي نقل الكتل من أجل التحديث عبر الهواء إلى زيادة وقت التحديث بسبب زيادة عمليات الإدخال/الإخراج بسبب نقل الكتل.

لحلّ هذه المشكلة، وسّعت Google أداة make_ext4fs في Android 7.0 للحفاظ على اتساق تخصيص الكتل في جميع الإصدارات. تقبل أداة 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 التجريبية، يقلل هذا الإجراء بشكل كبير من مساحة التخزين اللازمة لتطبيق التحديث عبر الهواء.

تجنُّب تحديث التطبيقات

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