OTA برای دستگاه‌های غیر A/B با پارتیشن‌های پویا

‫Android 10 از پارتیشن‌های پویا، سیستم پارتیشن‌بندی فضای کاربر که می‌تواند درطول به‌روزرسانی‌های ازطریق هوا (OTA) پارتیشن‌ها را ایجاد، تغییر اندازه، و حذف کند، پشتیبانی می‌کند.

این صفحه نحوه تغییر اندازه پارتیشن‌های پویا توسط کارخواه‌های OTA درطول به‌روزرسانی برای دستگاه‌های غیر A/B را شرح می‌دهد.

برای دستگاه‌های غیر A/B، به‌روزرسانی OTA برای پارتیشن‌های پویا بااستفاده از updater داخل بسته به‌روزرسانی اعمال می‌شود.

به‌روزرسانی دستگاه‌های راه‌اندازی

این بخش مربوط به دستگاه‌های غیر A/B است که با پشتیبانی از پارتیشن‌های پویا راه‌اندازی می‌شوند؛ این دستگاه‌ها از Android 10 به نسخه‌های بالاتر ارتقا می‌یابند.

تولید بسته‌های به‌روزرسانی

بسته‌های به‌روزرسانی ازطریق هوا توسط برنامه ota_from_target_files تولید می‌شود که در build/make/tools/releasetools قرار دارد. به‌طور پیش‌فرض، این دستورگان بسته‌ای تولید می‌کند که system و vendor پارتیشن را به‌روزرسانی می‌کند. اگر پارتیشن‌های پویای دیگری مثل product، product_services، یا odm وجود داشته باشد، به‌روزرسانی‌های آن‌ها باید در کد مخصوص دستگاه تولید شود.

برای تولید به‌روزرسانی‌ها، در واحد Python توسعه‌یافته، FullOTA_GetBlockDifferences() و IncrementalOTA_GetBlockDifferences() را پیاده‌سازی کنید. این دو تابع فهرستی از BlockDifference شیء برمی‌گردانند که هرکدام وصله به‌روزرسانی را که روی پارتیشن اعمال می‌شود توصیف می‌کنند. بخش‌های برگشتی از این دو تابع نباید به‌صورت دستی اصلاح شوند یا در جای دیگری، مثلاً در *_InstallBegin() یا *_InstallEnd()، درستی‌سنجی شوند.

مثالی از تولید به‌روزرسانی:

# device/yoyodyne/tardis/releasetools.py

import os
from common import BlockDifference, EmptyImage, GetUserImage

# The joined list of user image partitions of source and target builds.
# - Items should be added to the list if new dynamic partitions are added.
# - Items should not be removed from the list even if dynamic partitions are
#   deleted. When generating an incremental OTA package, this script needs to
#   know that an image is present in source build but not in target build.
USERIMAGE_PARTITIONS = [
    "product",
    "odm",
]

def GetUserImages(input_tmp, input_zip):
  return {partition: GetUserImage(partition, input_tmp, input_zip)
          for partition in USERIMAGE_PARTITIONS
          if os.path.exists(os.path.join(input_tmp,
                                         "IMAGES", partition + ".img"))}

def FullOTA_GetBlockDifferences(info):
  images = GetUserImages(info.input_tmp, info.input_zip)
  return [BlockDifference(partition, image)
          for partition, image in images.items()]

def IncrementalOTA_GetBlockDifferences(info):
  source_images = GetUserImages(info.source_tmp, info.source_zip)
  target_images = GetUserImages(info.target_tmp, info.target_zip)

  # Use EmptyImage() as a placeholder for partitions that will be deleted.
  for partition in source_images:
    target_images.setdefault(partition, EmptyImage())

  # Use source_images.get() because new partitions are not in source_images.
  return [BlockDifference(partition, target_image, source_images.get(partition))
          for partition, target_image in target_images.items()]

به‌روزرسانی جریان

در پشت صحنه، توابع زیر به اسکریپت edify اضافه می‌شوند:

  • unmap_partition(name)
    • اگر پارتیشن تخصیص داده شده است، تخصیص آن را لغو می‌کند، درغیراین‌صورت کاری انجام نمی‌دهد.
    • درصورت موفقیت، رشته t را برمی‌گرداند، یا درصورت عدم موفقیت، رشته‌ای خالی را برمی‌گرداند.
  • map_partition(name)
    • اگر پارتیشن قبلاً نگاشت نشده است، آن را نگاشت کنید.
    • درصورت موفقیت، مسیر مطلق دستگاه بلوک نگاشت‌شده را برمی‌گرداند، و درصورت عدم موفقیت، رشته خالی برمی‌گرداند.
  • update_dynamic_partitions(op_list)
    • فهرست عملیات داده‌شده را روی فراداده‌های پارتیشن پویا اعمال کنید، درصورت لزوم، پارتیشن‌ها را لغو تخصیص دهید.
    • درصورت موفقیت، t را برمی‌گرداند، یا درصورت ناموفق بودن، رشته‌ای خالی را برمی‌گرداند.

گزینه op_list برای update_dynamic_partitions به فایلی در بسته به‌روزرسانی اشاره می‌کند. هر خط در فایل یک عملیات را مشخص می‌کند. اگر هریک از عملیات‌ها ناموفق باشد، update_dynamic_partitions فوراً رشته خالی برمی‌گرداند. عملیات‌ها عبارت‌اند از:

  • resize partition-name size
    • پارتیشن را لغو نگاشت کنید، سپس اندازه آن را به size تغییر دهید.
  • remove partition_name
    • بخش را از نقشه بردارید، سپس آن را بردارید.
  • add partition-name group-name
    • افزودن بخش جدید به گروه مشخص‌شده.
    • اگر گروه وجود ندارد یا اگر بخش ازقبل وجود دارد، عملیات را متوقف کنید.
  • move partition-name group-name
    • انتقال پارتیشن به گروه مشخص‌شده.
    • اگر گروه وجود ندارد یا بخش وجود ندارد، عملیات را لغو کنید.
  • add_group group-name maximum-size
    • گروهی با نام و اندازه حداکثر داده‌شده اضافه کنید.
    • اگر گروه ازقبل وجود دارد، عملیات را متوقف کنید.
    • maximum_size صفر یعنی هیچ محدودیت اندازه‌ای برای پارتیشن‌های گروه وجود ندارد. آزمایش‌های بیشتری لازم است تا مطمئن شویم که پارتیشن‌های گروه از فضای دردسترس در دستگاه فراتر نمی‌روند.
  • resize_group group-name maximum-size
    • اندازه گروه را به حداکثر اندازه داده‌شده تغییر دهید.
    • اگر گروه وجود ندارد، عملیات را متوقف کنید.
    • maximum_size صفر یعنی هیچ محدودیت اندازه‌ای برای پارتیشن‌های گروه وجود ندارد. آزمایش‌های بیشتری لازم است تا مطمئن شویم که پارتیشن‌های گروه از فضای دردسترس در دستگاه فراتر نمی‌روند.
  • remove_group group-name
    • برداشتن گروه.
    • اگر پارتیشن‌هایی در گروه وجود دارد، لغو شود.
  • remove_all_groups
    • لغو نگاشت همه پارتیشن‌ها از نگاشت‌گر دستگاه.
    • همه پارتیشن‌ها و گروه‌ها را بردارید.

افزایشی ازطریق هوا

به‌روزرسانی‌های افزایشی ازطریق هوا از منطق زیر استفاده می‌کنند:

  1. کوچک کردن پارتیشن‌ها/حذف پارتیشن‌ها/انتقال پارتیشن‌ها به خارج از گروه (به‌طوری که فضای کافی برای کوچک کردن گروه‌ها وجود داشته باشد)
  2. کوچک کردن گروه‌ها (تا فضای کافی برای رشد گروه‌ها وجود داشته باشد)
  3. گروه‌ها را افزایش دهید (تا فضای کافی برای افزایش/افزودن پارتیشن‌ها داشته باشیم)
  4. افزایش پارتیشن‌ها/افزودن پارتیشن‌ها/انتقال پارتیشن‌ها به گروه جدید

به‌طور دقیق، update-script با این منطق تولید می‌شود: منطق:

for each shrinking partition:
    block_image_update(map_partition(name), …)

update_dynamic_partitions(op_list)

for each growing / adding partition:
    block_image_update(map_partition(name), …)

فایل op_list برای update_dynamic_partitions با این منطق تولید می‌شود:

for each deleting partition:
    remove
for each partition that changes groups:
    move to "default"
for each shrinking partition:
    resize
for each shrinking / removing group:
    resize_group / remove_group
for each growing / adding group:
    resize_group / add_group
for each adding partition:
    add
for each growing / adding partition:
    resize
for each partition that changes groups:
    move to target group

OTA کامل

به‌روزرسانی‌های کامل ازطریق هوا از منطق زیر استفاده می‌کنند:

  1. حذف همه گروه‌ها و پارتیشن‌های موجود
  2. افزودن گروه‌ها
  3. افزودن پارتیشن

به‌طور دقیق، update-script با این منطق تولید می‌شود: منطق:

update_dynamic_partitions(op_list)

for each adding partition:
    block_image_update(map_partition(name), …)

فایل op_list برای update_dynamic_partitions با این منطق تولید می‌شود:

remove_all_groups
for each adding group:
    add_group
for each adding partition:
    add
for each adding partition:
    resize