Android 10 รองรับ พาร์ติชันแบบไดนามิก ซึ่งเป็นระบบการแบ่งพาร์ติชันพื้นที่ผู้ใช้ที่สามารถสร้าง ปรับขนาด และทำลายพาร์ติชันระหว่างการอัปเดตแบบ over-the-air (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
จะต้องสร้างการอัพเดตใน โค้ดเฉพาะอุปกรณ์
หากต้องการสร้างการอัปเดต ในโมดูล 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 แบบเพิ่มหน่วยจะใช้ตรรกะต่อไปนี้:
- ย่อพาร์ติชั่น/ลบพาร์ติชั่น/ย้ายพาร์ติชั่นออกจากกลุ่ม (เพื่อให้มีพื้นที่เพียงพอที่จะย่อขนาดกลุ่ม)
- ย่อกลุ่ม (เพื่อให้มีพื้นที่เพียงพอที่จะขยายกลุ่ม)
- ขยายกลุ่ม (เพื่อให้เรามีพื้นที่เพียงพอที่จะขยาย/เพิ่มพาร์ติชัน)
- ขยายพาร์ติชั่น/เพิ่มพาร์ติชั่น/ย้ายพาร์ติชั่นไปยังกลุ่มใหม่
ในรายละเอียด 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 แบบเต็มจะใช้ตรรกะต่อไปนี้:
- ลบกลุ่มและพาร์ติชันที่มีอยู่ทั้งหมด
- เพิ่มกลุ่ม
- เพิ่มพาร์ติชัน
ในรายละเอียด 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