O Update Manager realiza atualizações para a VM. O Update Manager coordena com o cliente, que é fornecido pelo integrador de sistemas. O cliente fornece o payload de atualização e coordena a atualização geral do veículo. A atualização consiste nestas etapas:
- PRONTO:nenhuma atualização está em andamento.
- PREPARAR:o Update Manager grava a atualização no disco, mas não a ativa.
- ATIVAR:o Gerenciador de atualizações ativa a atualização preparada para que ela entre em vigor após uma reinicialização.
- CONFIRMAR:o Gerenciador de atualizações torna a atualização permanente.
Figura 1. Operação de alto nível do Update Manager.
O Gerenciador de atualizações oferece suporte a atualizações do sistema e do pacote de serviços, que são descritas nesta página.
Atualizações do sistema
O SO Android usa dois conjuntos de partições chamados de slots, com apenas um slot ativo por vez. Uma atualização do sistema grava um novo conjunto de partições no slot inativo, e o sistema troca o slot ativo na próxima reinicialização. Para mais informações sobre como criar atualizações do sistema, consulte Atualizações do sistema A/B.
Atualizações de pacotes de serviços
No AAOS SDV, os pacotes de serviços agrupam serviços em APEXes. As atualizações do pacote de serviços preparam novos arquivos APEX em sessões temporárias. O sistema ativa esses pacotes atualizados após uma reinicialização. Para mais informações sobre como criar APEXs de pacote de serviços, consulte Atualizações do pacote de serviços.
Máquina de estado
As solicitações do cliente e os eventos dos serviços do sistema impulsionam a máquina de estados do Update Manager. O Gerenciador de atualizações foi projetado para ser resiliente, recuperando o estado e retomando o processo de atualização mesmo após reinicializações ou falhas inesperadas.
Figura 2. Máquina de estado do Update Manager.
API
O Update Manager fornece uma API que impulsiona o processo de atualização pela máquina de estados. A API usa VSIDL, que é compatível com clientes em qualquer VM que ofereça suporte a comunicações SDV e fornece notificação de falha na solicitação.
Segurança e acesso
O sistema restringe o acesso à API usando políticas de autorização. Somente o cliente autorizado pode fazer chamadas para o Gerenciador de atualizações.
atualizações de status
Como as operações de atualização podem ser de longa duração, o Gerenciador de atualizações fornece atualizações de status assíncronas. Os clientes precisam monitorar o estado inscrevendo-se nas atualizações de status.
Gerenciamento de assinatura
Inscrição:os clientes se inscrevem para receber atualizações de status chamando o método
SubscribeToStatusUpdates():rpc SubscribeToStatusUpdates(SubscribeToStatusUpdatesRequest) returns (SubscribeToStatusUpdatesResponse) {} message SubscribeToStatusUpdatesRequest {} message SubscribeToStatusUpdatesResponse {}Antes de chamar
SubscribeToStatusUpdates(), o cliente precisa iniciar uma interface RPC que implementaUpdateManagerListenerService.Cancelamento da inscrição:os clientes podem parar de receber atualizações de status chamando
UnsubscribeFromStatusUpdates():rpc UnsubscribeFromStatusUpdates(UnsubscribeFromStatusUpdatesRequest) returns (UnsubscribeFromStatusUpdatesResponse) {} message UnsubscribeFromStatusUpdatesRequest {} message UnsubscribeFromStatusUpdatesResponse {}
UpdateManagerListenerService
Os clientes que chamam SubscribeToStatusUpdates() em UpdateManagerService precisam
implementar o seguinte serviço para receber atualizações de status:
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 {}
O OnStatusUpdateRequest entrega uma de duas mensagens possíveis usando o campo status_update:
UpdateManagerStatus: enviado quando o estado do Gerenciador de atualizações muda.UpdateProgress: enviado para indicar o progresso da atualização durante os estadosPREPAREeACTIVATE_PRE_REBOOT, já que o processo pode levar um tempo significativo.
Status e mensagens de erro
As mensagens de status incluem detalhes sobre o estado e falhas:
UpdateManagerStatus:informa a fase atual da atualização e o motivo da falha: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 o status atual do Update Engine durante as atualizações do 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; }
Receber status imediato
Você pode recuperar o estado e a carga útil atuais a qualquer momento chamando
GetStatus(). As mensagens SystemUpdatePayload e ServiceBundleUpdatePayload
são descritas em Preparar.
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;
}
}
Preparação
A solicitação Prepare inicia o processo de atualização ao preparar o payload, mas o
sistema aguarda para ativar a atualização:
rpc Prepare(PrepareRequest) returns (PrepareResponse) {}
message PrepareRequest {
oneof payload {
SystemUpdatePayload system_update_payload = 1;
ServiceBundleUpdatePayload service_bundle_update_payload = 2;
}
}
message PrepareResponse {}
Se a solicitação for válida, o estado vai mudar para PREPARE, e o Update
Manager vai iniciar a atualização.
O tipo do payload determina o tipo de atualização.
Payload de atualização do sistema
Uma atualização do sistema usa os dados SystemUpdatePayload, que exigem um caminho para uma imagem de atualização over-the-air (OTA). Os outros parâmetros são analisados da imagem, mas você pode especificá-los para substituir os valores analisados.
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;
}
O Update Manager processa a imagem OTA (fornecida pelo cliente no diretório
/data/ota_package) para executar etapas pós-instalação, mas não troca
o slot de inicialização ativo. Em seguida, ele passa para o estado PREPARE_COMPLETE em caso de
sucesso ou para o estado PREPARE_FAILURE em caso de falha.
Suspensão da atualização do sistema
É possível pausar o processo de atualização apenas para atualizações do sistema. Essa solicitação é válida
apenas quando está no estado PREPARE.
Suspender:pausa a atualização, fazendo a transição do estado por
PREPARE_SUSPEND.rpc Suspend(SuspendRequest) returns (SuspendResponse) {} message SuspendRequest {} message SuspendResponse {}Em caso de sucesso, o estado passa a ser
PREPARE_SUSPEND_COMPLETE. Em caso de falha, o estado passa a serPREPARE_FAILURE.Retomar:continua a atualização pausada. Isso é válido apenas no estado
PREPARE_SUSPEND_COMPLETE.rpc Resume(ResumeRequest) returns (ResumeResponse) {} message ResumeRequest {} message ResumeResponse {}O estado volta para
PREPARE.
Payload de atualização do pacote de serviços
Uma atualização do pacote de serviços usa o ServiceBundleUpdatePayload, que contém os caminhos para os arquivos APEX e define o limite de tentativas de ativação.
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;
}
O Gerenciador de atualizações verifica se os arquivos APEX estão assinados corretamente e os
prepara em uma sessão. Em caso de sucesso, o estado passa a ser PREPARE_COMPLETE. Em caso de falha, o estado passa a ser PREPARE_FAILURE.
Ativar
A solicitação Activate ativa a atualização preparada na próxima reinicialização.
rpc Activate(ActivateRequest) returns (ActivateResponse) {}
message ActivateRequest {}
message ActivateResponse {}
Pré-reinicialização
O Update Manager faz a transição para o estado ACTIVATE_PRE_REBOOT ao
ativar a atualização. O Gerenciador de atualizações também cria um ponto de verificação de dados do usuário que entra em vigor quando o sistema é reinicializado.
As ações de ativação variam de acordo com o tipo de atualização:
- Atualização do sistema:o sistema executa etapas pós-instalação e define o slot de inicialização para ativar na próxima reinicialização.
- Atualização do pacote de serviços:o sistema marca a sessão APEX em etapas como pronta para ativação.
Se o sistema ativar a atualização, o estado vai mudar para
ACTIVATE_PRE_REBOOT_COMPLETE, o que indica que a VM está pronta para reinicialização.
Caso contrário, o estado passa a ser ACTIVATE_PRE_REBOOT_FAILURE.
Pós reinicialização
Após a reinicialização, o sistema será iniciado no modo de checkpoint. Nesse modo, o sistema não confirma nenhuma mudança na partição de dados do usuário para o armazenamento permanente. Se o sistema não confirmar a atualização, ele vai reverter essas mudanças para o estado inicial.
Limite de inicialização
O sistema reverte as mudanças na partição de dados do usuário em uma destas condições:
- O cliente envia uma solicitação
Rollback()explícita e reinicia o sistema. - O sistema é inicializado muitas vezes sem que o cliente chame
Commit()ouRollback(). O limite de inicialização varia de acordo com o tipo de atualização:- Atualização do sistema:a implementação
BootControldefine isso. Por exemplo, o limite padrão na implementação usada por dispositivos Cuttlefish é de sete inicializações. - Atualização do pacote de serviços:o campo
boot_attemptsdoServiceBundleUpdatePayloadfornecido pelo cliente define isso quando a solicitaçãoPrepare()é feita.
- Atualização do sistema:a implementação
Verificação
Em seguida, o sistema verifica a atualização:
- Atualização do sistema:o dm-verity verifica se há corrupção no slot atualizado.
- Atualização do pacote de serviços:o
apexdverifica a assinatura de cada APEX e monta a imagem do APEX no sistema de arquivos.
Se a verificação for bem-sucedida, o estado vai mudar para
ACTIVATE_POST_REBOOT_COMPLETE. O Update Manager aguarda Commit() ou Rollback().
Se a verificação falhar, o sistema será reinicializado. Quando o sistema atinge o limite de inicialização, ele volta ao estado original:
- Atualização do sistema:o sistema volta ao slot original.
- Atualização do pacote de serviços:os APEXes atualizados são descartados, e os APEXes originais são reativados.
Se a verificação falhar para qualquer tipo de atualização, o estado vai mudar para
ACTIVATE_PRE_REBOOT_FAILURE depois que o estado original for restaurado.
Reversão
A solicitação Rollback começa a retornar o sistema ao estado anterior à atualização.
rpc Rollback(RollbackRequest) returns (RollbackResponse) {}
message RollbackRequest {}
message RollbackResponse {}
Você pode fazer a solicitação de Rollback() em vários estados. Dependendo do
estado inicial, o sistema realiza ações diferentes, e estados diferentes são seguidos:
| Estado quando a reversão é emitida | Transição de estado | Ação do sistema |
|---|---|---|
(Somente atualização do sistema) PREPARE, PREPARE_SUSPEND_COMPLETE |
→ PREPARE_CANCEL → PREPARE_ROLLBACK →
READY |
Atualização do sistema:cancela a atualização do sistema. |
PREPARE_FAILURE, PREPARE_COMPLETE |
→ PREPARE_ROLLBACK → READY |
Atualização do sistema:cancela a atualização do sistema. Atualização do pacote de serviços:interrompe a sessão APEX em etapas. |
ACTIVATE_PRE_REBOOT_COMPLETE, ACTIVATE_PRE_REBOOT_FAILURE |
→ ACTIVATE_PRE_REBOOT_ROLLBACK → READY |
Desativa o ponto de verificação de dados do usuário. Atualização do sistema:cancela a troca de slot de inicialização. Atualização do pacote de serviços:remove o APEX temporário. |
ACTIVATE_POST_REBOOT_COMPLETE |
→
ACTIVATE_POST_REBOOT_ROLLBACK → ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE |
Desativa o ponto de verificação de dados do usuário. Atualização do sistema:troca o slot de inicialização de volta. Atualização do pacote de serviços:reverte as sessões APEX ativas. É necessário fazer uma reinicialização final para que a reversão entre em vigor. Depois disso, o estado passa para READY.
|
Confirmação
Essa solicitação indica que a atualização foi concluída e aplica todas as mudanças de forma permanente.
rpc Commit(CommitRequest) returns (CommitResponse) {}
message CommitRequest {}
message CommitResponse {}
O estado passa para COMMIT ao realizar as ações de commit:
- Atualização do sistema:o Gerenciador de atualizações marca a inicialização como bem-sucedida, o que impede reversões futuras e seleciona esse slot nas inicializações subsequentes.
- Atualização do pacote de serviços:o Gerenciador de atualizações marca a sessão APEX em etapas como concluída, encerrando a sessão de atualização e ativando os pacotes de forma permanente.
Depois que o sistema confirma a atualização, o Gerenciador de atualizações confirma o ponto de verificação dos dados do usuário. O sistema confirma todos os novos dados do usuário gravados durante essa inicialização no
armazenamento permanente. O Gerenciador de atualizações volta para READY, indicando
que a atualização foi concluída.
Desinstalar APEXs
A solicitação UninstallApex remove a versão /data dos pacotes de serviços. É possível chamar UninstallApex em qualquer estado, mas a VM precisa ser reinicializada para que a desinstalação entre em vigor. Portanto, evite chamar UninstallApex enquanto uma
atualização estiver em andamento. O UninstallApex não remove APEXes pré-instalados, apaga
dados do APEX nem remove versões inativas do APEX.
rpc UninstallApex(UninstallApexRequest) returns (UninstallApexResponse) {}
message UninstallApexRequest {
message ApexInfo {
string module_name = 1;
int64 version_code = 2;
}
repeated ApexInfo apexes = 1;
}
message UninstallApexResponse {}