Criar pacotes OTA

É possível usar a ferramenta ota_from_target_files fornecida no build/make/tools/releasetools para criar pacotes OTA completos e incrementais para dispositivos que usam atualizações do sistema A/B ou atualizações do sistema não A/B. A ferramenta usa o arquivo target-files.zip produzido pelo sistema de build do Android como entrada.

Para dispositivos com o Android 11 ou versões mais recentes, é possível criar um pacote OTA para vários dispositivos com SKUs diferentes. Para isso, é necessário configurar os dispositivos de destino para usar impressões digitais dinâmicas e atualizar os metadados OTA para incluir o nome do dispositivo e a impressão digital nas entradas de pré e pós condição.

O Android 8.0 desativou pacotes OTA baseados em arquivos para dispositivos que não são A/B, que precisam usar pacotes OTA baseados em blocos. Para gerar pacotes OTA baseados em blocos ou dispositivos com o Android 7.x ou versões anteriores, transmita a opção --block para o parâmetro ota_from_target_files.

Criar atualizações completas

Uma atualização completa é um pacote OTA que contém todo o estado final do dispositivo (partições do sistema, de inicialização e de recuperação). Desde que o dispositivo seja capaz de receber e aplicar o pacote, ele poderá instalar o build independentemente do estado atual do dispositivo. Por exemplo, os comandos a seguir usam ferramentas de lançamento para criar o arquivo target-files.zip do dispositivo tardis.

. build/envsetup.sh && lunch tardis-eng
mkdir dist_output
make dist DIST_DIR=dist_output

O make dist cria um pacote OTA completo (em $OUT). O arquivo .zip resultante contém tudo o que é necessário para criar pacotes OTA para o dispositivo tardis. Também é possível criar o ota_from_target_files como um binário Python e chamá-lo para criar pacotes completos ou incrementais.

ota_from_target_files dist_output/tardis-target_files.zip ota_update.zip

O caminho ota_from_target_files é configurado em $PATH, e o binário Python resultante está localizado no diretório out/.

O ota_update.zip está pronto para ser enviado aos dispositivos de teste. Tudo está assinado com a chave de teste. Para dispositivos do usuário, gere e use suas próprias chaves privadas, conforme detalhado em Assinatura de builds para lançamento.

Criar atualizações incrementais

Uma atualização incremental é um pacote OTA que contém patches binários para os dados que já estão no dispositivo. Os pacotes com atualizações incrementais geralmente são menores, porque não precisam incluir arquivos inalterados. Além disso, como os arquivos modificados são geralmente muito semelhantes às versões anteriores, o pacote só precisa incluir uma codificação das diferenças entre os dois arquivos.

Só é possível instalar um pacote de atualização incremental em dispositivos que têm o build de origem usado na construção do pacote. Para criar uma atualização incremental, você precisa do arquivo target_files.zip do build anterior (aquele que você quer atualizar de) e do arquivo target_files.zip do novo build. Por exemplo, os comandos abaixo usam ferramentas de lançamento para criar uma atualização incremental para o dispositivo tardis.

ota_from_target_files -i PREVIOUS-tardis-target_files.zip dist_output/tardis-target_files.zip incremental_ota_update.zip

Esse build é muito semelhante ao anterior, e o pacote de atualização incremental (incremental_ota_update.zip) é muito menor do que a atualização completa correspondente (cerca de 1 MB em vez de 60 MB).

Distribua um pacote incremental somente para dispositivos que executam exatamente o mesmo build anterior usado como ponto de partida do pacote incremental. É necessário atualizar as imagens em PREVIOUS-tardis-target_files.zip ou PREVIOUS-tardis-img.zip (ambas criadas com make dist, para serem atualizadas com fastboot update), em vez de as que estão no diretório PRODUCT_OUT (criadas com make, que serão atualizadas com fastboot flashall). A tentativa de instalar o pacote incremental em um dispositivo com outro build resulta em um erro de instalação. Quando a instalação falha, o dispositivo permanece no mesmo estado de funcionamento (executando o sistema antigo). O pacote verifica o estado anterior de todos os arquivos que ele atualiza antes de tocá-los, para que o dispositivo não fique preso em um estado parcialmente atualizado.

Para oferecer a melhor experiência ao usuário, ofereça uma atualização completa a cada 3 a 4 atualizações incrementais. Isso ajuda os usuários a atualizar para a versão mais recente e evitar uma longa sequência de instalação de atualizações incrementais.

Criar pacotes OTA para várias SKUs

O Android 11 ou versões mais recentes oferecem suporte ao uso de um único pacote OTA para vários dispositivos com SKUs diferentes. Para isso, é necessário configurar os dispositivos de destino para usar impressões digitais dinâmicas e atualizar os metadados OTA (usando ferramentas OTA) para incluir o nome do dispositivo e a impressão digital nas entradas de pré e pós condição.

Sobre as SKUs

O formato de uma SKU é uma variação de valores combinados de parâmetros de criação e normalmente é um subconjunto não declarado dos parâmetros build_fingerprint atuais. Os OEMs podem usar qualquer combinação de parâmetros de build aprovados pelo CDD para um SKU e também uma única imagem para esses SKUs. Por exemplo, o SKU a seguir tem várias variações:

SKU = <product><device><modifierA><modifierB><modifierC>
  • modifierA é o nível do dispositivo (como Pro, Premium ou Plus)
  • modifierB é a variação de hardware (por exemplo, rádio)
  • modifierC é a região, que pode ser geral (como NA, EMEA ou CHN) ou específica para país ou idioma (como JPN, ENG ou CHN)

Muitos OEMs usam uma única imagem para vários SKUs e derivam o nome do produto final e a impressão digital do dispositivo no momento da execução, depois que o dispositivo é inicializado. Esse processo simplifica o processo de desenvolvimento da plataforma, permitindo que dispositivos com pequenas personalizações, mas com nomes de produtos diferentes, compartilhem imagens comuns (como tardis e tardispro).

Usar impressões digitais dinâmicas

Uma impressão digital é uma concatenação definida de parâmetros de build, como ro.product.brand, ro.product.name e ro.product.device. A impressão digital de um dispositivo é derivada da impressão digital da partição do sistema e é usada como um identificador exclusivo das imagens (e bytes) em execução no dispositivo. Para criar uma impressão digital dinâmica, use a lógica dinâmica no arquivo build.prop do dispositivo para extrair o valor das variáveis do carregador de inicialização no momento da inicialização do dispositivo e, em seguida, use esses dados para criar uma impressão digital dinâmica para esse dispositivo.

Por exemplo, para usar impressões digitais dinâmicas nos dispositivos tardis e tardispro, atualize os seguintes arquivos conforme mostrado abaixo.

  • Atualize o arquivo odm/etc/build_std.prop para conter a linha a seguir.

    ro.odm.product.device=tardis
    
  • Atualize o arquivo odm/etc/build_pro.prop para incluir a seguinte linha.

    ro.odm.product.device=tardispro
    
  • Atualize o arquivo odm/etc/build.prop para incluir as seguintes linhas.

    ro.odm.product.device=tardis
    import /odm/etc/build_${ro.boot.product.hardware.sku}.prop
    

Essas linhas definem dinamicamente o nome do dispositivo, a impressão digital e os valores de ro.build.fingerprint com base no valor da propriedade do carregador de inicialização ro.boot.product.hardware.sku (que é somente leitura).

Atualizar metadados do pacote OTA

Um pacote OTA contém um arquivo de metadados (META-INF/com/android/metadata) que descreve o pacote, incluindo a pré-condição e a pós-condição do pacote OTA. Por exemplo, o código abaixo é o arquivo de metadados para um pacote OTA destinado ao dispositivo tardis.

post-build=google/tardis/tardis:11/RP1A.200521.001/6516341:userdebug/dev-keys
post-build-incremental=6516341
post-sdk-level=30
post-security-patch-level=2020-07-05
post-timestamp=1590026334
pre-build=google/tardis/tardis:11/RP1A.200519.002.A1/6515794:userdebug/dev-keys
pre-build-incremental=6515794
pre-device=tardis

Os valores pre-device, pre-build-incremental e pre-build definem o estado que um dispositivo precisa ter antes que o pacote OTA possa ser instalado. Os valores post-build-incremental e post-build definem o estado que um dispositivo deve ter após a instalação do pacote OTA. Os valores dos campos pre- e post- são derivados das propriedades de build correspondentes abaixo.

  • O valor pre-device é derivado da propriedade de build ro.product.device.
  • Os valores pre-build-incremental e post-build-incremental são derivados da propriedade de build ro.build.version.incremental.
  • Os valores pre-build e post-build são derivados da propriedade de build ro.build.fingerprint.

Em dispositivos com o Android 11 ou versões mais recentes, é possível usar a flag --boot_variable_file em ferramentas OTA para especificar um caminho para um arquivo que contém os valores das variáveis de execução usadas na criação da impressão digital dinâmica do dispositivo. Em seguida, os dados são usados para atualizar os metadados OTA e incluir o nome do dispositivo e a impressão digital nas condições pre- e post- (usando o caractere de barra vertical | como delimitador). A flag --boot_variable_file tem a sintaxe e a descrição a seguir.

  • Sintaxe: --boot_variable_file <path>
  • Descrição: especifica um caminho para um arquivo que contém os valores possíveis das propriedades ro.boot.*. Usado para calcular os possíveis impressões digitais de execução quando algumas propriedades ro.product.* são substituídas pela instrução de importação. O arquivo espera uma propriedade por linha, em que cada linha tem o seguinte formato: prop_name=value1,value2.

Por exemplo, quando a propriedade é ro.boot.product.hardware.sku=std,pro, os metadados OTA para dispositivos tardis e tardispro são mostrados abaixo.

post-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-device=tardis|tardispro

Para oferecer suporte a essa funcionalidade em dispositivos com o Android 10, consulte a implementação de referência. Essa lista de mudanças analisa condicionalmente as instruções import no arquivo build.prop, o que permite que as substituições de propriedade sejam reconhecidas e refletidas nos metadados finais de OTA.