OTA للأجهزة غير A/B ذات الأقسام الديناميكية

يدعم Android 10 الأقسام الديناميكية ، وهو نظام تقسيم مساحة المستخدم الذي يمكنه إنشاء الأقسام وتغيير حجمها وتدميرها أثناء التحديثات عبر الهواء (OTA).

تصف هذه الصفحة كيفية قيام عملاء OTA بتغيير حجم الأقسام الديناميكية أثناء التحديث للأجهزة غير A/B.

بالنسبة للأجهزة غير A/B، يتم تطبيق التحديث عبر الهواء للأقسام الديناميكية باستخدام updater داخل حزمة التحديث.

تحديث أجهزة الإطلاق

ينطبق هذا القسم على الأجهزة غير A/B التي يتم تشغيلها بدعم الأقسام الديناميكية؛ تتم ترقية هذه الأجهزة من Android 10 إلى الإصدارات الأحدث.

إنشاء حزم التحديث

يتم إنشاء حزم تحديث OTA بواسطة البرنامج النصي 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 هو 0 يعني عدم وجود حدود لحجم الأقسام في المجموعة. يلزم إجراء اختبارات إضافية للتأكد من أن الأقسام الموجودة في المجموعة لا تتجاوز المساحة المتوفرة على الجهاز.
  • resize_group group-name maximum-size
    • قم بتغيير حجم المجموعة إلى الحجم الأقصى المحدد.
    • قم بالإلغاء إذا كانت المجموعة غير موجودة.
    • maximum_size هو 0 يعني عدم وجود حدود لحجم الأقسام في المجموعة. يلزم إجراء اختبارات إضافية للتأكد من أن الأقسام الموجودة في المجموعة لا تتجاوز المساحة المتوفرة على الجهاز.
  • remove_group group-name
    • إزالة مجموعة.
    • إحباط إذا كان هناك أقسام في المجموعة.
  • remove_all_groups
    • قم بإلغاء تحديد كافة الأقسام من مخطط الجهاز.
    • إزالة كافة الأقسام والمجموعات.

OTA التزايدي

تستخدم تحديثات OTA المتزايدة المنطق التالي:

  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