بهروزرسانیهای سیستم قدیمی A/B، که با نام بهروزرسانیهای یکپارچه نیز شناخته میشوند، تضمین میکنند که یک سیستم بوت کارآمد در طول بهروزرسانی از طریق هوا (OTA) روی دیسک باقی بماند. این رویکرد احتمال غیرفعال شدن دستگاه پس از بهروزرسانی را کاهش میدهد، که به معنای تعویض کمتر دستگاه و فلش مجدد دستگاه در مراکز تعمیر و گارانتی است. سایر سیستمعاملهای تجاری مانند ChromeOS نیز با موفقیت از بهروزرسانیهای A/B استفاده میکنند.
برای اطلاعات بیشتر در مورد بهروزرسانیهای سیستم A/B و نحوه عملکرد آنها، به بخش انتخاب پارتیشن (اسلاتها) مراجعه کنید.
بهروزرسانیهای سیستم A/B مزایای زیر را ارائه میدهند:
- بهروزرسانیهای OTA میتوانند در حین اجرای سیستم و بدون ایجاد وقفه در کار کاربر انجام شوند. کاربران میتوانند در طول OTA به استفاده از دستگاههای خود ادامه دهند - تنها زمان از کار افتادگی در طول بهروزرسانی، زمانی است که دستگاه در پارتیشن دیسک بهروزرسانیشده، مجدداً راهاندازی میشود.
- پس از بهروزرسانی، راهاندازی مجدد دستگاه بیشتر از یک راهاندازی مجدد معمولی طول نمیکشد.
- اگر بهروزرسانی OTA اعمال نشود (مثلاً به دلیل فلش بد)، کاربر تحت تأثیر قرار نمیگیرد. کاربر به اجرای سیستمعامل قدیمی ادامه خواهد داد و کلاینت میتواند دوباره برای بهروزرسانی تلاش کند.
- اگر بهروزرسانی OTA اعمال شود اما بوت نشود، دستگاه دوباره به پارتیشن قدیمی راهاندازی مجدد میشود و قابل استفاده باقی میماند. کلاینت میتواند دوباره برای بهروزرسانی تلاش کند.
- هرگونه خطایی (مانند خطاهای ورودی/خروجی) فقط بر مجموعه پارتیشنهای استفاده نشده تأثیر میگذارد و میتوان دوباره امتحان کرد. احتمال چنین خطاهایی نیز کمتر میشود زیرا بار ورودی/خروجی عمداً کم است تا از کاهش تجربه کاربری جلوگیری شود.
- بهروزرسانیها میتوانند به دستگاههای A/B منتقل شوند و دیگر نیازی به دانلود بسته قبل از نصب نباشد. انتقال به این معنی است که کاربر نیازی به فضای خالی کافی برای ذخیره بسته بهروزرسانی در
/dataیا/cacheندارد. - پارتیشن کش دیگر برای ذخیره بستههای بهروزرسانی OTA استفاده نمیشود، بنابراین نیازی به اطمینان از اینکه پارتیشن کش برای بهروزرسانیهای آینده به اندازه کافی بزرگ است، نیست.
- dm-verity تضمین میکند که دستگاه، یک ایمیج بدون مشکل را بوت کند. اگر دستگاهی به دلیل مشکل OTA یا dm-verity بوت نشود، دستگاه میتواند با یک ایمیج قدیمی مجدداً راهاندازی شود. (Android Verified Boot نیازی به بهروزرسانیهای A/B ندارد.)
درباره بهروزرسانیهای سیستم A/B
بهروزرسانیهای A/B نیاز به تغییراتی هم در کلاینت و هم در سیستم دارند. با این حال، سرور بسته OTA نباید نیازی به تغییرات داشته باشد: بستههای بهروزرسانی همچنان از طریق HTTPS ارائه میشوند. برای دستگاههایی که از زیرساخت OTA گوگل استفاده میکنند، تغییرات سیستمی همگی در AOSP هستند و کد کلاینت توسط سرویسهای Google Play ارائه میشود. تولیدکنندگان اصلی تجهیزات (OEM) که از زیرساخت OTA گوگل استفاده نمیکنند، میتوانند از کد سیستم AOSP دوباره استفاده کنند، اما باید کلاینت خود را ارائه دهند.
برای تولیدکنندگان اصلی تجهیزات (OEM) که به مشتری خود خدمات ارائه میدهند، مشتری باید:
- تصمیم بگیرید چه زمانی بهروزرسانی انجام شود. از آنجا که بهروزرسانیهای A/B در پسزمینه اتفاق میافتند، دیگر توسط کاربر آغاز نمیشوند. برای جلوگیری از ایجاد اختلال در کاربران، توصیه میشود بهروزرسانیها زمانی برنامهریزی شوند که دستگاه در حالت تعمیر و نگهداری غیرفعال، مانند شب هنگام، و در حالت اتصال به Wi-Fi باشد. با این حال، کلاینت شما میتواند از هر روش اکتشافی که میخواهید استفاده کند.
- با سرورهای بسته OTA خود تماس بگیرید و بررسی کنید که آیا بهروزرسانی در دسترس است یا خیر. این کد باید تقریباً مشابه کد کلاینت فعلی شما باشد، با این تفاوت که باید تأیید کنید که دستگاه از A/B پشتیبانی میکند. (کلاینت گوگل همچنین شامل یک دکمه Check now برای کاربران است تا آخرین بهروزرسانی را بررسی کنند.)
- با فرض اینکه بسته بهروزرسانی شما در دسترس باشد، تابع
update_engineبا آدرس HTTPS آن فراخوانی کنید.update_engineبلوکهای خام روی پارتیشنی که در حال حاضر استفاده نمیشود را همزمان با استریم بسته بهروزرسانی، بهروزرسانی میکند. - بر اساس کد نتیجه
update_engineموفقیت یا عدم موفقیت نصب را به سرورهای خود گزارش دهید. اگر بهروزرسانی با موفقیت اعمال شود،update_engineبه بوتلودر میگوید که در راهاندازی مجدد بعدی، سیستمعامل جدید را بوت کند. اگر سیستمعامل جدید نتواند بوت شود، بوتلودر به سیستمعامل قدیمی برمیگردد، بنابراین نیازی به انجام هیچ کاری از سوی کلاینت نیست. اگر بهروزرسانی با شکست مواجه شود، کلاینت باید بر اساس کد خطای دقیق، تصمیم بگیرد که چه زمانی (و آیا) دوباره امتحان کند. به عنوان مثال، یک کلاینت خوب میتواند تشخیص دهد که یک بسته OTA جزئی ("diff") با شکست مواجه میشود و به جای آن یک بسته OTA کامل را امتحان کند.
به صورت اختیاری، مشتری میتواند:
- اعلانی را نمایش دهید که از کاربر بخواهد سیستم را مجدداً راهاندازی کند. اگر میخواهید سیاستی را پیادهسازی کنید که در آن کاربر تشویق به بهروزرسانی منظم شود، میتوانید این اعلان را به کلاینت خود اضافه کنید. اگر کلاینت به کاربران اطلاع ندهد، کاربران دفعه بعد که سیستم را مجدداً راهاندازی کنند، بهروزرسانی را دریافت خواهند کرد. (کلاینت گوگل دارای تأخیر قابل تنظیم برای هر بهروزرسانی است.)
- اعلانی را نشان دهید که به کاربران میگوید آیا آنها به نسخه جدید سیستم عامل بوت شدهاند یا اینکه انتظار میرفت این کار را انجام دهند اما به نسخه قدیمی سیستم عامل برگشتهاند. (کلاینت گوگل معمولاً هیچکدام را انجام نمیدهد.)
از نظر سیستمی، بهروزرسانیهای سیستم A/B موارد زیر را تحت تأثیر قرار میدهند:
- انتخاب پارتیشن (اسلاتها)، دیمن
update_engineو تعاملات بوتلودر (در زیر شرح داده شده است) - فرآیند ساخت و تولید بسته بهروزرسانی OTA (در پیادهسازی بهروزرسانیهای A/B توضیح داده شده است)
انتخاب پارتیشن (اسلاتها)
بهروزرسانیهای سیستم A/B از دو مجموعه پارتیشن که به عنوان اسلات (معمولاً اسلات A و اسلات B) شناخته میشوند، استفاده میکنند. سیستم از اسلات فعلی اجرا میشود در حالی که پارتیشنهای اسلات استفاده نشده در طول عملیات عادی توسط سیستم در حال اجرا قابل دسترسی نیستند. این رویکرد با نگه داشتن اسلات استفاده نشده به عنوان یک جایگزین، بهروزرسانیها را در برابر خطا مقاوم میکند: اگر در حین یا بلافاصله پس از بهروزرسانی خطایی رخ دهد، سیستم میتواند به اسلات قدیمی برگردد و به داشتن یک سیستم کارآمد ادامه دهد. برای دستیابی به این هدف، هیچ پارتیشنی که توسط اسلات فعلی استفاده میشود نباید به عنوان بخشی از بهروزرسانی OTA بهروزرسانی شود (از جمله پارتیشنهایی که فقط یک نسخه از آنها وجود دارد).
هر اسلات یک ویژگی قابل بوت دارد که بیان میکند آیا اسلات شامل سیستم صحیحی است که دستگاه میتواند از آن بوت شود یا خیر. اسلات فعلی هنگام اجرای سیستم قابل بوت است، اما اسلات دیگر ممکن است دارای یک نسخه قدیمی (هنوز صحیح) از سیستم، یک نسخه جدیدتر یا دادههای نامعتبر باشد. صرف نظر از اسلات فعلی ، یک اسلات وجود دارد که اسلات فعال (اسلات بوت لودر در بوت بعدی از آن بوت میشود) یا اسلات ترجیحی است .
هر اسلات همچنین دارای یک ویژگی موفق است که توسط فضای کاربر تنظیم میشود، که تنها در صورتی مرتبط است که اسلات قابل بوت شدن نیز باشد. یک اسلات موفق باید بتواند خود را بوت، اجرا و بهروزرسانی کند. یک اسلات قابل بوت که به عنوان موفق علامتگذاری نشده است (پس از چندین تلاش برای بوت شدن از آن) باید توسط بوت لودر به عنوان غیرقابل بوت علامتگذاری شود، از جمله تغییر اسلات فعال به اسلات قابل بوت دیگر (معمولاً به اسلاتی که بلافاصله قبل از تلاش برای بوت شدن به اسلات جدید و فعال در حال اجرا است). جزئیات خاص رابط در boot_control.h تعریف شده است.
بهروزرسانی دیمن موتور
بهروزرسانیهای سیستم A/B از یک سرویس پسزمینه به نام update_engine برای آمادهسازی سیستم جهت بوت شدن به یک نسخه جدید و بهروزرسانیشده استفاده میکنند. این سرویس میتواند اقدامات زیر را انجام دهد:
- طبق دستورالعمل بسته OTA، از پارتیشنهای A/B اسلات فعلی اطلاعات را بخوانید و هرگونه دادهای را در پارتیشنهای A/B اسلات استفاده نشده بنویسید.
- رابط
boot_controlرا در یک گردش کار از پیش تعریف شده فراخوانی کنید. - پس از نوشتن تمام پارتیشنهای اسلات استفاده نشده، طبق دستورالعمل بسته OTA، یک برنامه پس از نصب را از پارتیشن جدید اجرا کنید. (برای جزئیات بیشتر، به بخش پس از نصب مراجعه کنید).
از آنجایی که سرویس update_engine در خود فرآیند بوت دخیل نیست، در طول بهروزرسانی توسط سیاستها و ویژگیهای SELinux در اسلات فعلی ، در کارهایی که میتواند انجام دهد، محدود است (چنین سیاستها و ویژگیهایی تا زمانی که سیستم به نسخه جدیدی بوت نشود، نمیتوانند بهروزرسانی شوند). برای حفظ یک سیستم قوی، فرآیند بهروزرسانی نباید جدول پارتیشن، محتوای پارتیشنها در اسلات فعلی یا محتوای پارتیشنهای غیر A/B که نمیتوان با تنظیم مجدد کارخانه پاک کرد را تغییر دهد.
منبع موتور را بهروزرسانی کنید
منبع update_engine در system/update_engine قرار دارد. فایلهای dexopt OTA نوع A/B بین installd و یک مدیر بسته تقسیم میشوند:
-
frameworks/native/cmds/installd/ota* شامل اسکریپت postinstall، فایل باینری chroot، کلون installd که dex2oat را فراخوانی میکند، اسکریپت move-artifacts مربوط به post-OTA و فایل rc مربوط به اسکریپت move است. -
frameworks/base/services/core/java/com/android/server/pm/OtaDexoptService.java(بهعلاوهOtaDexoptShellCommand) مدیر بستهای است که دستورات dex2oat را برای برنامهها آماده میکند.
برای یک مثال کاربردی، به /device/google/marlin/device-common.mk مراجعه کنید.
بهروزرسانی گزارشهای موتور
برای نسخههای اندروید ۸.x و قبل از آن، گزارشهای update_engine را میتوان در logcat و در گزارش اشکال یافت. برای اینکه گزارشهای update_engine در سیستم فایل در دسترس باشند، تغییرات زیر را در نسخه خود پچ کنید:
این تغییرات یک کپی از جدیدترین لاگ update_engine در مسیر /data/misc/update_engine_log/update_engine. YEAR - TIME . علاوه بر لاگ فعلی، پنج لاگ اخیر در مسیر /data/misc/update_engine_log/ ذخیره میشوند. کاربرانی که شناسه گروه لاگ را دارند، میتوانند به لاگهای سیستم فایل دسترسی داشته باشند.
تعاملات بوتلودر
boot_control HAL توسط update_engine (و احتمالاً سایر سرویسها) برای تعیین اینکه بوت لودر از چه چیزی بوت شود، استفاده میشود. سناریوهای مثال رایج و حالتهای مرتبط با آنها شامل موارد زیر است:
- حالت عادی : سیستم از اسلات فعلی خود، چه اسلات A و چه اسلات B، در حال اجرا است. تاکنون هیچ بهروزرسانی اعمال نشده است. اسلات فعلی سیستم قابل بوت، موفقیتآمیز و اسلات فعال است.
- بهروزرسانی در حال انجام است : سیستم از اسلات B در حال اجرا است، بنابراین اسلات B اسلات قابل بوت، موفق و فعال است. اسلات A به عنوان غیرقابل بوت علامتگذاری شده است زیرا محتویات اسلات A در حال بهروزرسانی هستند اما هنوز تکمیل نشدهاند. راهاندازی مجدد در این حالت باید بوت شدن از اسلات B را ادامه دهد.
- بهروزرسانی اعمال شد، راهاندازی مجدد در انتظار : سیستم از اسلات B در حال اجرا است، اسلات B قابل بوت و با موفقیت انجام شده است، اما اسلات A به عنوان فعال علامتگذاری شده است (و بنابراین به عنوان قابل بوت علامتگذاری شده است). اسلات A هنوز به عنوان موفق علامتگذاری نشده است و بوتلودر باید چندین بار برای بوت شدن از اسلات A تلاش کند.
- سیستم برای بهروزرسانی جدید راهاندازی مجدد شد : سیستم برای اولین بار از اسلات A اجرا میشود، اسلات B هنوز قابل بوت و موفق است در حالی که اسلات A فقط قابل بوت است و هنوز فعال است اما موفق نیست. یک سرویس فضای کاربر،
update_verifier، باید اسلات A را پس از انجام برخی بررسیها، به عنوان اسلات موفق علامتگذاری کند.
پشتیبانی از بهروزرسانی استریم
دستگاههای کاربران همیشه فضای کافی در /data برای دانلود بسته بهروزرسانی ندارند. از آنجایی که نه تولیدکنندگان اصلی تجهیزات (OEM) و نه کاربران نمیخواهند فضای پارتیشن /cache را هدر دهند، برخی از کاربران بدون بهروزرسانی کار میکنند زیرا دستگاه جایی برای ذخیره بسته بهروزرسانی ندارد. برای رفع این مشکل، اندروید ۸.۰ پشتیبانی از بهروزرسانیهای A/B استریمینگ را اضافه کرده است که بلوکها را مستقیماً هنگام دانلود در پارتیشن B مینویسند، بدون اینکه نیازی به ذخیره بلوکها در /data . بهروزرسانیهای A/B استریمینگ تقریباً به هیچ فضای ذخیرهسازی موقت نیاز ندارند و فقط به فضای ذخیرهسازی کافی برای تقریباً ۱۰۰ کیلوبایت فراداده نیاز دارند.
برای فعال کردن بهروزرسانیهای استریمینگ در اندروید ۷.۱، پچهای زیر را انتخاب کنید:
- اجازه لغو درخواست حل اختلاف با پروکسی
- رفع مشکل خاتمه انتقال هنگام حل و فصل پروکسیها
- اضافه کردن تست واحد برای TerminateTransfer بین محدودهها
- پاکسازی RetryTimeoutCallback()
این وصلهها برای پشتیبانی از بهروزرسانیهای A/B در اندروید ۷.۱ و بالاتر، چه با استفاده از سرویسهای موبایل گوگل (GMS) و چه با استفاده از هر کلاینت بهروزرسانی دیگری، مورد نیاز هستند.
طول عمر یک بهروزرسانی A/B
فرآیند بهروزرسانی زمانی شروع میشود که یک بسته OTA (که در کد به عنوان payload شناخته میشود) برای دانلود در دسترس باشد. سیاستهای موجود در دستگاه ممکن است دانلود payload و اجرای برنامه را بر اساس میزان باتری، فعالیت کاربر، وضعیت شارژ یا سایر سیاستها به تعویق بیندازند. علاوه بر این، از آنجا که بهروزرسانی در پسزمینه اجرا میشود، ممکن است کاربران از در حال انجام بودن بهروزرسانی مطلع نشوند. همه اینها به این معنی است که فرآیند بهروزرسانی ممکن است در هر نقطهای به دلیل سیاستها، راهاندازیهای مجدد غیرمنتظره یا اقدامات کاربر قطع شود.
به صورت اختیاری، فرادادههای موجود در خود بسته OTA نشان میدهند که بهروزرسانی میتواند به صورت استریم ارسال شود؛ همین بسته میتواند برای نصب غیر استریم نیز استفاده شود. سرور ممکن است از فرادادهها برای اطلاعرسانی به کلاینت در حال استریم استفاده کند تا کلاینت OTA را به درستی به update_engine تحویل دهد. تولیدکنندگان دستگاه با سرور و کلاینت خودشان میتوانند با اطمینان از اینکه سرور تشخیص میدهد بهروزرسانی در حال استریم است (یا فرض میکند همه بهروزرسانیها در حال استریم هستند) و کلاینت فراخوانی صحیح update_engine را برای استریم انجام میدهد، بهروزرسانیهای استریم را فعال کنند. تولیدکنندگان میتوانند از این واقعیت که بسته از نوع استریم است برای ارسال یک پرچم به کلاینت استفاده کنند تا به عنوان استریم، تحویل به سمت چارچوب را آغاز کند.
پس از در دسترس قرار گرفتن یک payload، فرآیند بهروزرسانی به شرح زیر است:
| قدم | فعالیتها |
|---|---|
| ۱ | اسلات فعلی (یا "اسلات منبع") با استفاده از markBootSuccessful() به عنوان موفق (اگر از قبل علامتگذاری نشده باشد) علامتگذاری میشود. |
| ۲ | اسلات استفاده نشده (یا "اسلات هدف") با فراخوانی تابع setSlotAsUnbootable() به عنوان غیرقابل بوت علامتگذاری میشود. اسلات فعلی همیشه در ابتدای بهروزرسانی به عنوان موفق علامتگذاری میشود تا از بازگشت بوت لودر به اسلات استفاده نشده، که به زودی دادههای نامعتبر خواهد داشت، جلوگیری شود. اگر سیستم به نقطهای رسیده باشد که بتواند شروع به اعمال بهروزرسانی کند، اسلات فعلی حتی اگر سایر اجزای اصلی خراب باشند (مانند رابط کاربری در یک حلقه خرابی) به عنوان موفق علامتگذاری میشود، زیرا میتوان نرمافزار جدیدی را برای رفع این مشکلات ارائه داد.فایل بهروزرسانی یک حباب مبهم با دستورالعملهای بهروزرسانی به نسخه جدید است. فایل بهروزرسانی شامل موارد زیر است:
|
| ۳ | متادیتای مربوط به payload دانلود میشود. |
| ۴ | برای هر عملیات تعریف شده در فراداده، به ترتیب، دادههای مرتبط (در صورت وجود) در حافظه دانلود میشوند، عملیات اعمال میشود و حافظه مرتبط دور ریخته میشود. |
| ۵ | کل پارتیشنها دوباره خوانده شده و با هش مورد انتظار مطابقت داده میشوند. |
| ۶ | مرحله پس از نصب (در صورت وجود) اجرا میشود. در صورت بروز خطا در طول اجرای هر مرحله، بهروزرسانی با شکست مواجه میشود و احتمالاً با یک payload متفاوت دوباره تلاش میشود. اگر تمام مراحل تاکنون موفقیتآمیز بوده باشند، بهروزرسانی با موفقیت انجام میشود و آخرین مرحله اجرا میشود. |
| ۷ | اسلات استفاده نشده با فراخوانی تابع setActiveBootSlot() به عنوان فعال علامتگذاری میشود. علامتگذاری اسلات استفاده نشده به عنوان فعال به این معنی نیست که بوت شدن آن تمام میشود. بوت لودر (یا خود سیستم) میتواند در صورت عدم موفقیت، اسلات فعال را به حالت اولیه برگرداند. |
| ۸ | پس از نصب (که در زیر توضیح داده شده است) شامل اجرای برنامه از نسخه "بهروزرسانی جدید" در حالی که هنوز در نسخه قدیمی در حال اجرا است، میشود. اگر در بسته OTA تعریف شده باشد، این مرحله اجباری است و برنامه باید با کد خروج 0 بازگردد؛ در غیر این صورت، بهروزرسانی با شکست مواجه میشود. | ۹ | پس از اینکه سیستم با موفقیت به اندازه کافی در اسلات جدید بوت شد و بررسیهای پس از راهاندازی مجدد را به پایان رساند، اسلات فعلی (که قبلاً "اسلات هدف" نام داشت) با فراخوانی markBootSuccessful() به عنوان اسلات موفق علامتگذاری میشود. |
پس از نصب
برای هر پارتیشنی که یک مرحله پس از نصب تعریف شده است، update_engine پارتیشن جدید را در یک مکان خاص نصب میکند و برنامه مشخص شده در OTA را نسبت به پارتیشن نصب شده اجرا میکند. به عنوان مثال، اگر برنامه پس از نصب به صورت usr/bin/postinstall در پارتیشن سیستم تعریف شده باشد، این پارتیشن از اسلات استفاده نشده در یک مکان ثابت (مانند /postinstall_mount ) نصب میشود و دستور /postinstall_mount/usr/bin/postinstall اجرا میشود.
برای موفقیتآمیز بودن نصب پس از نصب، هسته قدیمی باید بتواند:
- فرمت سیستم فایل جدید را نصب کنید . نوع سیستم فایل نمیتواند تغییر کند مگر اینکه در هسته قدیمی از آن پشتیبانی شود، از جمله جزئیاتی مانند الگوریتم فشردهسازی مورد استفاده در صورت استفاده از سیستم فایل فشرده (مثلاً SquashFS).
- فرمت برنامه پس از نصب پارتیشن جدید را درک کنید . اگر از فایل باینری Executable and Linkable Format (ELF) استفاده میکنید، باید با هسته قدیمی سازگار باشد (مثلاً یک برنامه جدید ۶۴ بیتی که روی یک هسته قدیمی ۳۲ بیتی اجرا میشود اگر معماری از ۳۲ بیتی به ۶۴ بیتی تغییر کند). مگر اینکه به لودر (
ld) دستور داده شود که از مسیرهای دیگری استفاده کند یا یک فایل باینری استاتیک بسازد، کتابخانهها از تصویر سیستم قدیمی و نه از تصویر جدید بارگذاری میشوند.
برای مثال، میتوانید از یک اسکریپت پوسته به عنوان یک برنامه پس از نصب که توسط باینری پوسته سیستم قدیمی با علامت #! در بالا تفسیر میشود، استفاده کنید (سپس مسیرهای کتابخانه را از محیط جدید برای اجرای یک برنامه پس از نصب باینری پیچیدهتر تنظیم کنید. به عنوان یک روش جایگزین، میتوانید مرحله پس از نصب را از یک پارتیشن کوچکتر اختصاصی اجرا کنید تا فرمت سیستم فایل در پارتیشن اصلی سیستم بدون بروز مشکلات سازگاری با نسخههای قبلی یا بهروزرسانیهای اولیه بهروزرسانی شود. این به کاربران امکان میدهد مستقیماً از یک تصویر کارخانه به آخرین نسخه بهروزرسانی کنند.
برنامه جدید پس از نصب توسط سیاستهای SELinux تعریف شده در سیستم قدیمی محدود شده است. به همین دلیل، مرحله پس از نصب برای انجام وظایف مورد نیاز طراحی بر روی یک دستگاه معین یا سایر وظایف با بهترین تلاش مناسب است. مرحله پس از نصب برای رفع اشکالات یکباره قبل از راهاندازی مجدد که نیاز به مجوزهای پیشبینی نشده دارند، مناسب نیست .
برنامهی پس از نصب انتخابشده در زمینهی postinstall SELinux اجرا میشود. تمام فایلهای موجود در پارتیشن جدید نصبشده، صرفنظر از ویژگیهایشان پس از راهاندازی مجدد در آن سیستم جدید، با postinstall_file برچسبگذاری میشوند. تغییرات در ویژگیهای SELinux در سیستم جدید، مرحلهی پس از نصب را تحت تأثیر قرار نمیدهد. اگر برنامهی پس از نصب به مجوزهای اضافی نیاز داشته باشد، باید آنها را به زمینهی پس از نصب اضافه کرد.
بعد از راه اندازی مجدد
پس از راهاندازی مجدد، update_verifier بررسی یکپارچگی را با استفاده از dm-verity آغاز میکند. این بررسی قبل از zygote شروع میشود تا از ایجاد هرگونه تغییر برگشتناپذیر توسط سرویسهای جاوا که مانع از بازگشت امن میشود، جلوگیری شود. در طول این فرآیند، در صورت تأیید بوت یا تشخیص هرگونه خرابی توسط dm-verity، بوتلودر و هسته نیز ممکن است راهاندازی مجدد را آغاز کنند. پس از اتمام بررسی، update_verifier بوت را موفقیتآمیز اعلام میکند.
update_verifier فقط بلوکهای فهرستشده در /data/ota_package/care_map.txt را میخواند، که هنگام استفاده از کد AOSP در یک بسته A/B OTA گنجانده شده است. کلاینت بهروزرسانی سیستم جاوا، مانند GmsCore، care_map.txt را استخراج میکند، قبل از راهاندازی مجدد دستگاه، مجوز دسترسی را تنظیم میکند و پس از بوت شدن موفقیتآمیز سیستم در نسخه جدید، فایل استخراجشده را حذف میکند.