Update Manager จะดำเนินการอัปเดต VM โดยจะประสานงานกับไคลเอ็นต์ซึ่งได้รับจากผู้ผสานรวมระบบ ไคลเอ็นต์จะระบุเพย์โหลดของการอัปเดตและประสานงานการอัปเดตยานพาหนะโดยรวม การอัปเดตประกอบด้วยขั้นตอนต่อไปนี้
- READY: ไม่มีการอัปเดตที่กำลังดำเนินการ
- PREPARE: Update Manager จะเขียนการอัปเดตลงในดิสก์ แต่จะไม่ทำให้การอัปเดตทำงาน
- ACTIVATE: Update Manager จะทำให้การอัปเดตที่เตรียมไว้ทำงานเพื่อให้มีผลหลังจากการรีบูต
- COMMIT: Update Manager จะทำให้การอัปเดตมีผลถาวร
รูปที่ 1 การทำงานระดับสูงของ Update Manager
Update Manager รองรับการอัปเดตระบบและการอัปเดต Service Bundle ซึ่งอธิบายไว้ในหน้านี้
การอัปเดตระบบ
ระบบปฏิบัติการ Android ใช้พาร์ติชัน 2 ชุดที่เรียกว่า สล็อต โดยมีสล็อตที่ใช้งานอยู่เพียงสล็อตเดียว ในแต่ละครั้ง การอัปเดตระบบจะเขียนพาร์ติชันชุดใหม่ลงในสล็อตที่ไม่ได้ใช้งาน และระบบจะเปลี่ยนสล็อตที่ใช้งานอยู่เมื่อรีบูตครั้งถัดไป ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างการอัปเดตระบบได้ที่ การอัปเดตระบบแบบ A/B
การอัปเดต Service Bundle
ใน AAOS SDV, Service Bundle จะรวมบริการต่างๆ ไว้ด้วยกันภายใน APEX การอัปเดต Service Bundle จะจัดเตรียมไฟล์ APEX ใหม่ในเซสชันชั่วคราว ระบบจะเปิดใช้งาน Bundle ที่อัปเดตแล้วเหล่านี้หลังจากการรีบูตระบบ ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้าง APEX ของ Service Bundle ได้ที่การอัปเดต Service Bundle
State Machine
คำขอจากไคลเอ็นต์และเหตุการณ์จากบริการของระบบจะขับเคลื่อน State Machine ของ Update Manager Update Manager ได้รับการออกแบบมาให้มีความยืดหยุ่น โดยจะกู้คืนสถานะและดำเนินการต่อในกระบวนการอัปเดตแม้หลังจากรีบูตหรือขัดข้องโดยไม่คาดคิด
รูปที่ 2 State Machine ของ Update Manager
API
Update Manager มี API ที่ขับเคลื่อนกระบวนการอัปเดตผ่าน State Machine API ใช้ VSIDL ซึ่งรองรับไคลเอ็นต์ที่อยู่ใน VM ใดก็ตามที่รองรับ SDV Comms และให้การแจ้งเตือนเมื่อคำขอไม่สำเร็จ
การรักษาความปลอดภัยและการเข้าถึง
ระบบจะจำกัดการเข้าถึง API โดยใช้นโยบายการให้สิทธิ์ เฉพาะไคลเอ็นต์ที่ได้รับอนุญาตเท่านั้นที่โทรหา Update Manager ได้
การอัปเดตสถานะ
เนื่องจากการดำเนินการอัปเดตอาจใช้เวลานาน Update Manager จึงให้การอัปเดตสถานะแบบไม่พร้อมกัน ไคลเอ็นต์ต้องตรวจสอบสถานะโดยสมัครรับข้อมูลอัปเดตสถานะ
การจัดการการสมัครใช้บริการ
การสมัครใช้บริการ: ไคลเอ็นต์สมัครรับข้อมูลอัปเดตสถานะโดยเรียกใช้เมธอด
SubscribeToStatusUpdates()ดังนี้rpc SubscribeToStatusUpdates(SubscribeToStatusUpdatesRequest) returns (SubscribeToStatusUpdatesResponse) {} message SubscribeToStatusUpdatesRequest {} message SubscribeToStatusUpdatesResponse {}ก่อนเรียกใช้
SubscribeToStatusUpdates()ไคลเอ็นต์ต้องเริ่มอินเทอร์เฟซ RPC ที่ใช้UpdateManagerListenerServiceการยกเลิกการสมัครใช้บริการ: ไคลเอ็นต์หยุดรับข้อมูลอัปเดตสถานะได้โดยเรียกใช้
UnsubscribeFromStatusUpdates()ดังนี้rpc UnsubscribeFromStatusUpdates(UnsubscribeFromStatusUpdatesRequest) returns (UnsubscribeFromStatusUpdatesResponse) {} message UnsubscribeFromStatusUpdatesRequest {} message UnsubscribeFromStatusUpdatesResponse {}
UpdateManagerListenerService
ไคลเอ็นต์ที่เรียกใช้ SubscribeToStatusUpdates() ใน UpdateManagerService ต้องใช้บริการต่อไปนี้เพื่อรับข้อมูลอัปเดตสถานะ
service UpdateManagerListenerService {
/* Called when there is a status update from the Update Manager. */
rpc OnStatusUpdate(OnStatusUpdateRequest) returns (OnStatusUpdateResponse) {}
}
message OnStatusUpdateRequest {
oneof status_update {
UpdateManagerStatus update_manager_status = 1;
UpdateProgress update_progress = 2;
}
}
message OnStatusUpdateResponse {}
OnStatusUpdateRequest จะส่งข้อความที่เป็นไปได้ 2 ข้อความโดยใช้ช่อง status_update ดังนี้
UpdateManagerStatus: ส่งเมื่อสถานะของ Update Manager เปลี่ยนไปUpdateProgress: ส่งเพื่อระบุความคืบหน้าของการอัปเดตในสถานะPREPAREและACTIVATE_PRE_REBOOTเนื่องจากกระบวนการอาจใช้เวลานาน
สถานะและข้อความแสดงข้อผิดพลาด
ข้อความสถานะประกอบด้วยรายละเอียดเกี่ยวกับสถานะและข้อผิดพลาดต่างๆ ดังนี้
UpdateManagerStatus: รายงานระยะปัจจุบันของการอัปเดตและเหตุผลที่ทำให้เกิดข้อผิดพลาด ดังนี้message UpdateManagerStatus { /* The current state of the update */ UpdateState update_state = 1; /* The reason for the failure, if the update failed */ FailureReason failure_reason = 2; } enum UpdateState { /* The Update Manager is ready to accept a new update. */ READY = 0; /* An update is being prepared. */ PREPARE = 1; /* The update failed during the prepare step. Roll back the update to start a * new update. */ PREPARE_FAILURE = 2; /* The update was prepared successfully. */ PREPARE_COMPLETE = 3; /* A rollback has started from the prepare step. When complete, transitions * to READY. */ PREPARE_ROLLBACK = 4; /* The prepared update is being activated. */ ACTIVATE_PRE_REBOOT = 5; /* The update failed during the activate step before the reboot. Roll back the * update to start a new update. */ ACTIVATE_PRE_REBOOT_FAILURE = 6; /* The update was activated successfully. Reboot to complete activation. */ ACTIVATE_PRE_REBOOT_COMPLETE = 7; /* A rollback has started from the activate pre-reboot step. When complete, * transitions to READY. */ ACTIVATE_PRE_REBOOT_ROLLBACK = 8; /* An update was successfully activated after the reboot. The update needs to * be committed or rolled back to be completed. */ ACTIVATE_POST_REBOOT_COMPLETE = 9; /* A rollback has started from the activate post-reboot step. */ ACTIVATE_POST_REBOOT_ROLLBACK = 10; /* The rollback was completed successfully. Reboot to complete the * rollback. */ ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE = 11; /* The update is being committed. When complete, transitions to READY */ COMMIT = 12; /* The prepare request is being cancelled */ PREPARE_CANCEL = 13; /* The system update has started suspending */ PREPARE_SUSPEND = 14; /* The system update has finished suspending */ PREPARE_SUSPEND_COMPLETE = 15; } message FailureReason { /* The original error that triggered the failure */ ErrorCode error_code = 1; /* Binder error message for most ErrorCodes. */ string error_message = 2; } enum ErrorCode { Unspecified = 0; /* Error from UpdateEngine service */ UpdateEngineError = 1; // Error from the ApexService ApexServiceError = 2; // Error from the BootControlService BootControlServiceError = 3; // Error from the VoldService VoldServiceError = 4; }UpdateProgress: รายงานสถานะปัจจุบันจาก Update Engine ระหว่างการอัปเดตระบบ ดังนี้message UpdateProgress { /* Matches the enum UpdateStatus from the UpdateEngine service. */ int32 status_code = 1; /* A value ranging from 0.0 to 1.0, 1.0 representing the process is complete. */ float percentage = 2; }
รับสถานะทันที
คุณสามารถเรียกข้อมูลสถานะและเพย์โหลดปัจจุบันได้ทุกเมื่อโดยเรียกใช้ GetStatus() ข้อความ SystemUpdatePayload และ ServiceBundleUpdatePayload
อธิบายไว้ในส่วน เตรียมพร้อม
rpc GetStatus(GetStatusRequest) returns (GetStatusResponse) {}
message GetStatusRequest {}
message GetStatusResponse {
/* The status of the Update Manager */
UpdateManagerStatus update_manager_status = 1;
/* The current update payload, if one has been set through the Prepare() request */
oneof payload {
SystemUpdatePayload system_update_payload = 2;
ServiceBundleUpdatePayload service_bundle_update_payload = 3;
}
}
เตรียมพร้อม
คำขอ Prepare จะเริ่มกระบวนการอัปเดตโดยจัดเตรียมเพย์โหลด แต่ระบบจะรอให้เปิดใช้งานการอัปเดต
rpc Prepare(PrepareRequest) returns (PrepareResponse) {}
message PrepareRequest {
oneof payload {
SystemUpdatePayload system_update_payload = 1;
ServiceBundleUpdatePayload service_bundle_update_payload = 2;
}
}
message PrepareResponse {}
หากคำขอถูกต้อง สถานะจะเปลี่ยนเป็น PREPARE และ Update Manager จะเริ่มการอัปเดต
ประเภทของเพย์โหลดจะเป็นตัวกำหนดประเภทการอัปเดต
เพย์โหลดของการอัปเดตระบบ
การอัปเดตระบบใช้ข้อมูล SystemUpdatePayload ซึ่งต้องมีเส้นทางไปยังอิมเมจการอัปเดตผ่านอากาศ (OTA) ระบบจะแยกวิเคราะห์พารามิเตอร์อื่นๆ จากอิมเมจ แต่คุณสามารถระบุพารามิเตอร์เหล่านั้นเพื่อลบล้างค่าที่แยกวิเคราะห์ได้
message SystemUpdatePayload {
/* Absolute path to the update image (e.g., /updates/ota_update.zip) */
string payload = 1;
/* Offset (in bytes) into the payload where the payload binary starts. */
optional int64 payload_offset = 2;
/* The amount of data (in bytes) to read from "payload" as the update payload. */
optional int64 payload_size = 3;
/* The header key value pairs to apply with the payload. */
map<string, string> header_key_value_pairs = 4;
}
Update Manager จะประมวลผลอิมเมจ OTA (ไคลเอ็นต์ระบุไว้ในไดเรกทอรี /data/ota_package) เพื่อเรียกใช้ขั้นตอนหลังการติดตั้ง แต่จะไม่เปลี่ยนสล็อตการบูตที่ใช้งานอยู่ จากนั้นสถานะจะเปลี่ยนเป็น PREPARE_COMPLETE หากสำเร็จ หรือ PREPARE_FAILURE หากไม่สำเร็จ
การระงับการอัปเดตระบบ
คุณสามารถหยุดกระบวนการอัปเดตชั่วคราวสำหรับการอัปเดตระบบเท่านั้น คำขอนี้จะใช้ได้เฉพาะเมื่ออยู่ในสถานะ PREPARE
ระงับ: หยุดการอัปเดตชั่วคราว โดยเปลี่ยนสถานะผ่าน
PREPARE_SUSPENDrpc Suspend(SuspendRequest) returns (SuspendResponse) {} message SuspendRequest {} message SuspendResponse {}หากสำเร็จ สถานะจะเปลี่ยนเป็น
PREPARE_SUSPEND_COMPLETEหากไม่สำเร็จ สถานะจะเปลี่ยนเป็นPREPARE_FAILUREดำเนินการต่อ: ดำเนินการอัปเดตที่หยุดไว้ชั่วคราวต่อ ซึ่งจะใช้ได้เฉพาะในสถานะ
PREPARE_SUSPEND_COMPLETErpc Resume(ResumeRequest) returns (ResumeResponse) {} message ResumeRequest {} message ResumeResponse {}สถานะจะเปลี่ยนกลับเป็นสถานะ
PREPARE
เพย์โหลดของการอัปเดต Service Bundle
การอัปเดต Service Bundle ใช้ ServiceBundleUpdatePayload ซึ่งมีเส้นทางไปยังไฟล์ APEX และกำหนดขีดจำกัดการพยายามเปิดใช้งาน
message ServiceBundleUpdatePayload {
/* Absolute path to an .apex file. Multiple .apex files can be included. */
repeated string apex_path = 1;
/* Number of boots to attempt activation before aborting. Must be > 0. */
int32 boot_attempts = 2;
}
Update Manager จะตรวจสอบว่าไฟล์ APEX มีการลงนามอย่างถูกต้องและจัดเตรียมไฟล์เหล่านั้นในเซสชัน หากสำเร็จ สถานะจะเปลี่ยนเป็น PREPARE_COMPLETE หากไม่สำเร็จ สถานะจะเปลี่ยนเป็น PREPARE_FAILURE
เปิดใช้งาน
คำขอ Activate จะเปิดใช้งานการอัปเดตที่เตรียมไว้เมื่อรีบูตครั้งถัดไป
rpc Activate(ActivateRequest) returns (ActivateResponse) {}
message ActivateRequest {}
message ActivateResponse {}
ก่อนรีบูต
Update Manager จะเปลี่ยนเป็นสถานะ ACTIVATE_PRE_REBOOT ขณะเปิดใช้งานการอัปเดต นอกจากนี้ Update Manager ยังสร้างจุดตรวจสอบข้อมูลผู้ใช้ที่จะมีผลเมื่อรีบูตระบบ
การดำเนินการเปิดใช้งานจะแตกต่างกันไปตามประเภทการอัปเดต ดังนี้
- การอัปเดตระบบ: ระบบจะเรียกใช้ขั้นตอนหลังการติดตั้งและตั้งค่าสล็อตการบูตให้เปลี่ยนเมื่อรีบูตครั้งถัดไป
- การอัปเดต Service Bundle: ระบบจะทำเครื่องหมายเซสชัน APEX ที่จัดเตรียมไว้ว่าพร้อมสำหรับการเปิดใช้งาน
หากระบบเปิดใช้งานการอัปเดตสำเร็จ สถานะจะเปลี่ยนเป็น ACTIVATE_PRE_REBOOT_COMPLETE ซึ่งบ่งชี้ว่า VM พร้อมสำหรับการรีบูต
หากไม่สำเร็จ สถานะจะเปลี่ยนเป็น ACTIVATE_PRE_REBOOT_FAILURE
หลังรีบูต
หลังจากรีบูต ระบบจะเริ่มทำงานในโหมดจุดตรวจสอบ ในโหมดนี้ ระบบจะไม่คอมมิตการเปลี่ยนแปลงใดๆ กับพาร์ติชันข้อมูลผู้ใช้ไปยังพื้นที่เก็บข้อมูลถาวร หากระบบคอมมิตการอัปเดตไม่สำเร็จ ระบบจะเปลี่ยนการเปลี่ยนแปลงเหล่านี้กลับสู่สถานะเริ่มต้น
ขีดจำกัดการบูต
ระบบจะเปลี่ยนการเปลี่ยนแปลงกลับไปที่พาร์ติชันข้อมูลผู้ใช้ในกรณีใดกรณีหนึ่งต่อไปนี้
- ไคลเอ็นต์ส่งคำขอ
Rollback()อย่างชัดเจนและรีบูตระบบ - ระบบบูตหลายครั้งเกินไปโดยที่ไคลเอ็นต์ไม่ได้เรียกใช้
Commit()หรือRollback()ขีดจำกัดการบูตจะแตกต่างกันไปตามประเภทการอัปเดต ดังนี้- การอัปเดตระบบ: การติดตั้งใช้งาน
BootControlจะกำหนดขีดจำกัดนี้ เช่น ขีดจำกัดเริ่มต้นในการติดตั้งใช้งานที่อุปกรณ์ Cuttlefish ใช้คือ การบูต 7 ครั้ง - การอัปเดต Service Bundle: ช่อง
boot_attemptsของServiceBundleUpdatePayloadที่ไคลเอ็นต์ระบุจะกำหนดขีดจำกัดนี้เมื่อมีการส่งคำขอPrepare()
- การอัปเดตระบบ: การติดตั้งใช้งาน
การยืนยัน
จากนั้นระบบจะยืนยันการอัปเดต ดังนี้
- การอัปเดตระบบ: dm-verity จะตรวจสอบสล็อตที่อัปเดตแล้วเพื่อหาข้อผิดพลาด
- การอัปเดต Service Bundle:
apexdจะตรวจสอบลายเซ็นของ APEX แต่ละรายการและติดตั้งอิมเมจของ APEX ลงในระบบไฟล์
หากการยืนยันสำเร็จ สถานะจะเปลี่ยนเป็น ACTIVATE_POST_REBOOT_COMPLETE Update Manager จะรอ Commit() หรือ Rollback()
หากการยืนยันไม่สำเร็จ ระบบจะรีบูต เมื่อระบบถึงขีดจำกัดการบูต ระบบจะเปลี่ยนกลับสู่สถานะเดิม ดังนี้
- การอัปเดตระบบ: ระบบจะเปลี่ยนกลับไปที่สล็อตเดิม
- การอัปเดต Service Bundle: ระบบจะทิ้ง APEX ที่อัปเดตแล้วและเปิดใช้งาน APEX เดิมอีกครั้ง
หากการยืนยันไม่สำเร็จสำหรับประเภทการอัปเดตใดก็ตาม สถานะจะเปลี่ยนเป็น ACTIVATE_PRE_REBOOT_FAILURE หลังจากที่ระบบกู้คืนสถานะเดิมแล้ว
ย้อนกลับ
คำขอ Rollback จะเริ่มเปลี่ยนระบบกลับสู่สถานะก่อนการอัปเดต
rpc Rollback(RollbackRequest) returns (RollbackResponse) {}
message RollbackRequest {}
message RollbackResponse {}
คุณสามารถส่งคำขอ Rollback() ได้ในหลายสถานะ ระบบจะดำเนินการต่างๆ และสถานะต่างๆ จะตามมา ขึ้นอยู่กับสถานะเริ่มต้น
| สถานะเมื่อมีการย้อนกลับ | การเปลี่ยนสถานะ | การทำงานของระบบ |
|---|---|---|
(การอัปเดตระบบเท่านั้น) PREPARE, PREPARE_SUSPEND_COMPLETE |
→ PREPARE_CANCEL → PREPARE_ROLLBACK →
READY |
การอัปเดตระบบ: ยกเลิกการอัปเดตระบบ |
PREPARE_FAILURE, PREPARE_COMPLETE |
→ PREPARE_ROLLBACK → READY |
การอัปเดตระบบ: ยกเลิกการอัปเดตระบบ การอัปเดต Service Bundle: ยกเลิกเซสชัน APEX ที่จัดเตรียมไว้ |
ACTIVATE_PRE_REBOOT_COMPLETE, ACTIVATE_PRE_REBOOT_FAILURE |
→ ACTIVATE_PRE_REBOOT_ROLLBACK → READY |
ปิดใช้จุดตรวจสอบข้อมูลผู้ใช้
การอัปเดตระบบ: ยกเลิกการเปลี่ยนสล็อตการบูต การอัปเดต Service Bundle: นำ APEX ที่จัดเตรียมไว้ออก |
ACTIVATE_POST_REBOOT_COMPLETE |
→
ACTIVATE_POST_REBOOT_ROLLBACK → ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE |
ปิดใช้จุดตรวจสอบข้อมูลผู้ใช้ การอัปเดตระบบ: เปลี่ยนสล็อตการบูตกลับ การอัปเดต Service Bundle: เปลี่ยนเซสชัน APEX ที่ใช้งานอยู่กลับ ระบบต้องรีบูตครั้งสุดท้ายเพื่อให้การย้อนกลับมีผล จากนั้นสถานะจะเปลี่ยนเป็น READY
|
คอมมิต
คำขอนี้บ่งชี้ว่าการอัปเดตเสร็จสมบูรณ์แล้วและใช้การเปลี่ยนแปลงทั้งหมดอย่างถาวร
rpc Commit(CommitRequest) returns (CommitResponse) {}
message CommitRequest {}
message CommitResponse {}
สถานะจะเปลี่ยนเป็น COMMIT ขณะดำเนินการคอมมิต ดังนี้
- การอัปเดตระบบ: Update Manager จะทำเครื่องหมายการบูตว่าสำเร็จ ซึ่งจะป้องกันการย้อนกลับในอนาคตและเลือกสล็อตนี้ในการบูตครั้งต่อๆ ไป
- การอัปเดต Service Bundle: Update Manager จะทำเครื่องหมายเซสชัน APEX ที่จัดเตรียมไว้ว่าสำเร็จ ซึ่งจะปิดเซสชันการอัปเดตและทำให้ Bundle ใช้งานได้ถาวร
หลังจากที่ระบบคอมมิตการอัปเดตแล้ว Update Manager จะคอมมิตจุดตรวจสอบข้อมูลผู้ใช้ ระบบจะคอมมิตข้อมูลผู้ใช้ใหม่ทั้งหมดที่เขียนขึ้นระหว่างการบูตนี้ไปยังพื้นที่เก็บข้อมูลถาวร Update Manager จะเปลี่ยนกลับเป็น READY ซึ่งบ่งชี้ว่าการอัปเดตเสร็จสมบูรณ์แล้ว
ถอนการติดตั้ง APEX
คำขอ UninstallApex จะนำ Service Bundle เวอร์ชัน /data ออก คุณสามารถเรียกใช้ UninstallApex ได้ในทุกสถานะ แต่ VM ต้องรีบูตเพื่อให้การถอนการติดตั้งมีผล ดังนั้น ให้หลีกเลี่ยงการเรียกใช้ UninstallApex ขณะที่การอัปเดตกำลังดำเนินการอยู่ UninstallApex จะไม่นำ APEX ที่ติดตั้งไว้ล่วงหน้าออก ล้างข้อมูล APEX หรือนำ APEX เวอร์ชันที่ไม่ได้ใช้งานออก
rpc UninstallApex(UninstallApexRequest) returns (UninstallApexResponse) {}
message UninstallApexRequest {
message ApexInfo {
string module_name = 1;
int64 version_code = 2;
}
repeated ApexInfo apexes = 1;
}
message UninstallApexResponse {}