Der Update Manager führt Updates für seine VM aus. Er kommuniziert mit dem Client, der vom Systemintegrator bereitgestellt wird. Der Client stellt die Update-Nutzlast bereit und koordiniert das gesamte Fahrzeugupdate. Das Update besteht aus den folgenden Schritten:
- READY (BEREIT): Es wird kein Update ausgeführt.
- PREPARE (VORBEREITEN): Der Update Manager schreibt das Update auf die Festplatte, aktiviert es aber nicht.
- ACTIVATE (AKTIVIEREN): Der Update Manager aktiviert das vorbereitete Update, sodass es nach einem Neustart wirksam wird.
- COMMIT (BESTÄTIGEN): Der Update Manager macht das Update dauerhaft.
Abbildung 1 : Überblick über die Funktionsweise des Update Managers.
Der Update Manager unterstützt Systemupdates und Updates von Dienstpaketen, die auf dieser Seite beschrieben werden.
System updates
Das Android-Betriebssystem verwendet zwei Partitionssätze, sogenannte Slots. Es ist immer nur ein Slot aktiv. Bei einem Systemupdate wird ein neuer Partitionssatz in den inaktiven Slot geschrieben und das System wechselt beim nächsten Neustart den aktiven Slot. Weitere Informationen zum Erstellen von Systemupdates finden Sie unter A/B-Systemupdates.
Updates von Dienstpaketen
In AAOS SDV werden Dienstpakete in APEX-Dateien zusammengefasst. Bei Updates von Dienstpaketen werden neue APEX-Dateien in temporären Sitzungen bereitgestellt. Das System aktiviert diese aktualisierten Pakete nach einem Neustart. Weitere Informationen zum Erstellen von APEX-Dateien für Dienstpakete finden Sie unter Updates von Dienstpaketen.
Zustandsautomat
Anfragen vom Client und Ereignisse von Systemdiensten steuern den Zustandsautomaten des Update Managers. Der Update Manager ist so konzipiert, dass er seinen Zustand wiederherstellen und den Updatevorgang auch nach unerwarteten Neustarts oder Abstürzen fortsetzen kann.
Abbildung 2 : Zustandsautomat des Update Managers.
API
Der Update Manager bietet eine API, die den Updatevorgang über den Zustandsautomaten steuert. Die API verwendet VSIDL, das Clients in jeder VM unterstützt, die SDV Comms unterstützt, und Benachrichtigungen über fehlgeschlagene Anfragen bereitstellt.
Sicherheit und Zugriff
Das System beschränkt den API-Zugriff mithilfe von Autorisierungsrichtlinien. Nur der autorisierte Client kann Aufrufe an den Update Manager senden.
Statusaktualisierungen
Da Updatevorgänge lange dauern können, bietet der Update Manager asynchrone Statusaktualisierungen. Clients müssen den Status beobachten, indem sie Statusaktualisierungen abonnieren.
Aboverwaltung
Abonnieren:Clients abonnieren Statusaktualisierungen, indem sie die Methode
SubscribeToStatusUpdates()aufrufen:rpc SubscribeToStatusUpdates(SubscribeToStatusUpdatesRequest) returns (SubscribeToStatusUpdatesResponse) {} message SubscribeToStatusUpdatesRequest {} message SubscribeToStatusUpdatesResponse {}Vor dem Aufruf von
SubscribeToStatusUpdates()muss der Client eine RPC Schnittstelle starten, dieUpdateManagerListenerServiceimplementiert.Abmelden:Clients können den Empfang von Statusaktualisierungen beenden, indem sie
UnsubscribeFromStatusUpdates()aufrufen:rpc UnsubscribeFromStatusUpdates(UnsubscribeFromStatusUpdatesRequest) returns (UnsubscribeFromStatusUpdatesResponse) {} message UnsubscribeFromStatusUpdatesRequest {} message UnsubscribeFromStatusUpdatesResponse {}
UpdateManagerListenerService
Clients, die SubscribeToStatusUpdates() für UpdateManagerService aufrufen, müssen den folgenden Dienst implementieren, um Statusaktualisierungen zu erhalten:
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 liefert eine von zwei möglichen Nachrichten über das Feld status_update:
UpdateManagerStatus: Wird gesendet, wenn sich der Status des Update Managers ändert.UpdateProgress: Wird gesendet, um den Fortschritt des Updates in den StatusPREPAREundACTIVATE_PRE_REBOOTanzugeben, da der Vorgang viel Zeit in Anspruch nehmen kann.
Status- und Fehlermeldungen
Die Statusmeldungen enthalten Details zum Status und zu Fehlern:
UpdateManagerStatus:Meldet die aktuelle Phase des Updates und den Grund für einen Fehler: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: Meldet den aktuellen Status von Update Engine während Systemupdates: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; }
Sofortigen Status abrufen
Sie können den aktuellen Status und die aktuelle Nutzlast jederzeit mit GetStatus() abrufen. Die SystemUpdatePayload und ServiceBundleUpdatePayload
Nachrichten werden unter Vorbereiten beschrieben.
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;
}
}
Vorbereiten
Die Anfrage Prepare startet den Updatevorgang, indem die Nutzlast bereitgestellt wird. Das System wartet jedoch mit der Aktivierung des Updates:
rpc Prepare(PrepareRequest) returns (PrepareResponse) {}
message PrepareRequest {
oneof payload {
SystemUpdatePayload system_update_payload = 1;
ServiceBundleUpdatePayload service_bundle_update_payload = 2;
}
}
message PrepareResponse {}
Wenn die Anfrage gültig ist, wechselt der Status zu PREPARE und der Update Manager startet das Update.
Der Typ der Nutzlast bestimmt den Update-Typ.
Nutzlast für Systemupdate
Bei einem Systemupdate werden die Daten SystemUpdatePayload verwendet, die einen Pfad zu einem OTA-Update-Image (Over-the-Air) erfordern. Die anderen Parameter werden aus dem Image geparst. Sie können sie jedoch angeben, um die geparsten Werte zu überschreiben.
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;
}
Der Update Manager verarbeitet das OTA-Image (das vom Client im Verzeichnis /data/ota_package bereitgestellt wird), um Schritte nach der Installation auszuführen. Er wechselt jedoch nicht den aktiven Boot-Slot. Anschließend wechselt er bei Erfolg in den Status PREPARE_COMPLETE oder bei einem Fehler in den Status PREPARE_FAILURE.
Systemupdate aussetzen
Sie können den Updatevorgang nur für Systemupdates pausieren. Diese Anfrage ist nur gültig, wenn der Status PREPARE ist.
Suspend (Aussetzen): Pausiert das Update und wechselt den Status über
PREPARE_SUSPEND.rpc Suspend(SuspendRequest) returns (SuspendResponse) {} message SuspendRequest {} message SuspendResponse {}Bei Erfolg wechselt der Status zu
PREPARE_SUSPEND_COMPLETE. Bei einem Fehler wechselt der Status zuPREPARE_FAILURE.Resume (Fortsetzen): Setzt das pausierte Update fort. Dies ist nur im Status
PREPARE_SUSPEND_COMPLETEgültig.rpc Resume(ResumeRequest) returns (ResumeResponse) {} message ResumeRequest {} message ResumeResponse {}Der Status wechselt zurück zu
PREPARE.
Nutzlast für Update von Dienstpaketen
Bei einem Update von Dienstpaketen wird ServiceBundleUpdatePayload verwendet. Diese Nutzlast enthält die Pfade zu den APEX-Dateien und legt das Limit für Aktivierungsversuche fest.
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;
}
Der Update Manager prüft, ob die APEX-Dateien korrekt signiert sind, und stellt sie in einer Sitzung bereit. Bei Erfolg wechselt der Status zu PREPARE_COMPLETE. Bei einem Fehler wechselt der Status zu PREPARE_FAILURE.
Aktivieren
Die Anfrage Activate aktiviert das vorbereitete Update beim nächsten Neustart.
rpc Activate(ActivateRequest) returns (ActivateResponse) {}
message ActivateRequest {}
message ActivateResponse {}
Vor dem Neustart
Der Update Manager wechselt in den Status ACTIVATE_PRE_REBOOT, während er das Update aktiviert. Außerdem erstellt er einen Prüfpunkt
für Nutzerdaten, der beim Neustart des Systems wirksam wird.
Die Aktivierungsaktionen unterscheiden sich je nach Update-Typ:
- Systemupdate:Das System führt Schritte nach der Installation aus und legt fest, dass der Boot-Slot beim nächsten Neustart gewechselt wird.
- Update von Dienstpaketen:Das System markiert die bereitgestellte APEX-Sitzung als bereit zur Aktivierung.
Wenn das System das Update erfolgreich aktiviert, wechselt der Status zu ACTIVATE_PRE_REBOOT_COMPLETE. Dies zeigt an, dass die VM bereit für den Neustart ist.
Andernfalls wechselt der Status zu ACTIVATE_PRE_REBOOT_FAILURE.
Nach Neustart
Nach dem Neustart wird das System im Prüfpunktmodus gestartet. In diesem Modus werden keine Änderungen an der Partition für Nutzerdaten im permanenten Speicher gespeichert. Wenn das System das Update nicht erfolgreich bestätigt, werden diese Änderungen auf den ursprünglichen Zustand zurückgesetzt.
Boot-Limit
Das System setzt die Änderungen an der Partition für Nutzerdaten unter einer der folgenden Bedingungen zurück:
- Der Client sendet eine explizite
Rollback()-Anfrage und startet das System neu. - Das System wird zu oft gestartet, ohne dass der Client
Commit()oderRollback()aufruft. Das Boot-Limit unterscheidet sich je nach Update-Typ:- Systemupdate:Dies wird durch die
BootControl-Implementierung festgelegt. Das Standardlimit in der Implementierung, die von Cuttlefish Geräten verwendet wird, beträgt beispielsweise sieben Starts. - Update von Dienstpaketen:Dies wird durch das Feld
boot_attemptsderServiceBundleUpdatePayloadfestgelegt, die vom Client bereitgestellt wird, wenn die AnfragePrepare()gesendet wird.
- Systemupdate:Dies wird durch die
Bestätigung
Das System überprüft dann das Update:
- Systemupdate: dm-verity prüft den aktualisierten Slot auf Beschädigungen.
- Update von Dienstpaketen:
apexdprüft die Signatur jeder APEX-Datei und hängt das Image der APEX-Datei an das Dateisystem an.
Wenn die Bestätigung erfolgreich ist, wechselt der Status zu ACTIVATE_POST_REBOOT_COMPLETE. Der Update Manager wartet auf Commit() oder Rollback().
Wenn die Bestätigung fehlschlägt, wird das System neu gestartet. Wenn das System das Boot Limit erreicht, wird der ursprüngliche Zustand wiederhergestellt:
- Systemupdate:Das System wechselt zurück zum ursprünglichen Slot.
- Update von Dienstpaketen:Die aktualisierten APEX-Dateien werden verworfen und die ursprünglichen APEX-Dateien werden wieder aktiviert.
Wenn die Bestätigung für einen Update-Typ fehlschlägt, wechselt der Status zu ACTIVATE_PRE_REBOOT_FAILURE, nachdem der ursprüngliche Zustand wiederhergestellt wurde.
Rollback
Die Anfrage Rollback startet die Rückkehr des Systems zum Zustand vor dem Update.
rpc Rollback(RollbackRequest) returns (RollbackResponse) {}
message RollbackRequest {}
message RollbackResponse {}
Sie können die Anfrage Rollback() in vielen Status senden. Je nach Ausgangsstatus führt das System unterschiedliche Aktionen aus und es folgen unterschiedliche Status:
| Status, wenn Rollback ausgeführt wird | Statusübergang | Systemaktion |
|---|---|---|
(Nur Systemupdate) PREPARE, PREPARE_SUSPEND_COMPLETE |
→ PREPARE_CANCEL → PREPARE_ROLLBACK →
READY |
Systemupdate:Bricht das Systemupdate ab. |
PREPARE_FAILURE, PREPARE_COMPLETE |
→ PREPARE_ROLLBACK → READY |
Systemupdate: Bricht das Systemupdate ab. Update von Dienstpaketen: Bricht die bereitgestellte APEX-Sitzung ab. |
ACTIVATE_PRE_REBOOT_COMPLETE, ACTIVATE_PRE_REBOOT_FAILURE |
→ ACTIVATE_PRE_REBOOT_ROLLBACK → READY |
Deaktiviert den Prüfpunkt für Nutzerdaten. Systemupdate: Bricht den Wechsel des Boot-Slots ab. Update von Dienstpaketen: Entfernt die bereitgestellte APEX-Datei. |
ACTIVATE_POST_REBOOT_COMPLETE |
→
ACTIVATE_POST_REBOOT_ROLLBACK → ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE |
Deaktiviert den Prüfpunkt für Nutzerdaten. Systemupdate: Wechselt den Boot-Slot zurück. Update von Dienstpaketen: Setzt die aktiven APEX-Sitzungen zurück. Damit das Rollback wirksam wird, ist ein letzter Neustart erforderlich. Danach wechselt der Status zu READY.
|
Commit
Diese Anfrage zeigt an, dass das Update erfolgreich abgeschlossen wurde, und wendet alle Änderungen dauerhaft an.
rpc Commit(CommitRequest) returns (CommitResponse) {}
message CommitRequest {}
message CommitResponse {}
Der Status wechselt zu COMMIT, während die Commit-Aktionen ausgeführt werden:
- Systemupdate:Der Update Manager markiert den Boot als erfolgreich. Dadurch wird ein zukünftiges Rollback verhindert und dieser Slot bei nachfolgenden Starts ausgewählt.
- Update von Dienstpaketen:Der Update Manager markiert die bereitgestellte APEX-Sitzung als erfolgreich, schließt die Update-Sitzung und aktiviert die Pakete dauerhaft.
Nachdem das System das Update bestätigt hat, bestätigt der Update Manager den Prüfpunkt für Nutzerdaten. Das System speichert alle neuen Nutzerdaten, die während dieses Starts geschrieben wurden, im permanenten Speicher. Der Update Manager wechselt zurück zu READY, was anzeigt, dass das Update abgeschlossen ist.
APEX-Dateien deinstallieren
Die Anfrage UninstallApex entfernt die /data-Version von Dienstpaketen. Sie können UninstallApex in jedem Status aufrufen. Die VM muss jedoch neu gestartet werden, damit die Deinstallation wirksam wird. Rufen Sie UninstallApex daher nicht auf, während ein Update ausgeführt wird. UninstallApex entfernt keine vorinstallierten APEX-Dateien, löscht keine APEX-Daten und entfernt keine inaktiven APEX-Versionen.
rpc UninstallApex(UninstallApexRequest) returns (UninstallApexResponse) {}
message UninstallApexRequest {
message ApexInfo {
string module_name = 1;
int64 version_code = 2;
}
repeated ApexInfo apexes = 1;
}
message UninstallApexResponse {}