يتوافق Android 10 مع الأقسام الديناميكية، وهو نظام تقسيم لمساحة المستخدم يمكنه إنشاء الأقسام وتغيير حجمها وإزالتها أثناء إجراء التحديثات عبر الهواء (OTA).
توضّح هذه الصفحة كيف يغيّر عملاء التحديثات عبر الهواء حجم الأقسام الديناميكية أثناء إجراء تحديث للأجهزة غير المتوافقة مع نظام A/B.
بالنسبة إلى الأجهزة غير المتوافقة مع نظام A/B، يتم تطبيق التحديث عبر الهواء للأقسام الديناميكية
باستخدام 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 script:
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- إلغاء ربط جميع الأقسام من أداة ربط الأجهزة.
- إزالة جميع الأقسام والمجموعات.
التحديث عبر الهواء الجزئي
تستخدم التحديثات عبر الهواء الجزئية المنطق التالي:
- تقليص حجم الأقسام أو حذفها أو نقلها خارج المجموعة (بحيث تكون هناك مساحة كافية لتقليص حجم المجموعات)
- تقليص حجم المجموعات (بحيث تكون هناك مساحة كافية لتوسيع حجم المجموعات)
- توسيع حجم المجموعات (بحيث تكون هناك مساحة كافية لتوسيع حجم الأقسام أو إضافتها )
- توسيع حجم الأقسام أو إضافتها أو نقلها إلى مجموعة جديدة
بالتفصيل، يتم إنشاء 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التحديث عبر الهواء الكامل
تستخدم التحديثات عبر الهواء الكاملة المنطق التالي:
- حذف جميع المجموعات والأقسام الحالية
- إضافة مجموعات
- إضافة أقسام
بالتفصيل، يتم إنشاء 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