As atualizações não AB são uma metodologia descontinuada de OTA usada por dispositivos Android mais antigos (Android 6 e anteriores). Esses dispositivos têm uma partição de recuperação dedicada que contém o software necessário para descompactar um pacote de atualização transferido por download e aplicar a atualização às outras partições.
Em dispositivos Android mais antigos sem partições A/B, o espaço de inicialização geralmente contém as seguintes partições:
- inicialização
- Contém o kernel do Linux e um sistema de arquivos raiz mínimo (carregado em um disco RAM). Ele monta o sistema e outras partições e inicia o ambiente de execução localizado na partição do sistema.
- system
- Contém aplicativos e bibliotecas do sistema que têm código-fonte disponível no Android Open Source Project (AOSP). Durante a operação normal, essa partição é montada como somente leitura. O conteúdo dela muda apenas durante uma atualização OTA.
- fornecedor
- Contém aplicativos e bibliotecas do sistema que não têm o código-fonte disponível no Android Open Source Project (AOSP). Durante a operação normal, essa partição é montada somente leitura. O conteúdo dela muda apenas durante uma atualização OTA.
- userdata
- Armazena os dados salvos por aplicativos instalados pelo usuário etc. Essa partição normalmente não é afetada pelo processo de atualização OTA.
- cache
- Área de retenção temporária usada por alguns aplicativos (o acesso a essa partição requer permissões especiais do app) e para o armazenamento de pacotes de atualização OTA transferidos por download. Outros programas usam esse espaço com a expectativa de que os arquivos possam desaparecer a qualquer momento. Algumas instalações de pacotes OTA podem resultar na eliminação completa dessa partição. O cache também contém os registros de atualização de uma atualização OTA.
- recuperação
- Contém um segundo sistema Linux completo, incluindo um kernel e o binário de recuperação especial que lê um pacote e usa o conteúdo dele para atualizar as outras partições.
- Diversos
- Pequena partição usada pela recuperação para armazenar algumas informações sobre o que está sendo feito caso o dispositivo seja reiniciado enquanto o pacote OTA está sendo aplicado.
Vida útil de uma atualização OTA
Uma atualização OTA típica contém as seguintes etapas:
- O dispositivo faz o check-in regular com os servidores OTA e é notificado sobre a disponibilidade de uma atualização, incluindo o URL do pacote de atualização e uma string de descrição para mostrar ao usuário.
-
Faz a atualização de downloads para uma partição de dados ou de cache, e a assinatura criptográfica é verificada
em relação aos certificados em
/system/etc/security/otacerts.zip
. O usuário é solicitado a instalar a atualização. - O dispositivo é reinicializado no modo de recuperação, em que o kernel e o sistema na partição de recuperação são inicializados em vez do kernel na partição de inicialização.
-
O binário de recuperação é iniciado pelo init. Ele encontra argumentos de linha de comando em
/cache/recovery/command
que apontam para o pacote transferido. -
A recuperação verifica a assinatura criptográfica do pacote em relação às chaves públicas em
/res/keys
(parte do disco RAM contido na partição de recuperação). - Os dados são extraídos do pacote e usados para atualizar as partições de inicialização, do sistema e/ou do fornecedor, conforme necessário. Um dos novos arquivos deixados na partição do sistema contém o conteúdo da nova partição de recuperação.
-
O dispositivo é reinicializado normalmente.
- A partição de inicialização atualizada é carregada, montada e começa a executar binários na partição do sistema atualizada.
-
Como parte da inicialização normal, o sistema verifica o conteúdo da partição de recuperação
em relação ao conteúdo desejado (que foi armazenado anteriormente como um arquivo em
/system
). Como eles são diferentes, a partição de recuperação é reescrita com o conteúdo desejado. (Em inicializações subsequentes, a partição de recuperação já contém o novo conteúdo, portanto, não é necessário refazer o flash.)
A atualização do sistema foi concluída. Os registros de atualização podem ser encontrados em
/cache/recovery/last_log.#
.
Atualizar pacotes
Um pacote de atualização é um arquivo .zip
que contém o binário executável
META-INF/com/google/android/update-binary
. Depois de verificar a assinatura no
pacote, o recovery
extrai esse binário para /tmp
e o executa,
transmitindo os seguintes argumentos:
- Atualize o número da versão da API binária. Se os argumentos transmitidos para a mudança de binário da atualização forem alterados, esse número vai aumentar.
- Descritor de arquivos do canal de comando. O programa de atualização pode usar esse pipe para enviar comandos de volta ao binário de recuperação, principalmente para mudanças na interface, como indicar o progresso ao usuário.
-
Nome do arquivo
.zip
do pacote de atualização.
Um pacote de atualização pode usar qualquer binário vinculado estaticamente como o binário de atualização. As ferramentas de construção
do pacote OTA usam o programa de atualização (bootable/recovery/updater
), que
oferece uma linguagem de script simples que pode realizar muitas tarefas de instalação. É possível substituir
qualquer outro binário em execução no dispositivo.
Para saber mais sobre o binário do atualizador, a sintaxe do edify e as funções integradas, consulte Dentro dos pacotes OTA.
Migrar de versões anteriores
Ao migrar do Android 2.3/3.0/4.0, a principal mudança é a conversão de todas as funcionalidades específicas do dispositivo de um conjunto de funções C com nomes predefinidos para objetos C++. A tabela a seguir lista as funções antigas e os novos métodos que servem a uma finalidade equivalente:
Função C | Método C++ |
---|---|
device_recovery_start() | Device::RecoveryStart() |
device_toggle_display() device_reboot_now() |
RecoveryUI::CheckKey() (também RecoveryUI::IsKeyPressed()) |
device_handle_key() | Device::HandleMenuKey() |
device_perform_action() | Device::InvokeMenuItem() |
device_wipe_data() | Device::WipeData() |
device_ui_init() | ScreenRecoveryUI::Init() |
A conversão de funções antigas em novos métodos precisa ser razoavelmente simples. Não se esqueça
de adicionar a nova função make_device()
para criar e retornar uma instância da nova subclasse de dispositivo.