Уменьшение размера OTA

На этой странице описаны изменения, добавленные в AOSP, чтобы уменьшить количество ненужных изменений файлов между сборками. Разработчики устройств, которые поддерживают свои собственные системы сборки, могут использовать эту информацию в качестве руководства по уменьшению размера своих беспроводных (OTA) обновлений.

Обновления Android OTA иногда содержат измененные файлы, которые не соответствуют изменениям кода. На самом деле это системные артефакты сборки. Это может произойти, когда один и тот же код, созданный в разное время, из разных каталогов или на разных машинах, создает большое количество измененных файлов. Такие лишние файлы увеличивают размер патча OTA и затрудняют определение того, какой код изменился.

Чтобы сделать содержимое OTA более прозрачным, AOSP включает изменения системы сборки, предназначенные для уменьшения размера патчей OTA. Ненужные изменения файлов между сборками были устранены, и в обновлениях OTA содержатся только файлы, связанные с исправлениями. AOSP также включает в себя средство сравнения сборок , которое отфильтровывает общие изменения файлов, связанные со сборкой, чтобы обеспечить более четкое различие файлов сборки, и средство сопоставления блоков , помогающее поддерживать согласованное распределение блоков.

Система сборки может создавать излишне большие исправления несколькими способами. Чтобы смягчить это, в Android 8.0 и более поздних версиях были реализованы новые функции для уменьшения размера патча для каждого различия файлов. Улучшения, которые уменьшили размеры пакетов OTA-обновлений, включают следующее:

  • Использование Brotli — универсального алгоритма сжатия без потерь для полных изображений при обновлениях устройств, отличных от A/B. Brotli можно настроить для оптимизации сжатия. Для более крупных обновлений, состоящих из двух или более блоков в файловой системе (например, system.img ), производители устройств или партнеры могут добавлять свои собственные алгоритмы сжатия и могут использовать разные алгоритмы сжатия для разных блоков одного и того же обновления.
  • Использование повторного сжатия Puffin , детерминированного инструмента исправления для потоков deflate, который обрабатывает функции сжатия и сравнения для генерации обновлений A/B OTA.
  • Изменения в использовании инструмента дельта-генерации, например, в том, как библиотека bsdiff используется для сжатия исправлений. В Android 9 и более поздних версиях инструмент bsdiff выбирает алгоритм сжатия, обеспечивающий наилучшие результаты сжатия для исправления.
  • Улучшения в update_engine привели к меньшему потреблению памяти при применении исправлений для обновлений устройств A/B.
  • Улучшения разделения больших zip-файлов для блочных OTA-обновлений. Режим в imgdiff разделяет негабаритные APK-файлы на основе имен записей. Это дает меньший патч по сравнению с линейным разделением файлов и использованием инструмента bsdiff для их сжатия.

В следующих разделах обсуждаются различные проблемы, влияющие на размеры OTA-обновлений, их решения и примеры реализации в AOSP.

Порядок файлов

Проблема : файловые системы не гарантируют порядок файлов при запросе списка файлов в каталоге, хотя он обычно одинаков для одной и той же проверки. Такие инструменты, как ls , сортируют результаты по умолчанию, но функция подстановки, используемая такими командами, как find и make , не сортирует. Перед использованием этих инструментов необходимо отсортировать выходные данные.

Решение . При использовании таких инструментов, как find и make с функцией подстановочных знаков, сортируйте выходные данные этих команд перед их использованием. При использовании $(wildcard) или $(shell find) в файлах Android.mk также отсортируйте их. Некоторые инструменты, такие как Java, сортируют входные данные, поэтому перед сортировкой файлов убедитесь, что инструмент, который вы используете, еще не сделал этого.

Примеры: многие экземпляры были исправлены в основной системе сборки с помощью встроенного макроса all-*-files-under , который включает all-cpp-files-under (поскольку несколько определений были распространены в других make-файлах). Для получения подробной информации см. следующее:

Каталог сборки

Проблема: изменение каталога, в котором создаются вещи, может привести к тому, что двоичные файлы будут другими. Большинство путей в сборке Android являются относительными путями, поэтому __FILE__ в C/C++ не является проблемой. Однако символы отладки по умолчанию кодируют полное имя пути, а .note.gnu.build-id генерируется путем хеширования предварительно очищенного двоичного файла, поэтому он изменится, если изменятся символы отладки.

Решение: AOSP теперь делает пути отладки относительными. Подробнее см. в CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02 .

Временные метки

Проблема: временные метки в выходных данных сборки приводят к ненужным изменениям файлов. Скорее всего, это произойдет в следующих местах:

  • __DATE__/__TIME__/__TIMESTAMP__ в коде C или C++.
  • Временные метки, встроенные в zip-архивы.

Решения/примеры. Чтобы удалить метки времени из выходных данных сборки, используйте инструкции, приведенные ниже в __DATE__/__TIME__/__TIMESTAMP__ в C/C++. и Встроенные метки времени в архивах .

__DATE__/__TIME__/__TIMESTAMP__ в C/C++

Эти макросы всегда производят разные выходные данные для разных сборок, поэтому не используйте их. Вот несколько вариантов устранения этих макросов:

Встроенные метки времени в архивах (zip, jar)

Android 7.0 устранил проблему встроенных временных меток в zip-архивах, добавив -X ко всем использованиям команды zip . Это удалило UID/GID сборщика и расширенную временную метку Unix из zip-файла.

Новый инструмент ziptime (расположенный в /platform/build/+/master/tools/ziptime/ ) сбрасывает нормальные метки времени в заголовках zip. Подробности смотрите в файле README .

Инструмент signapk устанавливает метки времени для файлов APK, которые могут различаться в зависимости от часового пояса сервера. Подробнее см. в CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 .

Строки версий

Проблема: к строкам версии APK часто BUILD_NUMBER к их жестко заданным версиям. Даже если в APK больше ничего не изменилось, в результате APK все равно будет другим.

Решение: удалите номер сборки из строки версии APK.

Решение: удалите номер сборки из строки версии APK.

Примеры:

Включить вычисление достоверности на устройстве

Если на вашем устройстве включена функция dm-verity , инструменты OTA автоматически подберут вашу конфигурацию проверки подлинности и активируют вычисление проверки подлинности на устройстве. Это позволяет вычислять блоки истинности на устройствах Android вместо того, чтобы хранить их в виде необработанных байтов в вашем пакете OTA. Блоки Verity могут использовать примерно 16 МБ для раздела размером 2 ГБ.

Однако вычисление правды на устройстве может занять много времени. В частности, код прямого исправления ошибок может занять много времени. На пиксельных устройствах это обычно занимает до 10 минут. На недорогих устройствах это может занять больше времени. Если вы хотите отключить вычисление истинности на устройстве, но при этом включить dm-verity, вы можете сделать это, передав --disable_fec_computation инструменту ota_from_target_files при создании обновления OTA. Этот флаг отключает вычисление достоверности на устройстве во время обновлений OTA. Это уменьшает время установки OTA, но увеличивает размер пакета OTA. Если на вашем устройстве не включена dm-verity, передача этого флага не имеет никакого эффекта.

Согласованные инструменты сборки

Проблема: Инструменты, которые генерируют установленные файлы, должны быть согласованы (данные входные данные всегда должны давать один и тот же результат).

Решения/примеры: Требовались изменения в следующих инструментах сборки:

Использование инструмента сборки различий

Для случаев, когда невозможно исключить изменения файлов, связанные со сборкой, AOSP включает инструмент сравнения сборки target_files_diff.py , который можно использовать для сравнения двух файловых пакетов. Этот инструмент выполняет рекурсивное сравнение двух сборок, исключая общие изменения файлов, связанные со сборкой, такие как

  • Ожидаемые изменения в выводе сборки (например, из-за изменения номера сборки).
  • Изменения из-за известных проблем в текущей системе сборки.

Чтобы использовать инструмент сборки различий, выполните следующую команду:

target_files_diff.py dir1 dir2

dir1 и dir2 — это базовые каталоги, содержащие извлеченные целевые файлы для каждой сборки.

Сохранение согласованности распределения блоков

Для данного файла, хотя его содержимое остается неизменным между двумя сборками, фактические блоки, содержащие данные, могли измениться. В результате программа обновления должна выполнять ненужные операции ввода-вывода, чтобы перемещать блоки для обновления OTA.

В обновлении Virtual A/B OTA ненужные операции ввода-вывода могут значительно увеличить объем памяти, необходимый для хранения моментального снимка копирования при записи. В OTA-обновлении, отличном от A/B, перемещение блоков для OTA-обновления способствует увеличению времени обновления, поскольку из-за перемещения блоков происходит больше операций ввода-вывода.

Чтобы решить эту проблему, в Android 7.0 Google расширил инструмент make_ext4fs для обеспечения согласованности распределения блоков между сборками. Инструмент make_ext4fs принимает необязательный флаг -d base_fs , который пытается разместить файлы в одних и тех же блоках при создании образа ext4 . Вы можете извлечь файлы сопоставления блоков (например, файлы сопоставления base_fs ) из zip-файла с целевыми файлами предыдущей сборки. Для каждого раздела ext4 существует файл .map в каталоге IMAGES (например, IMAGES/system.map соответствует system разделу). Затем эти файлы base_fs можно вернуть и указать через PRODUCT_<partition>_BASE_FS_PATH , как в этом примере:

  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

Хотя это не помогает уменьшить общий размер пакета OTA, оно повышает производительность обновления OTA за счет уменьшения количества операций ввода-вывода. Для обновлений Virtual A/B это значительно сокращает объем памяти, необходимый для применения OTA.

Избегайте обновления приложений

Помимо сведения к минимуму различий в сборке, вы можете уменьшить размеры обновлений OTA, исключив обновления для приложений, которые получают обновления через магазины приложений. APK часто составляют значительную часть различных разделов на устройстве. Включение последних версий приложений, которые обновляются магазинами приложений, в OTA-обновление может иметь большое влияние на размер пакетов OTA и мало что дает пользователям. К тому времени, когда пользователи получат пакет OTA, у них уже может быть обновленное приложение или даже более новая версия, полученная непосредственно из магазинов приложений.