Update Manager realiza actualizaciones para su VM. Update Manager se coordina con el cliente, que es proporcionado por el integrador de sistemas. El cliente proporciona la carga útil de la actualización y coordina la actualización general del vehículo. La actualización consta de los siguientes pasos:
- READY: No hay ninguna actualización en curso.
- PREPARE: Update Manager escribe la actualización en el disco, pero no la activa.
- ACTIVATE: Update Manager activa la actualización preparada para que surta efecto después de un reinicio.
- COMMIT: Update Manager hace que la actualización sea permanente.
Figura 1: Operación de alto nivel de Update Manager
Update Manager admite actualizaciones del sistema y actualizaciones de paquetes de servicios, que se describen en esta página.
Actualizaciones del sistema
El SO Android usa dos conjuntos de particiones llamadas slots, con solo una ranura activa a la vez. Una actualización del sistema escribe un nuevo conjunto de particiones en la ranura inactiva, y el sistema cambia la ranura activa en el próximo reinicio. Para obtener más información sobre la compilación de actualizaciones del sistema, consulta Actualizaciones del sistema A/B.
Actualizaciones de paquetes de servicios
En AAOS SDV, los paquetes de servicios agrupan los servicios dentro de los APEX. Las actualizaciones de paquetes de servicios organizan los archivos APEX nuevos en sesiones temporales. El sistema activa estos paquetes actualizados después de un reinicio del sistema. Para obtener más información sobre la compilación de APEX de paquetes de servicios, consulta Actualizaciones de paquetes de servicios.
Máquina de estados
Las solicitudes del cliente y los eventos de los servicios del sistema controlan la máquina de estados de Update Manager. Update Manager está diseñado para ser resistente, recuperar su estado y reanudar el proceso de actualización incluso después de reinicios o fallas inesperados.
Figura 2: Máquina de estados de Update Manager
API
Update Manager proporciona una API que controla el proceso de actualización a través de la máquina de estados. La API usa VSIDL, que admite clientes que residen en cualquier VM que admita SDV Comms y proporciona una notificación de falla de solicitud.
Seguridad y acceso
El sistema restringe el acceso a la API mediante políticas de autorización. Solo el cliente autorizado puede realizar llamadas a Update Manager.
Actualizaciones de estado
Debido a que las operaciones de actualización pueden ser de larga duración, Update Manager proporciona actualizaciones de estado asíncronas. Los clientes deben supervisar el estado suscribiéndose a las actualizaciones de estado.
Administración de suscripciones
Suscripción: Los clientes se suscriben a las actualizaciones de estado llamando al método
SubscribeToStatusUpdates():rpc SubscribeToStatusUpdates(SubscribeToStatusUpdatesRequest) returns (SubscribeToStatusUpdatesResponse) {} message SubscribeToStatusUpdatesRequest {} message SubscribeToStatusUpdatesResponse {}Antes de llamar a
SubscribeToStatusUpdates(), el cliente debe iniciar una interfaz RPC que implementeUpdateManagerListenerService.Anulación de la suscripción: Los clientes pueden dejar de recibir actualizaciones de estado llamando a
UnsubscribeFromStatusUpdates():rpc UnsubscribeFromStatusUpdates(UnsubscribeFromStatusUpdatesRequest) returns (UnsubscribeFromStatusUpdatesResponse) {} message UnsubscribeFromStatusUpdatesRequest {} message UnsubscribeFromStatusUpdatesResponse {}
UpdateManagerListenerService
Los clientes que llaman a SubscribeToStatusUpdates() en UpdateManagerService deben implementar el siguiente servicio para recibir actualizaciones de estado:
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 entrega uno de los dos mensajes posibles con el campo status_update:
UpdateManagerStatus: Se envía cuando cambia el estado de Update Manager.UpdateProgress: Se envía para indicar el progreso de la actualización durante los estadosPREPAREyACTIVATE_PRE_REBOOT, ya que el proceso puede tardar una cantidad de tiempo significativa.
Mensajes de estado y error
Los mensajes de estado incluyen detalles sobre el estado y las fallas:
UpdateManagerStatus: Informa la fase actual de la actualización y cualquier motivo de falla: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: Informa el estado actual de Update Engine durante las actualizaciones del sistema: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; }
Obtén el estado inmediato
Puedes recuperar el estado y la carga útil actuales en cualquier momento llamando a GetStatus(). Los mensajes SystemUpdatePayload y ServiceBundleUpdatePayload
se describen en Preparación.
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;
}
}
Preparación
La solicitud Prepare inicia el proceso de actualización organizando la carga útil, pero el sistema espera para activar la actualización:
rpc Prepare(PrepareRequest) returns (PrepareResponse) {}
message PrepareRequest {
oneof payload {
SystemUpdatePayload system_update_payload = 1;
ServiceBundleUpdatePayload service_bundle_update_payload = 2;
}
}
message PrepareResponse {}
Si la solicitud es válida, el estado pasa a PREPARE y Update Manager inicia la actualización.
El tipo de carga útil determina el tipo de actualización.
Carga útil de la actualización del sistema
Una actualización del sistema usa los datos SystemUpdatePayload, que requieren una ruta de acceso a una imagen de actualización inalámbrica (OTA). Los otros parámetros se analizan a partir de la imagen, pero puedes especificarlos para anular los valores analizados.
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 procesa la imagen OTA (proporcionada por el cliente en el directorio /data/ota_package) para ejecutar los pasos posteriores a la instalación, pero no cambia la ranura de inicio activa. Luego, pasa al estado PREPARE_COMPLETE si la operación se realiza correctamente o al estado PREPARE_FAILURE si falla.
Suspensión de la actualización del sistema
Solo puedes pausar el proceso de actualización para las actualizaciones del sistema. Esta solicitud solo es válida cuando está en el estado PREPARE.
Suspend: Pausa la actualización y pasa el estado a través de
PREPARE_SUSPEND.rpc Suspend(SuspendRequest) returns (SuspendResponse) {} message SuspendRequest {} message SuspendResponse {}Si la operación se realiza correctamente, el estado pasa a
PREPARE_SUSPEND_COMPLETE. Si falla, el estado cambia aPREPARE_FAILURE.Resume: Continúa con la actualización pausada. Esto solo es válido en el estado
PREPARE_SUSPEND_COMPLETE.rpc Resume(ResumeRequest) returns (ResumeResponse) {} message ResumeRequest {} message ResumeResponse {}El estado vuelve al estado
PREPARE.
Carga útil de la actualización de paquetes de servicios
Una actualización de paquetes de servicios usa ServiceBundleUpdatePayload, que contiene las rutas de acceso a los archivos APEX y establece el límite de intentos de activación.
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 verifica que los archivos APEX estén firmados correctamente y los organiza en una sesión. Si la operación se realiza correctamente, el estado pasa a PREPARE_COMPLETE. Si falla, el estado cambia a PREPARE_FAILURE.
Activar
La solicitud Activate activa la actualización preparada en el próximo reinicio.
rpc Activate(ActivateRequest) returns (ActivateResponse) {}
message ActivateRequest {}
message ActivateResponse {}
Antes del reinicio
Update Manager pasa al estado ACTIVATE_PRE_REBOOT mientras activa la actualización. Update Manager también crea un punto de control
de datos del usuario que entra en vigencia cuando se reinicia el sistema.
Las acciones de activación difieren según el tipo de actualización:
- Actualización del sistema: El sistema ejecuta los pasos posteriores a la instalación y establece la ranura de inicio para que se active en el próximo reinicio.
- Actualización de paquetes de servicios: El sistema marca la sesión de APEX organizada como lista para la activación.
Si el sistema activa la actualización correctamente, el estado pasa a ACTIVATE_PRE_REBOOT_COMPLETE, lo que indica que la VM está lista para reiniciarse.
De lo contrario, el estado pasa a ACTIVATE_PRE_REBOOT_FAILURE.
Inicio posterior
Después del reinicio, el sistema se inicia en el modo de punto de control. En este modo, el sistema no confirma ningún cambio en la partición de datos del usuario en el almacenamiento permanente. Si el sistema no confirma la actualización correctamente, revierte estos cambios al estado inicial.
Límite de inicio
El sistema revierte los cambios en la partición de datos del usuario en cualquiera de estas condiciones:
- El cliente envía una solicitud
Rollback()explícita y reinicia el sistema. - El sistema se inicia demasiadas veces sin que el cliente llame a
Commit()ni aRollback(). El límite de inicio difiere para cada tipo de actualización:- Actualización del sistema: La implementación de
BootControlestablece esto. Por ejemplo, el límite predeterminado en la implementación que usan los dispositivos Cuttlefish es de siete inicios. - Actualización de paquetes de servicios: El campo
boot_attemptsdeServiceBundleUpdatePayloadproporcionado por el cliente establece esto cuando se realiza la solicitudPrepare().
- Actualización del sistema: La implementación de
Verificación
Luego, el sistema verifica la actualización:
- Actualización del sistema: dm-verity verifica si la ranura actualizada está dañada.
- Actualización de paquetes de servicios:
apexdverifica la firma de cada APEX y monta la imagen del APEX en el sistema de archivos.
Si la verificación se realiza correctamente, el estado pasa a ACTIVATE_POST_REBOOT_COMPLETE. Update Manager espera Commit() o Rollback().
Si la verificación falla, el sistema se reinicia. Cuando el sistema alcanza el límite de inicio, vuelve al estado original:
- Actualización del sistema: El sistema vuelve a la ranura original.
- Actualización de paquetes de servicios: Se descartan los APEX actualizados y se reactivan los APEX originales.
Si falla la verificación para cualquier tipo de actualización, el estado pasa a ACTIVATE_PRE_REBOOT_FAILURE después de que se restablece el estado original.
Revertir
La solicitud Rollback comienza a devolver el sistema a su estado anterior a la actualización.
rpc Rollback(RollbackRequest) returns (RollbackResponse) {}
message RollbackRequest {}
message RollbackResponse {}
Puedes realizar la solicitud Rollback() durante muchos estados. Según el estado inicial, el sistema realiza diferentes acciones y siguen diferentes estados:
| Estado cuando se emite la reversión | Transición de estado | Acción del sistema |
|---|---|---|
(Solo actualización del sistema) PREPARE, PREPARE_SUSPEND_COMPLETE |
→ PREPARE_CANCEL → PREPARE_ROLLBACK →
READY |
Actualización del sistema: Cancela la actualización del sistema. |
PREPARE_FAILURE, PREPARE_COMPLETE |
→ PREPARE_ROLLBACK → READY |
Actualización del sistema: Cancela la actualización del sistema. Actualización de paquetes de servicios: Anula la sesión de APEX organizada. |
ACTIVATE_PRE_REBOOT_COMPLETE, ACTIVATE_PRE_REBOOT_FAILURE |
→ ACTIVATE_PRE_REBOOT_ROLLBACK → READY |
Inhabilita el punto de control de datos del usuario. Actualización del sistema: Cancela el cambio de ranura de inicio. Actualización de paquetes de servicios: Quita el APEX organizado. |
ACTIVATE_POST_REBOOT_COMPLETE |
→
ACTIVATE_POST_REBOOT_ROLLBACK → ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE |
Inhabilita el punto de control de datos del usuario. Actualización del sistema: Vuelve a cambiar la ranura de inicio. Actualización de paquetes de servicios: Revierte las sesiones de APEX activas. Se requiere un reinicio final para que la reversión surta efecto, después de lo cual el estado pasa a READY.
|
Confirmar
Esta solicitud indica que la actualización se completó correctamente y aplica todos los cambios de forma permanente.
rpc Commit(CommitRequest) returns (CommitResponse) {}
message CommitRequest {}
message CommitResponse {}
El estado pasa a COMMIT mientras se realizan las acciones de confirmación:
- Actualización del sistema: Update Manager marca el inicio como exitoso, lo que evita la reversión futura y selecciona esta ranura en los inicios posteriores.
- Actualización de paquetes de servicios: Update Manager marca la sesión de APEX organizada como exitosa, cierra la sesión de actualización y hace que los paquetes estén activos de forma permanente.
Después de que el sistema confirma la actualización, Update Manager confirma el punto de control de datos del usuario. El sistema confirma todos los datos de usuario nuevos escritos durante este inicio en el almacenamiento permanente. Update Manager vuelve a READY, lo que indica que la actualización se completó.
Desinstalar APEX
La solicitud UninstallApex quita la versión /data de los paquetes de servicios. Puedes llamar a UninstallApex durante cualquier estado, pero la VM debe reiniciarse para que la desinstalación surta efecto. Por lo tanto, evita llamar a UninstallApex mientras se realiza una actualización. UninstallApex no quita los APEX preinstalados, no borra los datos de APEX ni quita las versiones inactivas de APEX.
rpc UninstallApex(UninstallApexRequest) returns (UninstallApexResponse) {}
message UninstallApexRequest {
message ApexInfo {
string module_name = 1;
int64 version_code = 2;
}
repeated ApexInfo apexes = 1;
}
message UninstallApexResponse {}