Güncelleme Yöneticisi

Güncelleme Yöneticisi, sanal makinesinin güncellemelerini gerçekleştirir. Güncelleme Yöneticisi, sistem entegratörü tarafından sağlanan istemciyle koordineli çalışır. İstemci, güncelleme yükünü sağlar ve genel araç güncellemesini koordine eder. Güncelleme şu adımlardan oluşur:

  1. HAZIR: Güncelleme yapılmıyor.
  2. HAZIRLAMA: Güncelleme Yöneticisi, güncellemeyi diske yazar ancak etkinleştirmez.
  3. ETKİNLEŞTİR: Güncelleme Yöneticisi, hazırlanan güncellemeyi etkinleştirir. Böylece güncelleme, yeniden başlatma işleminden sonra geçerli olur.
  4. COMMIT: Güncelleme Yöneticisi, güncellemeyi kalıcı hale getirir.

Güncelleme Yöneticisi'nin iş akışını gösteren basitleştirilmiş bir durum makinesi

Şekil 1. Güncelleme Yöneticisi'nin üst düzeyde çalışması.

Güncelleme Yöneticisi, bu sayfada açıklanan sistem güncellemelerini ve hizmet paketi güncellemelerini destekler.

Sistem güncellemeleri

Android işletim sistemi, yuvalar adı verilen iki bölüm kümesi kullanır. Bu yuvalardan yalnızca biri aynı anda aktiftir. Sistem güncellemesi, etkin olmayan yuvaya yeni bir bölüm grubu yazar ve sistem, bir sonraki yeniden başlatmada etkin yuvayı değiştirir. Sistem güncellemeleri oluşturma hakkında daha fazla bilgi için A/B sistem güncellemeleri başlıklı makaleyi inceleyin.

Hizmet paketi güncellemeleri

AAOS SDV'de hizmet paketleri, hizmetleri APEX'ler içinde birlikte paketler. Hizmet paketi güncellemeleri, yeni APEX dosyalarını geçici oturumlarda aşamalandırır. Sistem, yeniden başlatıldıktan sonra bu güncellenmiş paketleri etkinleştirir. Hizmet paketi APEX'leri oluşturma hakkında daha fazla bilgi için Hizmet paketi güncellemeleri başlıklı makaleyi inceleyin.

Durum makinesi

İstemciden gelen istekler ve sistem hizmetlerinden gelen etkinlikler, UpdateManager durum makinesini yönlendirir. Güncelleme Yöneticisi, beklenmedik yeniden başlatma veya kilitlenme durumlarında bile durumunu kurtaracak ve güncelleme sürecine devam edecek şekilde tasarlanmıştır.

Güncelleme Yöneticisi'nin iş akışını gösteren bir durum makinesi

Şekil 2. Update Manager durum makinesini güncelleyin.

API

Güncelleme Yöneticisi, durum makinesi aracılığıyla güncelleme sürecini yönlendiren bir API sağlar. API, VSIDL kullanır. Bu, SDV Comms'u destekleyen herhangi bir VM'de bulunan istemcileri destekler ve istek hatası bildirimi sağlar.

Güvenlik ve erişim

Sistem, yetkilendirme politikalarını kullanarak API erişimini kısıtlar. Yalnızca yetkili istemci, güncelleme yöneticisine çağrı yapabilir.

Gelişmelerin paylaşılması

Güncelleme işlemleri uzun sürebileceğinden Update Manager, eşzamansız durum güncellemeleri sağlar. İstemciler, durum güncellemelerine abone olarak durumu izlemelidir.

Abonelik yönetimi

  • Abone olma: İstemciler, SubscribeToStatusUpdates() yöntemini çağırarak durum güncellemelerine abone olur:

    rpc SubscribeToStatusUpdates(SubscribeToStatusUpdatesRequest)
        returns (SubscribeToStatusUpdatesResponse) {}
    
    message SubscribeToStatusUpdatesRequest {}
    
    message SubscribeToStatusUpdatesResponse {}
    

    SubscribeToStatusUpdates() işlevi çağrılmadan önce istemcinin UpdateManagerListenerService işlevini uygulayan bir RPC arayüzü başlatması gerekir.

  • Abonelikten çıkma: İstemciler, UnsubscribeFromStatusUpdates() işlevini çağırarak durum güncellemeleri almayı durdurabilir:

    rpc UnsubscribeFromStatusUpdates(UnsubscribeFromStatusUpdatesRequest)
        returns (UnsubscribeFromStatusUpdatesResponse) {}
    
    message UnsubscribeFromStatusUpdatesRequest {}
    
    message UnsubscribeFromStatusUpdatesResponse {}
    

UpdateManagerListenerService

UpdateManagerService üzerinden SubscribeToStatusUpdates()'ı arayan müşterilerin durum güncellemelerini alabilmek için aşağıdaki hizmeti uygulaması gerekir:

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, status_update alanını kullanarak iki olası mesajdan birini gönderir:

  1. UpdateManagerStatus: Güncelleme Yöneticisi'nin durumu değiştiğinde gönderilir.
  2. UpdateProgress: İşlem önemli ölçüde zaman alabileceğinden PREPARE ve ACTIVATE_PRE_REBOOT durumları sırasında güncelleme ilerleme durumunu belirtmek için gönderilir.

Durum ve hata mesajları

Durum mesajları, durum ve hatalarla ilgili ayrıntıları içerir:

  • UpdateManagerStatus: Güncellemenin mevcut aşamasını ve başarısızlık nedenlerini bildirir:

    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: Sistem güncellemeleri sırasında Güncelleme Motoru'nun mevcut durumunu bildirir:

    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;
    }
    
    

Anında durum bilgisi alma

GetStatus() işlevini çağırarak mevcut durumu ve yükü istediğiniz zaman alabilirsiniz. SystemUpdatePayload ve ServiceBundleUpdatePayload ile ilgili mesajlar Hazırlama bölümünde açıklanmıştır.

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;
  }
}

Hazırlık

Prepare isteği, yükü hazırlayarak güncelleme sürecini başlatır ancak sistem, güncellemeyi etkinleştirmek için bekler:

rpc Prepare(PrepareRequest) returns (PrepareResponse) {}

message PrepareRequest {
  oneof payload {
    SystemUpdatePayload system_update_payload = 1;
    ServiceBundleUpdatePayload service_bundle_update_payload = 2;
  }
}

message PrepareResponse {}

İstek geçerliyse durum PREPARE olarak değişir ve Update Manager güncellemeyi başlatır.

Güncelleme türü, yükün türüne göre belirlenir.

Sistem güncellemesi yükü

Sistem güncellemesinde SystemUpdatePayload verileri kullanılır. Bu veriler için kablosuz (OTA) güncelleme görüntüsüne giden bir yol gerekir. Diğer parametreler resimden ayrıştırılır ancak ayrıştırılan değerleri geçersiz kılmak için bunları belirtebilirsiniz.

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;
}

Güncelleme Yöneticisi, yükleme sonrası adımları çalıştırmak için OTA görüntüsünü (istemci tarafından /data/ota_package dizininde sağlanır) işler ancak etkin önyükleme yuvasını değiştirmez. Ardından, başarılı olursa PREPARE_COMPLETE durumuna, başarısız olursa PREPARE_FAILURE durumuna geçer.

Sistem güncellemesinin askıya alınması

Yalnızca sistem güncellemeleri için güncelleme sürecini duraklatabilirsiniz. Bu istek yalnızca PREPARE durumundayken geçerlidir.

  • Askıya alma: Güncellemeyi duraklatır ve durumu PREPARE_SUSPEND aracılığıyla değiştirir.

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

    Başarılı olursa durum PREPARE_SUSPEND_COMPLETE olarak değişir. Başarısızlık durumunda, durum PREPARE_FAILURE olarak değişir.

  • Devam ettir: Duraklatılmış güncellemeyi devam ettirir. Bu yalnızca PREPARE_SUSPEND_COMPLETE eyaletinde geçerlidir.

    rpc Resume(ResumeRequest) returns (ResumeResponse) {}
    
    message ResumeRequest {}
    
    message ResumeResponse {}
    

    Durum, PREPARE durumuna geri döner.

Hizmet paketi güncelleme yükü

Hizmet paketi güncellemesinde, APEX dosyalarının yollarını içeren ve etkinleştirme denemesi sınırını belirleyen ServiceBundleUpdatePayload kullanılır.

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;
}

Güncelleme Yöneticisi, APEX dosyalarının doğru şekilde imzalandığını doğrular ve bunları bir oturumda aşamalandırır. Başarılı olursa durum PREPARE_COMPLETE olarak değişir. Başarısız olursa durum PREPARE_FAILURE olarak değişir.

Etkinleştir

Activate isteği, hazırlanan güncellemeyi bir sonraki yeniden başlatma işleminde etkinleştirir.

rpc Activate(ActivateRequest) returns (ActivateResponse) {}

message ActivateRequest {}

message ActivateResponse {}

Yeniden başlatma öncesi

Güncelleme Yöneticisi, güncellemeyi etkinleştirirken ACTIVATE_PRE_REBOOT durumuna geçer. Güncelleme Yöneticisi, sistem yeniden başlatıldığında geçerli olacak bir kullanıcı verileri kontrol noktası da oluşturur.

Etkinleştirme işlemleri, güncelleme türüne göre farklılık gösterir:

  • Sistem güncellemesi: Sistem, yükleme sonrası adımları çalıştırır ve bir sonraki yeniden başlatmada geçiş yapmak için önyükleme yuvasını ayarlar.
  • Hizmet paketi güncellemesi: Sistem, hazırlanan APEX oturumunu etkinleştirilmeye hazır olarak işaretler.

Sistem güncellemeyi başarıyla etkinleştirirse durum ACTIVATE_PRE_REBOOT_COMPLETE olarak değişir. Bu, sanal makinenin yeniden başlatılmaya hazır olduğunu gösterir. Aksi takdirde durum ACTIVATE_PRE_REBOOT_FAILURE olarak değişir.

Yeniden başlatma sonrası

Yeniden başlatma işleminden sonra sistem, kontrol noktası modunda başlar. Bu modda sistem, kullanıcı verileri bölümünde yapılan değişiklikleri kalıcı depolama alanına işlemez. Sistem güncellemeyi başarıyla uygulamadığında bu değişiklikleri ilk durumuna geri döndürür.

Başlatma sınırı

Sistem, aşağıdaki koşullardan birinde kullanıcı verileri bölümündeki değişiklikleri geri alır:

  • İstemci açık bir Rollback() isteği gönderir ve sistemi yeniden başlatır.
  • Sistem, istemci Commit() veya Rollback() işlevini çağırmadan çok fazla kez başlatılıyor. Yükleme sınırı, her güncelleme türü için farklıdır:
    • Sistem güncellemesi: Bu, BootControl uygulamasıyla ayarlanır. Örneğin, Cuttlefish cihazları tarafından kullanılan uygulamadaki varsayılan sınır yedi başlatmadır.
    • Hizmet paketi güncellemesi: Müşteri tarafından sağlanan boot_attempts alanı, Prepare() isteği yapıldığında bu değeri ayarlar.ServiceBundleUpdatePayload
Doğrulama

Ardından sistem, güncellemeyi doğrular:

  • Sistem güncellemesi: dm-verity, güncellenen yuvada bozulma olup olmadığını kontrol eder.
  • Hizmet paketi güncellemesi: apexd Her APEX'in imzasını kontrol eder ve APEX'in görüntüsünü dosya sistemine bağlar.

Doğrulama başarılı olursa durum ACTIVATE_POST_REBOOT_COMPLETE olarak değişir. Güncelleme Yöneticisi, Commit() veya Rollback()'yi bekler.

Doğrulama başarısız olursa sistem yeniden başlatılır. Sistem önyükleme sınırına ulaştığında orijinal durumuna geri döner:

  • Sistem güncelleme: Sistem, orijinal yuvaya geri döner.
  • Hizmet paketi güncellemesi: Güncellenen APEX'ler bırakılır ve orijinal APEX'ler yeniden etkinleştirilir.

Doğrulama herhangi bir güncelleme türü için başarısız olursa orijinal durum geri yüklendikten sonra durum ACTIVATE_PRE_REBOOT_FAILURE olarak değişir.

Geri al

Rollback isteği, sistemi güncelleme öncesi durumuna döndürmeye başlar.

rpc Rollback(RollbackRequest) returns (RollbackResponse) {}

message RollbackRequest {}

message RollbackResponse {}

Rollback() isteğini birçok aşamada yapabilirsiniz. Sistem, başlangıç durumuna bağlı olarak farklı işlemler yapar ve farklı durumlar ortaya çıkar:

Geri alma işleminin yapıldığı tarih Durum geçişi Sistem işlemi
(Yalnızca sistem güncellemesi) PREPARE, PREPARE_SUSPEND_COMPLETE &rightarrow; PREPARE_CANCEL &rightarrow; PREPARE_ROLLBACK &rightarrow; READY Sistem güncelleme: Sistem güncellemesini iptal eder.
PREPARE_FAILURE, PREPARE_COMPLETE &rightarrow; PREPARE_ROLLBACK &rightarrow; READY Sistem güncellemesi: Sistem güncellemesini iptal eder.

Hizmet paketi güncellemesi: Aşamalı APEX oturumunu iptal eder.
ACTIVATE_PRE_REBOOT_COMPLETE, ACTIVATE_PRE_REBOOT_FAILURE &rightarrow; ACTIVATE_PRE_REBOOT_ROLLBACK &rightarrow; READY Kullanıcı verileri kontrol noktasını devre dışı bırakır.

Sistem güncellemesi: Önyükleme yuvası geçişini iptal eder.

Hizmet paketi güncellemesi: Aşamalı APEX'i kaldırır.
ACTIVATE_POST_REBOOT_COMPLETE &rightarrow; ACTIVATE_POST_REBOOT_ROLLBACK &rightarrow; ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE Kullanıcı verileri kontrol noktasını devre dışı bırakır.

Sistem güncellemesi: Önyükleme yuvasını geri değiştirir.

Hizmet paketi güncellemesi: Etkin APEX oturumlarını geri alır.

Geri alma işleminin geçerli olması için son bir yeniden başlatma gerekir. Ardından durum READY olarak değişir.

Kaydet

Bu istek, güncellemenin başarıyla tamamlandığını ve tüm değişikliklerin kalıcı olarak uygulandığını gösterir.

rpc Commit(CommitRequest) returns (CommitResponse) {}

message CommitRequest {}

message CommitResponse {}

Commit işlemleri gerçekleştirilirken durum COMMIT olarak değişir:

  • Sistem güncellemesi: Güncelleme Yöneticisi, başlatmayı başarılı olarak işaretler. Bu durum, gelecekteki geri alma işlemlerini engeller ve sonraki başlatmalarda bu yuva seçilir.
  • Hizmet paketi güncellemesi: Güncelleme Yöneticisi, hazırlanan APEX oturumunu başarılı olarak işaretler, güncelleme oturumunu kapatır ve paketleri kalıcı olarak etkinleştirir.

Sistem güncellemeyi işledikten sonra Güncelleme Yöneticisi, kullanıcı verileri kontrol noktasını işler. Sistem, bu başlatma sırasında yazılan tüm yeni kullanıcı verilerini kalıcı depolamaya aktarır. Güncelleme Yöneticisi, güncellemenin tamamlandığını belirten READY'ya geri döner.

APEX'lerin yüklemesini kaldırma

UninstallApex isteği, hizmet paketlerinin /data sürümünü kaldırır. UninstallApex'ı herhangi bir durumda çağırabilirsiniz ancak kaldırma işleminin geçerli olması için VM'nin yeniden başlatılması gerekir. Bu nedenle, güncelleme devam ederken UninstallApex uygulamasını aramaktan kaçının. UninstallApex, önceden yüklenmiş APEX'leri kaldırmaz, APEX verilerini silmez veya etkin olmayan APEX sürümlerini kaldırmaz.

rpc UninstallApex(UninstallApexRequest) returns (UninstallApexResponse) {}

message UninstallApexRequest {
  message ApexInfo {
    string module_name = 1;
    int64 version_code = 2;
  }
  repeated ApexInfo apexes = 1;
}

message UninstallApexResponse {}