โปรแกรมจัดการการอัปเดต

Update Manager จะดำเนินการอัปเดต VM โดยจะประสานงานกับไคลเอ็นต์ซึ่งได้รับจากผู้ผสานรวมระบบ ไคลเอ็นต์จะระบุเพย์โหลดของการอัปเดตและประสานงานการอัปเดตยานพาหนะโดยรวม การอัปเดตประกอบด้วยขั้นตอนต่อไปนี้

  1. READY: ไม่มีการอัปเดตที่กำลังดำเนินการ
  2. PREPARE: Update Manager จะเขียนการอัปเดตลงในดิสก์ แต่จะไม่ทำให้การอัปเดตทำงาน
  3. ACTIVATE: Update Manager จะทำให้การอัปเดตที่เตรียมไว้ทำงานเพื่อให้มีผลหลังจากการรีบูต
  4. 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 ดังนี้

  1. UpdateManagerStatus: ส่งเมื่อสถานะของ Update Manager เปลี่ยนไป
  2. 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_SUSPEND

    rpc Suspend(SuspendRequest) returns (SuspendResponse) {}
    
    message SuspendRequest {}
    
    message SuspendResponse {}
    

    หากสำเร็จ สถานะจะเปลี่ยนเป็น PREPARE_SUSPEND_COMPLETE หากไม่สำเร็จ สถานะจะเปลี่ยนเป็น PREPARE_FAILURE

  • ดำเนินการต่อ: ดำเนินการอัปเดตที่หยุดไว้ชั่วคราวต่อ ซึ่งจะใช้ได้เฉพาะในสถานะ PREPARE_SUSPEND_COMPLETE

    rpc 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 &rightarrow; PREPARE_CANCEL &rightarrow; PREPARE_ROLLBACK &rightarrow; READY การอัปเดตระบบ: ยกเลิกการอัปเดตระบบ
PREPARE_FAILURE, PREPARE_COMPLETE &rightarrow; PREPARE_ROLLBACK &rightarrow; READY การอัปเดตระบบ: ยกเลิกการอัปเดตระบบ

การอัปเดต Service Bundle: ยกเลิกเซสชัน APEX ที่จัดเตรียมไว้
ACTIVATE_PRE_REBOOT_COMPLETE, ACTIVATE_PRE_REBOOT_FAILURE &rightarrow; ACTIVATE_PRE_REBOOT_ROLLBACK &rightarrow; READY ปิดใช้จุดตรวจสอบข้อมูลผู้ใช้

การอัปเดตระบบ: ยกเลิกการเปลี่ยนสล็อตการบูต

การอัปเดต Service Bundle: นำ APEX ที่จัดเตรียมไว้ออก
ACTIVATE_POST_REBOOT_COMPLETE &rightarrow; ACTIVATE_POST_REBOOT_ROLLBACK &rightarrow; 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 {}