OTA का आकार कम करें

यह पृष्ठ बिल्ड के बीच अनावश्यक फ़ाइल परिवर्तनों को कम करने के लिए AOSP में जोड़े गए परिवर्तनों का वर्णन करता है। डिवाइस कार्यान्वयनकर्ता जो अपने स्वयं के बिल्ड सिस्टम को बनाए रखते हैं, इस जानकारी का उपयोग अपने ओवर-द-एयर (ओटीए) अपडेट के आकार को कम करने के लिए एक गाइड के रूप में कर सकते हैं।

एंड्रॉइड ओटीए अपडेट में कभी-कभी बदली हुई फ़ाइलें होती हैं जो कोड परिवर्तनों के अनुरूप नहीं होती हैं। वे वास्तव में सिस्टम कलाकृतियों का निर्माण कर रहे हैं। यह तब हो सकता है जब एक ही कोड, अलग-अलग समय पर, अलग-अलग निर्देशिकाओं से, या अलग-अलग मशीनों पर बड़ी संख्या में परिवर्तित फ़ाइलें तैयार करता है। ऐसी अतिरिक्त फ़ाइलें OTA पैच के आकार को बढ़ा देती हैं, और यह निर्धारित करना कठिन बना देती हैं कि कौन सा कोड बदल गया है।

ओटीए की सामग्री को अधिक पारदर्शी बनाने के लिए, एओएसपी में ओटीए पैच के आकार को कम करने के लिए डिज़ाइन किए गए बिल्ड सिस्टम परिवर्तन शामिल हैं। बिल्ड के बीच अनावश्यक फ़ाइल परिवर्तन समाप्त कर दिए गए हैं, और केवल पैच-संबंधित फ़ाइलें ओटीए अपडेट में शामिल हैं। एओएसपी में एक बिल्ड डिफ टूल भी शामिल है, जो एक क्लीनर बिल्ड फ़ाइल डिफ प्रदान करने के लिए सामान्य बिल्ड-संबंधित फ़ाइल परिवर्तनों को फ़िल्टर करता है, और एक ब्लॉक मैपिंग टूल , जो आपको ब्लॉक आवंटन को सुसंगत रखने में मदद करता है।

एक बिल्ड सिस्टम कई तरीकों से अनावश्यक रूप से बड़े पैच बना सकता है। इसे कम करने के लिए, एंड्रॉइड 8.0 और उच्चतर में, प्रत्येक फ़ाइल अंतर के लिए पैच आकार को कम करने के लिए नई सुविधाएँ लागू की गईं। ओटीए-अपडेट पैकेज आकार को कम करने वाले सुधारों में निम्नलिखित शामिल हैं:

  • गैर-ए/बी डिवाइस अपडेट पर पूर्ण छवियों के लिए एक सामान्य-उद्देश्य, दोषरहित-संपीड़न एल्गोरिदम, ब्रॉटली का उपयोग। ब्रॉटली को संपीड़न को अनुकूलित करने के लिए अनुकूलित किया जा सकता है। फ़ाइल सिस्टम में दो या दो से अधिक ब्लॉकों से युक्त बड़े अपडेट पर (उदाहरण के लिए, system.img ), डिवाइस निर्माता या भागीदार अपने स्वयं के संपीड़न एल्गोरिदम जोड़ सकते हैं, और एक ही अपडेट के विभिन्न ब्लॉकों पर विभिन्न संपीड़न एल्गोरिदम का उपयोग कर सकते हैं।
  • पफिन पुनर्संपीड़न का उपयोग, डिफ्लेट स्ट्रीम के लिए एक नियतात्मक पैचिंग उपकरण, जो ए/बी ओटीए अद्यतन पीढ़ी के लिए संपीड़न और भिन्न कार्यों को संभालता है।
  • डेल्टा-जेनरेशन टूल उपयोग में परिवर्तन, जैसे कि पैच को संपीड़ित करने के लिए bsdiff लाइब्रेरी का उपयोग कैसे किया जाता है। एंड्रॉइड 9 और उच्चतर में, bsdiff टूल संपीड़न एल्गोरिदम का चयन करता है जो पैच के लिए सर्वोत्तम संपीड़न परिणाम देगा।
  • जब A/B डिवाइस अपडेट के लिए पैच लागू किए जाते हैं तो update_engine में सुधार के परिणामस्वरूप कम मेमोरी खपत होती है।
  • ब्लॉक-आधारित ओटीए अपडेट के लिए बड़ी ज़िप फ़ाइलों को विभाजित करने में सुधार। imgdiff में एक मोड प्रविष्टि नामों के आधार पर बड़े आकार की एपीके फ़ाइलों को विभाजित करता है। यह फ़ाइलों को रैखिक रूप से विभाजित करने और उन्हें संपीड़ित करने के लिए bsdiff टूल का उपयोग करने की तुलना में एक छोटा पैच उत्पन्न करता है।

निम्नलिखित अनुभाग विभिन्न मुद्दों पर चर्चा करते हैं जो ओटीए-अपडेट आकार, उनके समाधान और एओएसपी में कार्यान्वयन के उदाहरणों को प्रभावित करते हैं।

फ़ाइल आदेश

समस्या : किसी निर्देशिका में फ़ाइलों की सूची मांगने पर फ़ाइल सिस्टम फ़ाइल ऑर्डर की गारंटी नहीं देता है, हालाँकि समान चेकआउट के लिए यह आमतौर पर समान होता है। ls जैसे उपकरण डिफ़ॉल्ट रूप से परिणामों को क्रमबद्ध करते हैं, लेकिन find और make जैसे कमांड द्वारा उपयोग किए जाने वाले वाइल्डकार्ड फ़ंक्शन क्रमबद्ध नहीं होते हैं। इन उपकरणों का उपयोग करने से पहले, आपको आउटपुट को सॉर्ट करना होगा।

समाधान : जब आप वाइल्डकार्ड फ़ंक्शन के साथ find और make जैसे टूल का उपयोग करते हैं, तो इन कमांड का उपयोग करने से पहले उनके आउटपुट को सॉर्ट करें। Android.mk फ़ाइलों में $(wildcard) या $(shell find) उपयोग करते समय, उन्हें भी क्रमबद्ध करें। कुछ उपकरण, जैसे जावा, इनपुट को सॉर्ट करते हैं, इसलिए फ़ाइलों को सॉर्ट करने से पहले, सत्यापित करें कि आप जिस टूल का उपयोग कर रहे हैं उसने पहले से ऐसा नहीं किया है।

उदाहरण: कोर बिल्ड सिस्टम में बिल्ट- all-*-files-under मैक्रो का उपयोग करके कई उदाहरण तय किए गए थे, जिसमें all-cpp-files-under शामिल है (क्योंकि कई परिभाषाएं अन्य मेकफाइल्स में फैली हुई थीं)। विवरण के लिए, निम्नलिखित देखें:

निर्देशिका बनाएँ

समस्या: जिस निर्देशिका में चीज़ें बनाई गई हैं उसे बदलने से बायनेरिज़ भिन्न हो सकते हैं। एंड्रॉइड बिल्ड में अधिकांश पथ सापेक्ष पथ हैं इसलिए C/C++ में __FILE__ कोई समस्या नहीं है। हालाँकि, डिबग प्रतीक डिफ़ॉल्ट रूप से पूर्ण पथनाम को एन्कोड करते हैं, और .note.gnu.build-id प्री-स्ट्रिप्ड बाइनरी को हैश करने से उत्पन्न होता है, इसलिए यदि डिबग प्रतीक बदलते हैं तो यह बदल जाएगा।

समाधान: AOSP अब डिबग पथों को सापेक्ष बनाता है। विवरण के लिए, सीएल देखें: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02

मुहर

समस्या: बिल्ड आउटपुट में टाइमस्टैम्प के परिणामस्वरूप अनावश्यक फ़ाइल परिवर्तन होते हैं। निम्नलिखित स्थानों पर ऐसा होने की संभावना है:

  • C या C++ कोड में __DATE__/__TIME__/__TIMESTAMP__ मैक्रोज़।
  • ज़िप-आधारित अभिलेखागार में एम्बेडेड टाइमस्टैम्प।

समाधान/उदाहरण: बिल्ड आउटपुट से टाइमस्टैम्प हटाने के लिए, C/C++ में __DATE__/__TIME__/__TIMESTAMP__ में नीचे दिए गए निर्देशों का उपयोग करें। और अभिलेखागार में एंबेडेड टाइमस्टैम्प

C/C++ में __DATE__/__TIME__/__TIMESTAMP__

ये मैक्रोज़ हमेशा अलग-अलग बिल्ड के लिए अलग-अलग आउटपुट देते हैं, इसलिए इनका उपयोग न करें। इन मैक्रोज़ को हटाने के लिए यहां कुछ विकल्प दिए गए हैं:

अभिलेखागार में एंबेडेड टाइमस्टैम्प (ज़िप, जार)

एंड्रॉइड 7.0 ने zip कमांड के सभी उपयोगों में -X जोड़कर ज़िप अभिलेखागार में एम्बेडेड टाइमस्टैम्प की समस्या को ठीक किया। इसने बिल्डर की यूआईडी/जीआईडी ​​और ज़िप फ़ाइल से विस्तारित यूनिक्स टाइमस्टैम्प को हटा दिया।

एक नया टूल, ziptime ( /platform/build/+/main/tools/ziptime/ में स्थित) ज़िप हेडर में सामान्य टाइमस्टैम्प को रीसेट करता है। विवरण के लिए, README फ़ाइल देखें।

signapk टूल एपीके फ़ाइलों के लिए टाइमस्टैम्प सेट करता है जो सर्वर टाइमज़ोन के आधार पर भिन्न हो सकता है। विवरण के लिए, सीएल https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 देखें।

संस्करण तार

समस्या: एपीके संस्करण स्ट्रिंग्स में अक्सर उनके हार्डकोडेड संस्करणों में BUILD_NUMBER जोड़ा जाता था। भले ही एपीके में और कुछ नहीं बदला हो, परिणामस्वरूप, एपीके अभी भी अलग होगा।

समाधान: एपीके संस्करण स्ट्रिंग से बिल्ड नंबर हटा दें।

उदाहरण:

ऑन-डिवाइस सत्य गणना सक्षम करें

यदि आपके डिवाइस पर डीएम-वेरिटी सक्षम है, तो ओटीए उपकरण स्वचालित रूप से आपके वेरिटी कॉन्फ़िगरेशन को उठाते हैं, और ऑन-डिवाइस वेरिटी गणना को सक्षम करते हैं। यह आपके ओटीए पैकेज में कच्चे बाइट्स के रूप में संग्रहीत होने के बजाय, एंड्रॉइड डिवाइस पर वेरिटी ब्लॉक की गणना करने की अनुमति देता है। वेरिटी ब्लॉक 2GB विभाजन के लिए लगभग 16MB का उपयोग कर सकते हैं।

हालाँकि, डिवाइस पर सत्यता की गणना करने में लंबा समय लग सकता है। विशेष रूप से, अग्रेषित त्रुटि-सुधार कोड में लंबा समय लग सकता है। पिक्सेल उपकरणों पर, इसमें 10 मिनट तक का समय लग सकता है। निम्न-स्तरीय उपकरणों पर इसमें अधिक समय लग सकता है। यदि आप ऑन-डिवाइस वेरिटी गणना को अक्षम करना चाहते हैं, लेकिन फिर भी डीएम-वेरिटी को सक्षम करना चाहते हैं, तो आप ओटीए अपडेट जेनरेट करते समय ota_from_target_files टूल में --disable_fec_computation पास करके ऐसा कर सकते हैं। यह फ़्लैग OTA अपडेट के दौरान ऑन-डिवाइस सत्यापन गणना को अक्षम कर देता है। यह OTA इंस्टॉलेशन समय को कम करता है, लेकिन OTA पैकेज का आकार बढ़ाता है। यदि आपके डिवाइस में dm-verity सक्षम नहीं है, तो इस फ़्लैग को पास करने से कोई प्रभाव नहीं पड़ेगा।

लगातार निर्माण उपकरण

समस्या: स्थापित फ़ाइलें उत्पन्न करने वाले उपकरण सुसंगत होने चाहिए (किसी दिए गए इनपुट को हमेशा एक ही आउटपुट उत्पन्न करना चाहिए)।

समाधान/उदाहरण: निम्नलिखित बिल्ड टूल में परिवर्तन आवश्यक थे:

  • नोटिस फ़ाइल निर्माता । प्रतिलिपि प्रस्तुत करने योग्य नोटिस संग्रह बनाने के लिए नोटिस फ़ाइल निर्माता को बदल दिया गया था। सीएल देखें: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64
  • जावा एंड्रॉइड कंपाइलर किट (जैक) । जेनरेटेड कंस्ट्रक्टर ऑर्डरिंग में समय-समय पर होने वाले बदलावों को संभालने के लिए जैक टूलचेन को अपडेट की आवश्यकता होती है। कंस्ट्रक्टर्स के लिए नियतात्मक एक्सेसर्स को टूलचेन में जोड़ा गया था: https://android.googlesource.com/toolchin/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b
  • एआरटी एओटी कंपाइलर (डेक्स2ओएटी) । एआरटी कंपाइलर बाइनरी को एक अपडेट प्राप्त हुआ जिसमें एक नियतात्मक छवि बनाने के लिए एक विकल्प जोड़ा गया: https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9
  • libpac.so फ़ाइल (V8) . प्रत्येक बिल्ड एक अलग /system/lib/libpac.so फ़ाइल बनाता है क्योंकि प्रत्येक बिल्ड के लिए V8 स्नैपशॉट बदलता है। समाधान स्नैपशॉट को हटाना था: https://android.googlesource.com/platform/exterminal/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29
  • एप्लिकेशन प्री-डेक्सॉप्ट (.ओडेक्स) फ़ाइलें । प्री-डेक्सॉप्ट (.odex) फ़ाइलों में 64-बिट सिस्टम पर अप्रारंभीकृत पैडिंग शामिल थी। इसे ठीक किया गया: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029

बिल्ड डिफ टूल का उपयोग करें

ऐसे मामलों के लिए जहां बिल्ड-संबंधित फ़ाइल परिवर्तनों को समाप्त करना संभव नहीं है, AOSP में दो फ़ाइल पैकेजों की तुलना करने में उपयोग के लिए एक बिल्ड डिफ टूल, target_files_diff.py शामिल है। यह उपकरण सामान्य बिल्ड-संबंधी फ़ाइल परिवर्तनों को छोड़कर, दो बिल्ड के बीच एक पुनरावर्ती अंतर निष्पादित करता है, जैसे कि

  • बिल्ड आउटपुट में अपेक्षित परिवर्तन (उदाहरण के लिए, बिल्ड नंबर परिवर्तन के कारण)।
  • वर्तमान बिल्ड सिस्टम में ज्ञात समस्याओं के कारण परिवर्तन।

बिल्ड डिफ टूल का उपयोग करने के लिए, निम्न कमांड चलाएँ:

target_files_diff.py dir1 dir2

dir1 और dir2 आधार निर्देशिकाएँ हैं जिनमें प्रत्येक बिल्ड के लिए निकाली गई लक्ष्य फ़ाइलें होती हैं।

ब्लॉक आवंटन को सुसंगत रखें

किसी दी गई फ़ाइल के लिए, हालाँकि इसकी सामग्री दो बिल्डों के बीच समान रहती है, लेकिन डेटा रखने वाले वास्तविक ब्लॉक बदल गए होंगे। परिणामस्वरूप, अपडेटर को ओटीए अपडेट के लिए ब्लॉक को इधर-उधर ले जाने के लिए अनावश्यक I/O निष्पादित करना होगा।

वर्चुअल ए/बी ओटीए अपडेट में, अनावश्यक I/O कॉपी-ऑन-राइट स्नैपशॉट को स्टोर करने के लिए आवश्यक स्टोरेज स्पेस को काफी बढ़ा सकता है। गैर-ए/बी ओटीए अपडेट में, ओटीए अपडेट के लिए ब्लॉकों को इधर-उधर ले जाने से अपडेट समय में योगदान होता है क्योंकि ब्लॉक चालों के कारण अधिक I/O होता है।

इस समस्या को हल करने के लिए, एंड्रॉइड 7.0 में Google ने सभी बिल्ड में ब्लॉक आवंटन को सुसंगत रखने के लिए make_ext4fs टूल का विस्तार किया। make_ext4fs टूल एक वैकल्पिक -d base_fs ध्वज स्वीकार करता है जो ext4 छवि बनाते समय समान ब्लॉकों में फ़ाइलें आवंटित करने का प्रयास करता है। आप पिछले बिल्ड की लक्ष्य फ़ाइलों की ज़िप फ़ाइल से ब्लॉक मैपिंग फ़ाइलें (जैसे कि base_fs मैप फ़ाइलें) निकाल सकते हैं। प्रत्येक ext4 विभाजन के लिए, IMAGES निर्देशिका में एक .map फ़ाइल होती है (उदाहरण के लिए, 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 पैकेज आकार को कम करने में मदद नहीं करता है, यह I/O की मात्रा को कम करके OTA अद्यतन प्रदर्शन में सुधार करता है। वर्चुअल ए/बी अपडेट के लिए, यह ओटीए लागू करने के लिए आवश्यक भंडारण स्थान की मात्रा को काफी कम कर देता है।

ऐप्स अपडेट करने से बचें

बिल्ड अंतर को कम करने के अलावा, आप ऐप स्टोर के माध्यम से अपडेट प्राप्त करने वाले ऐप्स के अपडेट को छोड़कर ओटीए अपडेट आकार को कम कर सकते हैं। एपीके अक्सर किसी डिवाइस पर विभिन्न विभाजनों का एक महत्वपूर्ण हिस्सा होते हैं। ओटीए अपडेट में ऐप स्टोर द्वारा अपडेट किए जाने वाले ऐप्स के नवीनतम संस्करणों को शामिल करने से ओटीए पैकेज पर बड़े आकार का प्रभाव पड़ सकता है, और उपयोगकर्ता को कम लाभ मिल सकता है। जब तक उपयोगकर्ताओं को ओटीए पैकेज प्राप्त होता है, तब तक उनके पास पहले से ही अपडेटेड ऐप या उससे भी नया संस्करण सीधे ऐप स्टोर से प्राप्त हो सकता है।