Reduzir o tamanho da OTA

Esta página descreve as mudanças adicionadas ao AOSP para reduzir mudanças desnecessárias de arquivos entre builds. Os implementadores de dispositivos que mantêm os próprios sistemas de compilação podem usar essas informações como um guia para reduzir o tamanho das atualizações over the air (OTA).

Às vezes, as atualizações OTA do Android contêm arquivos alterados que não correspondem às mudanças no código. Na verdade, eles são artefatos do sistema de build. Isso ocorre quando o mesmo código, criado em diferentes vezes, de diferentes diretórios ou máquinas, produz um grande número de . Esses arquivos em excesso aumentam o tamanho de um patch OTA e dificultam a determinação qual código mudou.

Para tornar o conteúdo de uma OTA mais transparente, o AOSP inclui mudanças do sistema de build projetadas para reduzir o tamanho dos patches OTA. Mudanças desnecessárias nos arquivos entre builds foram eliminados, e apenas arquivos relacionados a patches são contidos nas atualizações OTA. O AOSP também inclui uma ferramenta de comparação de builds, que filtra recursos comuns relacionados ao build do arquivo de build para oferecer uma comparação mais limpa do arquivo de compilação e uma Ferramenta de mapeamento de blocos, que ajuda a manter a alocação de blocos consistentes.

Um sistema de build pode criar patches desnecessariamente grandes de várias maneiras. Para mitigar isso, em No Android 8.0 e versões mais recentes, novos recursos foram implementados para reduzir o tamanho do patch para cada diferença de arquivos. As melhorias que reduziram os tamanhos dos pacotes de atualização OTA incluem o seguinte:

  • O uso do ZSTD, um algoritmo de compactação sem perdas de finalidade genérica para imagens em atualizações de dispositivo não A/B. O ZSTD pode ser personalizado para taxas de compactação aumentando o nível de compactação. O nível de compressão é definido durante o OTA hora de geração e pode ser definido passando a sinalização --vabc_compression_param=zstd,$COMPRESSION_LEVEL
  • Aumentar o tamanho da janela de compactação usada durante o OTA. O tamanho máximo da janela de compactação podem ser definidas personalizando o parâmetro de build no arquivo .mk de um dispositivo. Isso é definida como PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
  • Uso da recompressão do Puffin, uma ferramenta determinista de aplicação de patches para redução que lida com as funções de compactação e diferença para a geração de atualizações OTA A/B.
  • Alterações no uso da ferramenta de geração de delta, por exemplo, a forma como os bsdiff é usada para compactar patches. No Android 9 e versões mais recentes, a bsdiff seleciona o algoritmo de compactação que fornece os melhores resultados de compactação para um patch.
  • Melhorias no update_engine resultou em menos memória consumida quando patches são aplicados para atualizações A/B de dispositivos.

As seções a seguir discutem vários problemas que afetam os tamanhos das atualizações OTA, as soluções delas e exemplos de implementação no AOSP.

Ordem dos arquivos

Problema: os sistemas de arquivos não garantem a ordem dos arquivos quando solicitam uma lista de arquivos em um diretório, embora normalmente seja o mesmo para o mesmo checkout. Ferramentas como ls classifica os resultados por padrão, mas a função curinga usada por comandos como find e make não ordenam. Antes de usar essas ferramentas, você deve classificar das saídas.

Solução: quando você usa ferramentas como find e make com a função de caractere curinga, classifique a saída desses comandos antes de usar para resolvê-los com rapidez. Ao usar $(wildcard) ou $(shell find) em Android.mk, classifique-os também. Algumas ferramentas, como Java, ordenam as entradas, então antes de classificar os arquivos, verifique se a ferramenta que você está usando ainda não fez isso.

Exemplos:muitas instâncias foram corrigidas no sistema de build principal usando a integrada all-*-files-under, que inclui all-cpp-files-under (porque várias definições foram espalhadas em outros makefiles). Para mais detalhes, consulte:

Diretório do build

Problema: alterar o diretório no qual os itens são criados pode causar binários sejam diferentes. A maioria dos caminhos no build do Android são relativos. __FILE__ em C/C++ não é um problema. No entanto, os símbolos de depuração codificam por padrão, e o .note.gnu.build-id é gerado a partir do hash binário pré-retirado, portanto será alterado se os símbolos de depuração mudarem.

Solução:o AOSP agora faz com que os caminhos de depuração sejam relativos. Para mais detalhes, consulte o CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02.

Carimbos de data/hora

Problema:os carimbos de data/hora na saída do build resultam em mudanças desnecessárias no arquivo. Isso provavelmente vai acontecer nos seguintes locais:

  • __DATE__/__TIME__/__TIMESTAMP__ no código C ou C++.
  • Carimbos de data/hora incorporados em arquivos baseados em ZIP.

Soluções/exemplos:para remover carimbos de data/hora da saída da compilação, use as instruções fornecidas abaixo __DATE__/__TIME__/__TIMESTAMP__ em C/C++ e Carimbos de data/hora incorporados nos arquivos.

__DATE__/__TIME__/__TIMESTAMP__ em C/C++

Essas macros sempre produzem saídas diferentes para builds diferentes, portanto, não as use. Aqui algumas opções para eliminar essas macros:

.

Carimbos de data/hora incorporados em arquivos (zip, jar)

O Android 7.0 corrigiu o problema de carimbos de data/hora incorporados em arquivos ZIP adicionando -X para todos os usos do comando zip. Isso removeu o UID/GID do e o carimbo de data/hora Unix estendido do arquivo ZIP.

Uma nova ferramenta, ziptime, localizada em /platform/build/+/main/tools/ziptime/) redefine os carimbos de data/hora normais nos cabeçalhos zip. Para mais detalhes, consulte Arquivo README.

A ferramenta signapk define carimbos de data/hora para os arquivos APK que podem variar dependendo do fuso horário do servidor. Para mais detalhes, consulte o CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.

A ferramenta signapk define carimbos de data/hora para os arquivos APK que podem variar dependendo do fuso horário do servidor. Para mais detalhes, consulte o CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.

Strings de versão

Problema:as strings da versão do APK geralmente tinham o BUILD_NUMBER anexado às versões fixadas no código. Mesmo que nada mais tenha mudado em um APK, como resultado, o APK ainda seria diferente.

Solução:remova o número da versão da string da versão do APK.

Exemplos:

Ativar a computação de verdade no dispositivo

Se dm-verity estiver ativado no dispositivo, as ferramentas OTA escolherão automaticamente a configuração da verificação e ativar a computação de verdade no dispositivo. Isso permite que os blocos de verdade sejam calculados no Android. em vez de serem armazenados como bytes brutos no pacote OTA. Os blocos Verity podem usar com aproximadamente 16 MB para uma partição de 2 GB.

No entanto, computar a verdade no dispositivo pode levar muito tempo. Especificamente, o Encaminhar O código de correção de erro pode levar muito tempo. Em dispositivos Pixel, esse número tende a levar até 10 minutos. Em dispositivos mais simples, isso pode demorar mais. Se você quiser desativar a versão no dispositivo computação, mas ainda ativar dm-verity, é possível fazer isso passando --disable_fec_computation à ferramenta ota_from_target_files quando para gerar uma atualização OTA. Essa flag desativa a computação de verdade no dispositivo durante atualizações OTA. Diminui o tempo de instalação do OTA, mas aumenta o tamanho do pacote do OTA. Caso seu dispositivo não tiverem o dm-verity ativado, transmitir essa sinalização não terá efeito.

Ferramentas de build consistentes

Problema: as ferramentas que geram arquivos instalados precisam ser consistentes (um determinado entrada deve sempre produzir a mesma saída).

Soluções/exemplos:foram necessárias alterações nas seguintes ferramentas de compilação:

Usar a ferramenta de diferenças de build

Para os casos em que não é possível eliminar mudanças em arquivos relacionadas ao build, o AOSP inclui uma ferramenta de diferença de build, target_files_diff.py para usar na comparação de dois pacotes de arquivos. Essa ferramenta realiza uma diferença recursiva entre dois builds, excluindo alterações de arquivo comuns relacionadas a builds, como

  • Mudanças esperadas na saída do build (por exemplo, devido a uma mudança no número do build).
  • Mudanças devido a problemas conhecidos no sistema de build atual.

Para usar a ferramenta de diferenças de build, execute o seguinte comando:

target_files_diff.py dir1 dir2

dir1 e dir2 são diretórios de base que contêm o destino extraído de configuração para cada build.

Manter a alocação de blocos consistente

Embora o conteúdo de um determinado arquivo permaneça o mesmo entre dois builds, os blocos reais que contêm os dados podem ter mudado. Como resultado, o atualizador deve executar E/S desnecessária para mover os blocos para uma atualização OTA.

Em uma atualização OTA A/B virtual, uma E/S desnecessária pode aumentar muito o espaço de armazenamento necessário para armazenar o snapshot copy-on-write. Em uma atualização OTA não A/B, mover os blocos por uma A atualização OTA contribui para o tempo de atualização, já que há mais E/S devido a movimentos de blocos.

Para resolver esse problema, no Android 7.0, o Google estendeu a ferramenta make_ext4fs para mantendo a alocação de blocos consistente entre builds. A ferramenta make_ext4fs aceita uma sinalização -d base_fs opcional que tenta alocar arquivos para os mesmos blocos ao gerar uma imagem ext4. Você pode extrair os arquivos de mapeamento de blocos (como os arquivos de mapa base_fs) dos arquivos de destino de um build anterior ZIP. Para cada ext4, há um arquivo .map na diretório IMAGES (por exemplo, IMAGES/system.map corresponde ao system). Esses base_fs arquivos podem ser incluídos no check-in e especificado por PRODUCT_<partition>_BASE_FS_PATH, como neste exemplo:

  PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map
  PRODUCT_SYSTEM_EXT_BASE_FS_PATH := path/to/base_fs_files/base_system_ext.map
  PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map
  PRODUCT_PRODUCT_BASE_FS_PATH := path/to/base_fs_files/base_product.map
  PRODUCT_ODM_BASE_FS_PATH := path/to/base_fs_files/base_odm.map

Embora isso não ajude a reduzir o tamanho geral do pacote OTA, ele melhora a atualização OTA desempenho reduzindo a quantidade de E/S. Para atualizações A/B virtuais, ele reduz drasticamente o espaço de armazenamento necessário para aplicar o OTA.

Evitar a atualização de apps

Além de minimizar as diferenças de build, você pode reduzir o tamanho das atualizações OTA excluindo atualizações para apps que recebem atualizações nas app stores. Os APKs geralmente compõem uma parte significativa várias partições em um dispositivo. Incluindo as versões mais recentes dos aplicativos que são atualizados por aplicativo as lojas em uma atualização OTA podem ter um grande impacto nos pacotes OTA e fornecer aos usuários benefício. No momento em que os usuários recebem um pacote OTA, eles podem já ter o app atualizado ou uma versão ainda mais recente, recebida diretamente das app stores.