OTA সাইজ কমানো

বিল্ডের মধ্যে অপ্রয়োজনীয় ফাইল পরিবর্তন কমানোর জন্য AOSP-তে যোগ করা পরিবর্তনগুলি এই পৃষ্ঠায় বর্ণনা করা হয়েছে। যেসব ডিভাইস ইমপ্লিমেন্টার নিজস্ব বিল্ড সিস্টেম বজায় রাখে, তারা এই তথ্যকে ওভার-দ্য-এয়ার (OTA) আপডেটের সাইজ কমানোর জন্য একটি নির্দেশিকা হিসেবে ব্যবহার করতে পারে।

Android OTA আপডেটে মাঝে মাঝে এমন পরিবর্তিত ফাইল থাকে যা কোডের পরিবর্তনের সাথে সঙ্গতিপূর্ণ নয়। এগুলি আসলে বিল্ড সিস্টেম আর্টিফ্যাক্ট। এটি তখন হতে পারে যখন একই কোড, আলাদা আলাদা সময়ে, আলাদা আলাদা ডিরেক্টরি থেকে বা আলাদা আলাদা মেশিনে তৈরি করা হয় এবং এর ফলে প্রচুর সংখ্যক পরিবর্তিত ফাইল তৈরি হয়। এই ধরনের অতিরিক্ত ফাইল OTA প্যাচের সাইজ বাড়িয়ে দেয় এবং কোন কোড পরিবর্তন করা হয়েছে তা নির্ধারণ করা কঠিন করে তোলে।

OTA-এর কন্টেন্ট আরও স্বচ্ছ করতে, AOSP-তে বিল্ড সিস্টেম পরিবর্তন অন্তর্ভুক্ত থাকে যা OTA প্যাচের সাইজ কমানোর জন্য ডিজাইন করা হয়েছে। বিল্ডের মধ্যে অপ্রয়োজনীয় ফাইল পরিবর্তন বাদ দেওয়া হয়েছে এবং OTA আপডেটে শুধুমাত্র প্যাচ-সম্পর্কিত ফাইল থাকে। এছাড়াও, AOSP-তে একটি বিল্ড ডিফারেন্স টুল অন্তর্ভুক্ত থাকে, যা একটি আরও পরিষ্কার বিল্ড ফাইল ডিফারেন্স প্রদান করতে, সাধারণ বিল্ড-সম্পর্কিত ফাইল পরিবর্তন ফিল্টার করে এবং একটি ব্লক ম্যাপিং টুল অন্তর্ভুক্ত থাকে, যা আপনাকে ব্লক অ্যাসাইনমেন্ট সামঞ্জস্যপূর্ণ রাখতে সাহায্য করে।

বিল্ড সিস্টেম বিভিন্ন উপায়ে অপ্রয়োজনীয়ভাবে বড় প্যাচ তৈরি করতে পারে। এটি কমানোর জন্য, Android 8.0 এবং এর পরের যেকোনও ভার্সনে, প্রতিটি ফাইলের ডিফের জন্য প্যাচ সাইজ কমানোর জন্য নতুন ফিচার ইমপ্লিমেন্ট করা হয়েছে। OTA-আপডেট প্যাকেজের সাইজ কমানোর জন্য করা উন্নতিগুলির মধ্যে এগুলি অন্তর্ভুক্ত:

  • নন-A/B ডিভাইস আপডেটে সম্পূর্ণ ইমেজের জন্য সাধারণ-উদ্দেশ্য, লসলেস-কম্প্রেশন অ্যালগরিদম ZSTD-এর ব্যবহার। কম্প্রেশন লেভেল বাড়িয়ে ZSTD-কে আরও বেশি কম্প্রেশন রেশিওর জন্য কাস্টমাইজ করা যেতে পারে। OTA জেনারেট করার সময় কম্প্রেশন লেভেল সেট করা হয় এবং ফ্ল্যাগ --vabc_compression_param=zstd,$COMPRESSION_LEVEL পাস করার মাধ্যমে এটি সেট করা যেতে পারে
  • OTA-এর সময় ব্যবহৃত কম্প্রেশন উইন্ডোর সাইজ বাড়ানো। ডিভাইসের .mk ফাইলে বিল্ড প্যারামিটার কাস্টমাইজ করে সর্বাধিক কম্প্রেশন উইন্ডো সাইজ সেট করা যেতে পারে। এই ভেরিয়েবলকে PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144 হিসেবে সেট করা হয়েছে
  • Puffin রিকমপ্রেশন ব্যবহার করা, এটি হল deflate স্ট্রিমের জন্য একটি ডিটারমিনিস্টিক প্যাচিং টুল, যা A/B OTA আপডেট জেনারেশনের জন্য কম্প্রেশন ও ডিফারেন্স ফাংশন ম্যানেজ করে।
  • ডেল্টা-জেনারেট করার টুলের ব্যবহার সংক্রান্ত পরিবর্তন, যেমন, কীভাবে bsdiff লাইব্রেরি প্যাচ কম্প্রেস করার জন্য ব্যবহার করা হয়। Android 9 ও তার পরের যেকোনও ভার্সনে, 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 দেখুন।

টাইমস্ট্যাম্প

সমস্যা: বিল্ড আউটপুটে টাইমস্ট্যাম্পের ফলে ফাইলে অপ্রয়োজনীয় পরিবর্তন হয়। নিম্নলিখিত লোকেশনে এটি হওয়ার সম্ভাবনা রয়েছে:

  • C বা C++ কোডে __DATE__/__TIME__/__TIMESTAMP__ ম্যাক্রো।
  • zip-ভিত্তিক আর্কাইভের মধ্যে এম্বেড করা টাইমস্ট্যাম্প।

সমাধান/উদাহরণ: বিল্ড আউটপুট থেকে টাইমস্ট্যাম্প সরাতে, নিচে দেওয়া নির্দেশাবলী C/C++-এ __DATE__/__TIME__/__TIMESTAMP__ এবং আর্কাইভের মধ্যে এম্বেড করা টাইমস্ট্যাম্প ব্যবহার করুন।

C/C++-এ __DATE__/__TIME__/__TIMESTAMP__

এইসব ম্যাক্রো সবসময় বিভিন্ন বিল্ডের জন্য বিভিন্ন আউটপুট তৈরি করে, তাই এগুলি ব্যবহার করবেন না। এই ম্যাক্রো বাদ দেওয়ার জন্য এখানে কয়েকটি বিকল্প দেওয়া হল:

আর্কাইভে (zip, jar) এম্বেড করা টাইমস্ট্যাম্প

Android 7.0, zip কমান্ডের সব ব্যবহার -X-এ যোগ করে zip আর্কাইভে এম্বেড করা টাইমস্ট্যাম্পের সমস্যা সমাধান করেছে। এর ফলে zip ফাইল থেকে বিল্ডারের UID/GID এবং এক্সটেন্ডেড Unix টাইমস্ট্যাম্প সরিয়ে দেওয়া হয়েছে।

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 টুল অটোমেটিক আপনার যাচাইকরণ কনফিগারেশন বেছে নেবে এবং ডিভাইসে যাচাইকরণ কম্পিউটেশন চালু করবে। এর ফলে, আপনার OTA প্যাকেজে কাঁচা বাইট হিসেবে সেভ না করে, android ডিভাইসে ভেরিটি ব্লক গণনা করা যায়। ভেরিটি ব্লক ২ জিবি পার্টিশনের জন্য আনুমানিক ১৬ এমবি ব্যবহার করতে পারে।

তবে, ডিভাইসে ভেরিটি কম্পিউট করতে অনেক সময় লাগতে পারে। বিশেষত, ফরওয়ার্ড এরর-কারেকশন কোড পেতে অনেক সময় লাগতে পারে। Pixel ডিভাইসে, এটি সাধারণত ১০ মিনিট পর্যন্ত সময় নেয়। কম দামের ডিভাইসে এটি আরও বেশি সময় নিতে পারে। আপনি যদি ডিভাইসে থাকা ভেরিটি কম্পিউটেশন বন্ধ করতে চান, কিন্তু তারপরেও dm-ভেরিটি চালু রাখতে চান, তাহলে OTA আপডেট জেনারেট করার সময় ota_from_target_files টুলে --disable_fec_computation পাস করে আপনি এটি করতে পারবেন। এই ফ্ল্যাগ OTA আপডেট চলাকালীন ডিভাইসে ভেরিটি কম্পিউটেশন বন্ধ করে দেয়। এটি OTA ইনস্টলেশন সময় কমায়, কিন্তু OTA প্যাকেজের সাইজ বাড়ায়। আপনার ডিভাইসে dm-verity চালু করা না থাকলে, এই ফ্ল্যাগ পাস করার কোনও প্রভাব পড়ে না।

কনসিস্টেন্ট বিল্ড টুল

সমস্যা: ইনস্টল করা ফাইল তৈরি করা টুলগুলিকে সামঞ্জস্যপূর্ণ হতে হবে (কোনও প্রদত্ত ইনপুটকে সবসময় একই আউটপুট তৈরি করতে হবে)।

সমাধান/উদাহরণ: নিম্নলিখিত বিল্ড টুলে পরিবর্তন করতে হবে:

  • NOTICE ফাইল ক্রিয়েটর। NOTICE ফাইল ক্রিয়েটরকে পরিবর্তন করে পুনরুৎপাদনযোগ্য NOTICE সংগ্রহ তৈরি করা হয়েছে। CL: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64 দেখুন।
  • Java Android Compiler Kit (Jack). জেনারেট করা কনস্ট্রাক্টর অর্ডারিংয়ে মাঝে মাঝে হওয়া পরিবর্তন ম্যানেজ করার জন্য Jack টুলচেন আপডেট করতে হবে। টুলচেনে কনস্ট্রাক্টরদের জন্য ডিটারমিনিস্টিক অ্যাক্সেসর যোগ করা হয়েছে: 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.
  • অ্যাপ্লিকেশন প্রি-ডেক্সঅপট (.odex) ফাইল। প্রি-ডেক্সঅপ্টিমাইজ (.odex) ফাইলগুলিতে ৬৪-বিট সিস্টেমে আনইনিশিয়ালাইজড প্যাডিং ছিল। এটি সংশোধন করা হয়েছে: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029.

বিল্ড ডিফারেন্স টুল ব্যবহার করা

যেসব ক্ষেত্রে বিল্ড-সম্পর্কিত ফাইল পরিবর্তনগুলি সরানো সম্ভব নয়, AOSP-তে বিল্ড ডিফারেন্স টুল, target_files_diff.py দুটি ফাইল প্যাকেজ তুলনা করার জন্য ব্যবহার করা হয়। এই টুলটি দুটি বিল্ডের মধ্যে রিকার্সিভ ডিফারেন্স পারফর্ম করে। এর মধ্যে সাধারণ বিল্ড-সম্পর্কিত ফাইল পরিবর্তন অন্তর্ভুক্ত থাকে না, যেমন

  • বিল্ড আউটপুটে প্রত্যাশিত পরিবর্তন (যেমন, বিল্ড নম্বর পরিবর্তনের কারণে)।
  • বর্তমান বিল্ড সিস্টেমে পরিচিত সমস্যার কারণে পরিবর্তন।

বিল্ড ডিফারেন্স টুল ব্যবহার করতে, নিম্নলিখিত কমান্ড রান করুন:

target_files_diff.py dir1 dir2

dir1 এবং dir2 হল বেস ডিরেক্টরি যাতে প্রতিটি বিল্ডের জন্য এক্সট্র্যাক্ট করা টার্গেট ফাইল থাকে।

ব্লক অ্যালোকেশন ধারাবাহিক রাখুন

কোনও নির্দিষ্ট ফাইলের ক্ষেত্রে, দুটি বিল্ডের মধ্যে এর কন্টেন্ট একই থাকলেও, ডেটা ধারণকারী প্রকৃত ব্লক পরিবর্তিত হতে পারে। এর ফলে, OTA আপডেটের জন্য ব্লকগুলি এদিক-ওদিক সরাতে আপডেটারকে অপ্রয়োজনীয় I/O পারফর্ম করতে হবে।

ভার্চুয়াল A/B OTA আপডেটে, অপ্রয়োজনীয় I/O, কপি-অন-রাইট স্ন্যাপশট স্টোর করার জন্য প্রয়োজনীয় স্টোরেজ স্পেস অনেক বাড়িয়ে দিতে পারে। নন-A/B OTA আপডেটে, OTA আপডেটের জন্য ব্লকগুলি এদিক-ওদিক সরানোর ফলে আপডেট হতে বেশি সময় লাগে কারণ ব্লক সরানোর জন্য আরও বেশি I/O হয়।

এই সমস্যার সমাধান করতে, Android 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 আপডেট পারফর্ম্যান্স উন্নত করে। ভার্চুয়াল A/B আপডেটের ক্ষেত্রে, OTA প্রয়োগ করার জন্য প্রয়োজনীয় স্টোরেজ স্পেসের পরিমাণ অনেক কমে যায়।

অ্যাপ আপডেট করা এড়িয়ে চলুন

বিল্ড ডিফারেন্স কমানোর পাশাপাশি, অ্যাপ স্টোরের মাধ্যমে আপডেট পাওয়া অ্যাপের জন্য আপডেট বাদ দিয়ে OTA আপডেট সাইজ কমাতে পারবেন। APKs প্রায়শই ডিভাইসের বিভিন্ন পার্টিশনের একটি গুরুত্বপূর্ণ অংশ নিয়ে গঠিত হয়। OTA আপডেটে অ্যাপ স্টোর দ্বারা আপডেট করা অ্যাপের লেটেস্ট ভার্সন সহ অন্যান্য অ্যাপের সাইজ OTA প্যাকেজের উপর বড় প্রভাব ফেলতে পারে এবং ব্যবহারকারীকে খুব কম সুবিধা দিতে পারে। ব্যবহারকারীরা OTA প্যাকেজ পাওয়ার আগেই, তাদের কাছে আপডেট করা অ্যাপ বা আরও নতুন ভার্সন থাকতে পারে, যা সরাসরি অ্যাপ স্টোর থেকে পাওয়া যায়।