تصف هذه الصفحة التغييرات التي تمت إضافتها إلى AOSP لتقليل تغييرات الملفات غير الضرورية بين الإصدارات. يمكن لمنفذي الأجهزة الذين يحتفظون بأنظمة البناء الخاصة بهم استخدام هذه المعلومات كدليل لتقليل حجم التحديثات عبر الهواء (OTA).
تحتوي تحديثات Android OTA أحيانًا على ملفات تم تغييرها لا تتوافق مع تغييرات الرمز. إنهم في الواقع يقومون ببناء أدوات النظام. يمكن أن يحدث هذا عندما ينتج عن نفس الكود ، الذي تم إنشاؤه في أوقات مختلفة ، أو من أدلة مختلفة ، أو على أجهزة مختلفة عددًا كبيرًا من الملفات المتغيرة. تزيد هذه الملفات الزائدة من حجم تصحيح OTA وتجعل من الصعب تحديد الرمز الذي تم تغييره.
لجعل محتويات OTA أكثر شفافية ، تتضمن AOSP تغييرات نظام البناء المصممة لتقليل حجم تصحيحات OTA. تم التخلص من تغييرات الملفات غير الضرورية بين الإصدارات ، ويتم تضمين الملفات المتعلقة بالتصحيح فقط في تحديثات OTA. يتضمن AOSP أيضًا أداة فرق البناء ، والتي تقوم بتصفية تغييرات الملفات الشائعة المتعلقة بالبناء لتوفير فرق ملف بناء أنظف ، وأداة تعيين الكتلة ، والتي تساعدك على الحفاظ على تناسق تخصيص الكتلة.
يمكن لنظام الإنشاء إنشاء تصحيحات كبيرة غير ضرورية بعدة طرق. لتخفيف هذا الأمر ، في Android 8.0 والإصدارات الأحدث ، تم تطبيق ميزات جديدة لتقليل حجم التصحيح لكل اختلاف في الملف. تشمل التحسينات التي قللت من أحجام حزم تحديث OTA ما يلي:
- استخدام Brotli ، وهو خوارزمية ذات غرض عام وضغط بلا خسارة للصور الكاملة في تحديثات الأجهزة غير A / B. يمكن تخصيص Brotli لتحسين الضغط. في التحديثات الكبيرة التي تتكون من كتلتين أو أكثر في نظام الملفات (على سبيل المثال ،
system.img
) ، يمكن لمصنعي الأجهزة أو الشركاء إضافة خوارزميات الضغط الخاصة بهم ، ويمكنهم استخدام خوارزميات ضغط مختلفة على كتل مختلفة من نفس التحديث. - استخدام إعادة ضغط Puffin ، وهي أداة ترقيع حتمية لتدفقات الانكماش ، والتي تتعامل مع وظائف الضغط والفرق لتوليد تحديث A / B OTA.
- التغييرات التي تم إجراؤها على استخدام أداة إنشاء دلتا ، مثل كيفية استخدام مكتبة
bsdiff
لضغط التصحيحات. في Android 9 والإصدارات الأحدث ، تحدد أداةbsdiff
خوارزمية الضغط التي من شأنها أن تعطي أفضل نتائج ضغط للتصحيح. - أدت التحسينات التي تم إجراؤها على
update_engine
إلى تقليل استهلاك الذاكرة عند تطبيق التصحيحات على تحديثات جهاز A / B. - تحسينات لتقسيم ملفات zip الكبيرة لتحديثات OTA القائمة على الكتلة. يقسم وضع في
imgdiff
ملفات APK كبيرة الحجم ، بناءً على أسماء الإدخال. ينتج عن ذلك تصحيح أصغر مقارنة بتقسيم الملفات خطيًا واستخدام أداةbsdiff
لضغطها.
تناقش الأقسام التالية المشكلات المختلفة التي تؤثر على أحجام تحديث OTA وحلولها وأمثلة للتنفيذ في AOSP.
ترتيب الملفات
المشكلة : لا تضمن أنظمة الملفات ترتيب الملفات عند مطالبتك بقائمة من الملفات في دليل ، على الرغم من أنها عادةً ما تكون متشابهة في عملية السحب نفسها. أدوات مثل ls
تقوم بفرز النتائج افتراضيًا ، لكن وظيفة أحرف البدل المستخدمة بواسطة أوامر مثل find
make
لا تفرز. قبل استخدام هذه الأدوات ، يجب عليك فرز المخرجات.
الحل : عند استخدام أدوات مثل find
make
بوظيفة أحرف البدل ، قم بفرز إخراج هذه الأوامر قبل استخدامها. عند استخدام $(wildcard)
أو $(shell find)
في ملفات Android.mk
، قم بفرزها أيضًا. تقوم بعض الأدوات ، مثل Java ، بفرز المدخلات ، لذا قبل فرز الملفات ، تحقق من أن الأداة التي تستخدمها لم تقم بذلك بالفعل.
أمثلة: تم إصلاح العديد من الحالات في نظام الإنشاء الأساسي باستخدام all-*-files-under
الماكرو ، والذي يتضمن all-cpp-files-under
(حيث تم نشر العديد من التعريفات في ملفات makefiles الأخرى). لمزيد من التفاصيل ، يرجى الرجوع إلى ما يلي:
- https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f
- https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410
- https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653
- https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c
بناء الدليل
المشكلة: قد يؤدي تغيير الدليل الذي تُبنى فيه الأشياء إلى اختلاف الثنائيات. معظم المسارات في إصدار Android هي مسارات نسبية ، لذا لا يمثل __FILE__
في C / C ++ مشكلة. ومع ذلك ، تقوم رموز التصحيح بترميز اسم المسار الكامل افتراضيًا ، ويتم إنشاء .note.gnu.build-id
من تجزئة الملف الثنائي الذي تم تجريده مسبقًا ، لذلك سيتغير إذا تغيرت رموز التصحيح.
الحل: تقوم AOSP الآن بجعل مسارات تصحيح الأخطاء نسبية. للحصول على التفاصيل ، راجع CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02 .
الطوابع الزمنية
المشكلة: ينتج عن الطوابع الزمنية في إخراج البناء تغييرات غير ضرورية في الملف. من المحتمل أن يحدث هذا في المواقع التالية:
-
__DATE__/__TIME__/__TIMESTAMP__
في كود C أو C ++. - الطوابع الزمنية المضمنة في أرشيفات مضغوطة.
الحلول / الأمثلة: لإزالة الطوابع الزمنية من مخرجات الإصدار ، استخدم الإرشادات الواردة أدناه في __DATE __ / __ TIME __ / __ TIMESTAMP__ في C / C ++. والطوابع الزمنية المضمنة في الأرشيف .
__DATE __ / __ TIME __ / __ TIMESTAMP__ في C / C ++
تنتج وحدات الماكرو هذه دائمًا مخرجات مختلفة لبناءات مختلفة ، لذا لا تستخدمها. فيما يلي بعض الخيارات للتخلص من وحدات الماكرو هذه:
- احذفهم. للحصول على مثال ، راجع https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f .
- لتعريف الثنائي الجاري بشكل فريد ، اقرأ معرف البناء من رأس ELF.
- لمعرفة تاريخ إنشاء نظام التشغيل ، اقرأ
ro.build.date
(يعمل هذا مع كل شيء باستثناء الإصدارات الإضافية ، والتي قد لا تُحدِّث هذا التاريخ). للحصول على مثال ، راجع https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84 .
الطوابع الزمنية المضمنة في الأرشيفات (الرمز البريدي ، الجرة)
قام Android 7.0 بإصلاح مشكلة الطوابع الزمنية المضمنة في أرشيفات zip عن طريق إضافة -X
إلى جميع استخدامات الأمر zip
. أدى ذلك إلى إزالة UID / GID الخاص بالمنشئ والطابع الزمني الممتد لنظام Unix من ملف zip.
أداة جديدة ، ziptime
(موجودة في /platform/build/+/master/tools/ziptime/
) تعيد تعيين الطوابع الزمنية العادية في رؤوس الملفات المضغوطة. للحصول على تفاصيل ، راجع ملف README .
تعيّن أداة signapk
الطوابع الزمنية لملفات APK التي قد تختلف وفقًا للمنطقة الزمنية للخادم. للحصول على التفاصيل ، راجع CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 .
سلاسل الإصدار
المشكلة: تحتوي سلاسل إصدار APK غالبًا على BUILD_NUMBER
مُلحقًا بإصداراتها المشفرة. حتى إذا لم يتغير شيء آخر في APK ، كنتيجة لذلك ، سيظل ملف APK مختلفًا.
الحل: قم بإزالة رقم البنية من سلسلة إصدار APK.
أمثلة:
- https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27
- https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c
تفعيل حساب الحقيقة على الجهاز
إذا تم تمكين dm-verity على جهازك ، فستقوم أدوات OTA تلقائيًا باختيار تكوين الحقيقة الخاص بك ، وتمكين حساب الحقيقة على الجهاز. يسمح ذلك بحساب كتل الحقيقة على أجهزة Android ، بدلاً من تخزينها كبايتات أولية في حزمة OTA الخاصة بك. يمكن أن تستخدم كتل Verity حوالي 16 ميجابايت لقسم 2 جيجابايت.
ومع ذلك ، يمكن أن تستغرق صحة الحوسبة على الجهاز وقتًا طويلاً. على وجه التحديد ، يمكن أن يستغرق رمز تصحيح الخطأ الأمامي وقتًا طويلاً. على أجهزة البكسل ، يستغرق الأمر ما يصل إلى 10 دقائق. قد يستغرق الأمر وقتًا أطول على الأجهزة المنخفضة الجودة. إذا كنت ترغب في تعطيل حساب الحقيقة على الجهاز ، ولكن لا تزال تقوم بتمكين dm-verity ، فيمكنك القيام بذلك عن طريق تمرير --disable_fec_computation
إلى أداة ota_from_target_files
عند إنشاء تحديث OTA. تعمل هذه العلامة على تعطيل حساب الحقيقة على الجهاز أثناء تحديثات OTA. يقلل من وقت تثبيت OTA ، لكنه يزيد من حجم حزمة OTA. إذا لم يتم تمكين dm-verity على جهازك ، فلن يكون لتمرير هذه العلامة أي تأثير.
أدوات بناء متسقة
المشكلة: يجب أن تكون الأدوات التي تنشئ ملفات مثبتة متسقة (يجب أن ينتج إدخال معين نفس الإخراج دائمًا).
الحلول / الأمثلة: التغييرات مطلوبة في أدوات البناء التالية:
- منشئ ملف الإخطار . تم تغيير مُنشئ ملف NOTICE لإنشاء مجموعات إشعار قابلة للإنتاج. راجع CL: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64 .
- Java Android Compiler Kit (جاك) . تطلب Jack toolchain تحديثًا للتعامل مع التغييرات العرضية في ترتيب المُنشئ الذي تم إنشاؤه. تمت إضافة موصّلات محددة للمُنشئين إلى toolchain: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b .
- مترجم ART AOT (dex2oat) . تلقى ثنائي مترجم ART تحديثًا أضاف خيارًا لإنشاء صورة حتمية: https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9 .
- ملف libpac.so (V8) . يقوم كل بناء بإنشاء ملف
/system/lib/libpac.so
مختلف لأن لقطة V8 تتغير لكل بناء. كان الحل هو إزالة اللقطة: https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29 . - ملفات التطبيق pre-dexopt'd (.odex) . احتوت ملفات pre-dexopt'd (.odex) على حشوة غير مهيأة على أنظمة 64 بت. تم تصحيح ذلك: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029 .
استخدام أداة فرق البناء
بالنسبة للحالات التي يتعذر فيها استبعاد تغييرات الملفات المتعلقة بالبناء ، فإن AOSP يتضمن أداة فرق البناء ، target_files_diff.py
لاستخدامها في مقارنة حزمتي ملفات. تقوم هذه الأداة بإجراء فرق متكرر بين بنائين ، باستثناء تغييرات الملفات الشائعة المتعلقة بالبناء ، مثل
- التغييرات المتوقعة في مخرجات البناء (على سبيل المثال ، بسبب تغيير رقم الإصدار).
- التغييرات بسبب المشكلات المعروفة في نظام البناء الحالي.
لاستخدام أداة build diff ، قم بتشغيل الأمر التالي:
target_files_diff.py dir1 dir2
dir1
و dir2
هما مجلدان أساسيان يحتويان على ملفات الهدف المستخرجة لكل بناء.
الحفاظ على اتساق تخصيص الكتلة
بالنسبة لملف معين ، على الرغم من أن محتوياته تظل كما هي بين بنائين ، فقد تكون الكتل الفعلية التي تحتوي على البيانات قد تغيرت. نتيجة لذلك ، يجب أن يقوم المحدث بإجراء إدخال / إخراج غير ضروري لتحريك الكتل لتحديث OTA.
في تحديث Virtual A / B OTA ، يمكن أن تؤدي عمليات الإدخال / الإخراج غير الضرورية إلى زيادة مساحة التخزين المطلوبة بشكل كبير لتخزين لقطة النسخ عند الكتابة. في تحديث OTA غير A / B ، يساهم تحريك الكتل لتحديث OTA في تحديث الوقت نظرًا لوجود المزيد من الإدخال / الإخراج بسبب تحركات الحظر.
لمعالجة هذه المشكلة ، وسعت Google في Android 7.0 أداة make_ext4fs
للحفاظ على تناسق تخصيص الكتلة عبر الإصدارات. تقبل أداة make_ext4fs
علامة اختيارية -d base_fs
تحاول تخصيص الملفات لنفس الكتل عند إنشاء صورة ext4
. يمكنك استخراج ملفات تعيين الكتل (مثل ملفات خريطة base_fs
) من ملف مضغوط لملفات هدف بناء سابق. لكل قسم 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 ، قد يكون لديهم بالفعل التطبيق المحدث ، أو حتى إصدار أحدث ، يتم تلقيه مباشرة من متاجر التطبيقات.