Android 10 รองรับพาร์ติชันแบบไดนามิก ซึ่งเป็นระบบการแบ่งพาร์ติชันพื้นที่ผู้ใช้ที่สามารถสร้าง ปรับขนาด และลบพาร์ติชันในระหว่างการอัปเดตแบบ OTA ได้
หน้านี้อธิบายวิธีปรับขนาดพาร์ติชันแบบไดนามิกของไคลเอ็นต์ OTA ระหว่างการอัปเดตสำหรับอุปกรณ์ที่ไม่ใช่ A/B
สำหรับอุปกรณ์ที่ไม่ใช่ A/B ระบบจะใช้การอัปเดต OTA สำหรับพาร์ติชันแบบไดนามิกโดยใช้ updater
ในแพ็กเกจการอัปเดต
อัปเดตอุปกรณ์ที่จะเปิดตัว
ส่วนนี้ใช้กับอุปกรณ์ที่ไม่ใช่ A/B ซึ่งเปิดตัวด้วยการรองรับพาร์ติชันแบบไดนามิก โดยอุปกรณ์เหล่านี้จะอัปเกรดจาก Android 10 เป็นเวอร์ชันที่ใหม่กว่า
สร้างแพ็กเกจอัปเดต
แพ็กเกจอัปเดต OTA สร้างขึ้นโดยสคริปต์ ota_from_target_files
ซึ่งอยู่ภายใต้ build/make/tools/releasetools
โดยค่าเริ่มต้น สคริปต์จะสร้างแพ็กเกจที่อัปเดตพาร์ติชัน system
และ vendor
หากมีพาร์ติชันแบบไดนามิกเพิ่มเติม เช่น product
, product_services
หรือ odm
การอัปเดตพาร์ติชันเหล่านี้จะต้องสร้างในโค้ดเฉพาะอุปกรณ์
หากต้องการสร้างการอัปเดต ให้ใช้ FullOTA_GetBlockDifferences()
และ IncrementalOTA_GetBlockDifferences()
ในโมดูล Python แบบขยาย ฟังก์ชันทั้ง 2 รายการนี้จะแสดงรายการออบเจ็กต์ BlockDifference
โดยแต่ละรายการจะอธิบายแพตช์การอัปเดตที่จะใช้กับพาร์ติชัน พาร์ติชันที่แสดงผลโดยฟังก์ชันทั้ง 2 นี้ไม่ควรแก้ไขด้วยตนเองหรือยืนยันที่อื่น เช่น ใน *_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 ที่เพิ่มขึ้นจะใช้ตรรกะต่อไปนี้
- ย่อขนาดพาร์ติชัน/ลบพาร์ติชัน/ย้ายพาร์ติชันออกจากกลุ่ม (เพื่อให้มีพื้นที่เพียงพอในการย่อขนาดกลุ่ม)
- ย่อกลุ่ม (เพื่อให้มีที่ว่างเพียงพอที่จะเพิ่มกลุ่ม)
- ขยายกลุ่ม (เพื่อให้เรามีพื้นที่เพียงพอสำหรับการขยาย/เพิ่มพาร์ติชัน)
- ขยายพาร์ติชัน/เพิ่มพาร์ติชัน/ย้ายพาร์ติชันไปยังกลุ่มใหม่
โดยละเอียดคือ 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 เต็มรูปแบบ
การอัปเดต OTA แบบเต็มจะใช้ตรรกะต่อไปนี้
- ลบกลุ่มและพาร์ติชันที่มีอยู่ทั้งหมด
- เพิ่มกลุ่ม
- เพิ่มพาร์ติชัน
โดยรายละเอียดคือ 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