Часто задаваемые вопросы

Использует ли Google A/B OTA на каких-либо устройствах?

Да. Маркетинговое название A/B-обновлений – незаметные обновления. Телефоны Pixel и Pixel XL, выпущенные в октябре 2016 г., поставлялись с системой A/B, и все Chromebook используют ту же реализацию A/B.update_engine Необходимая реализация кода платформы является общедоступной в Android 7.1 и более поздних версиях.

Почему A/B-тестирование OTA лучше?

A/B-обновления по беспроводной сети удобнее для пользователей. Данные, полученные в результате ежемесячных обновлений системы безопасности, показывают, что эта функция уже доказала свою эффективность. По состоянию на май 2017 года 95% владельцев устройств Pixel установили последнее обновление системы безопасности в течение месяца после его выхода. Для сравнения, среди пользователей Nexus этот показатель составил 87 %. Кроме того, пользователи Pixel устанавливают обновления быстрее, чем пользователи Nexus. Если при беспроводном обновлении не удается обновить блоки, устройство все равно загружается. Пока новая версия системы не будет успешно загружена, Android может вернуться к предыдущей рабочей версии.

Что такое system_other?

Приложения хранятся в файлах APK, которые представляют собой ZIP-архивы. Каждый файл APK содержит один или несколько файлов DEX с переносимым байт-кодом Dalvik. Файл ODEX (оптимизированный DEX) хранится отдельно от файла APK и может содержать машинный код, предназначенный для конкретного устройства. Если файл .odex доступен, Android может запускать приложения с помощью предварительной компиляции, не дожидаясь компиляции кода при каждом запуске приложения. Файл ODEX не является строго необходимым: Android может выполнять код DEX напрямую с помощью интерпретации или JIT-компиляции, но файл ODEX обеспечивает оптимальное сочетание скорости запуска и выполнения, если есть свободное место.

Пример. В файле installed-files.txt для Nexus 6P с Android 7.1 и общим размером образа системы 2628 МиБ (2 755 792 836 байт) разбивка по типам файлов, которые больше всего влияют на размер образа системы, выглядит следующим образом:

ODEX 1391770312 байт 50,5%
APK 846878259 байт 30,7%
.so (нативный код C/C++); 202162479 байт 7,3%
Файлы OAT и изображения ART 163892188 байт 5,9%
Шрифты 38952361 байт 1,4 %
icu locale data 27468687 байт 0,9 %

На других устройствах эти показатели похожи, поэтому на устройствах Nexus/Pixel файлы .odex занимают примерно половину системного раздела. Это означало, что мы могли продолжать использовать ext4, но записывать файлы .odex в раздел B на заводе, а затем копировать их в /data при первой загрузке. Фактическое хранилище, используемое с ext4 A/B, идентично SquashFS A/B, поскольку, если бы мы использовали SquashFS, мы бы отправили предварительно оптимизированные файлы .odex в system_a вместо system_b.

Разве при копировании файлов .odex в /data сэкономленное место в /system не теряется в /data?

Не совсем. На устройствах Pixel большая часть места, занимаемого файлами .odex, приходится на приложения, которые обычно находятся в разделе /data. Эти приложения получают обновления из Google Play, поэтому файлы APK и ODEX в образе системы не используются большую часть срока службы устройства. Такие файлы можно полностью исключить и заменить небольшими файлами ODEX, которые создаются на основе профиля, когда пользователь запускает приложение .Таким образом, приложения, которые не используются, не будут занимать место. Подробную информацию можно найти в докладе Эволюция искусства, представленном на конференции Google I/O 2016.

Сравнение затруднено по нескольким причинам:

  • Приложения, обновленные через Google Play, всегда имели файлы .odex в каталоге /data после первого обновления.
  • Приложениям, которые пользователь не запускает, файл .odex не нужен.
  • При компиляции на основе профиля создаются файлы ODEX меньшего размера, чем при предварительной компиляции, поскольку оптимизируется только критически важный для производительности код.

Подробную информацию о доступных OEM-производителям вариантах настройки можно найти в статье Настройка ART.

Разве в папке /data нет двух копий файлов .odex?

Все немного сложнее. После записи нового образа системы новая версия dex2oat запускается для новых DEX-файлов, чтобы сгенерировать новые ODEX-файлы. Это происходит, пока старая система ещё работает, поэтому старые и новые файлы ODEX находятся в /data одновременно.

Код в OtaDexoptService (frameworks/base/+/android17-release/services/core/java/com/android/server/pm/OtaDexoptService.java) вызывает getAvailableSpace перед оптимизацией каждого пакета, чтобы избежать переполнения /data. Обратите внимание, что доступный объем памяти рассчитывается с запасом. Это объем, оставшийся до достижения обычного системного порога (измеряется в процентах и байтах). Поэтому если раздел /data заполнен, то у каждого файла ODEX не будет двух копий. В том же коде есть BULK_DELETE_THRESHOLD .Если на устройстве остается мало свободного места, удаляются ODEX-файлы, принадлежащие неиспользуемым приложениям. Это ещё один случай, когда не создаются две копии каждого файла .odex.

В худшем случае, когда раздел /data полностью заполнен, обновление откладывается до тех пор, пока устройство не будет перезагружено в новой системе и ему больше не будут нужны ODEX-файлы старой системы. Этим занимается менеджер пакетов (frameworks/base/+/android17-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215). После успешной загрузки новой системы installd (frameworks/native/+/android17-release/cmds/installd/dexopt.cpp#2422) может удалить файлы .odex, которые использовались старой системой, вернув устройство в стабильное состояние, в котором есть только одна копия.

Таким образом, хотя в разделе /data могут содержаться две копии всех файлов ODEX, это временное явление, которое происходит, только если в разделе /data достаточно свободного места. Кроме того, во время обновления создается только одна копия. Кроме того, в рамках общих функций надежности ART никогда не будет заполнять /data файлами .odex (поскольку это было бы проблемой и в системе без разделов A/B).

Не приводит ли запись и копирование данных к износу флеш-памяти?

Перезаписывается только небольшая часть флеш-памяти: полное обновление системы Pixel занимает около 2,3 ГБ. (Приложения также перекомпилируются, но это происходит и в системах без разделов A/B.) Обычно при полной OTA-обновлении на основе блоков записывается примерно одинаковый объем данных, поэтому износ флеш-памяти должен быть похожим.

Увеличивает ли прошивка двух системных разделов время заводской прошивки?

Нет. Размер образа системы на устройствах Pixel не увеличился, а просто был разделен между двумя разделами.

Если оставить файлы .odex на разделе B, будет ли перезагрузка после сброса настроек к заводским выполняться медленнее?

Да. Если вы использовали устройство, выполнили обновление по воздуху и сброс до заводских настроек, первая перезагрузка будет выполняться дольше, чем обычно (1 мин. 40 с вместо 40 с на Pixel XL), поскольку файлы .odex будут удалены из раздела B после первого обновления по воздуху и не смогут быть скопированы в раздел /data. Такова цена.

Сброс до заводских настроек выполняется реже, чем обычная загрузка, поэтому время, затраченное на него, менее важно. Это не влияет на пользователей и специалистов по проверке, которые получают устройство с завода, поскольку в этом случае раздел B доступен. Благодаря JIT-компилятору нам не нужно перекомпилировать все, поэтому все не так плохо, как вы могли подумать. Также можно указать, что приложению требуется предварительная компиляция, с помощью тега coreApp="true" в манифесте (frameworks/base/+/android17-release/packages/SystemUI/AndroidManifest.xml#23). В настоящее время это используется в system_server, поскольку JIT запрещена по соображениям безопасности.

Если хранить файлы ODEX в каталоге /data, а не /system, не замедлит ли это перезагрузку после беспроводного обновления?

Нет. Как описано выше, новый dex2oat запускается, пока ещё работает старый образ системы, чтобы создать файлы, которые понадобятся новой системе. Пока это не будет сделано, обновление не будет считаться доступным.

Можно ли (нужно ли) поставлять устройство A/B с 32 ГБ памяти? 16 ГиБ? 8 ГиБ?

32 ГиБ хорошо работает на Pixel, а 320 МиБ из 16 ГиБ означает сокращение на 2%. Аналогично, 320 МиБ из 8 ГиБ – это сокращение на 4%. Очевидно, что на устройствах с 4 ГБ памяти не рекомендуется использовать схему A/B, поскольку 320 МБ составляют почти 10% от общего доступного пространства.

Требуется ли для AVB2.0 обновление OTA с использованием разделов A/B?

Нет. Для подтвержденной загрузки Android всегда требовались обновления на основе блоков, но не обязательно обновления A/B.

Требуется ли AVB2.0 для OTA-обновлений A/B?

Нет.

Нарушают ли OTA-обновления A/B защиту от отката AVB2.0?

Нет. Путаница возникает из-за того, что если система A/B не может загрузить новый образ системы, она автоматически возвращается к предыдущему образу системы (после нескольких попыток, определяемых загрузчиком). Однако важно помнить, что в контексте A/B "предыдущая" версия на самом деле является "текущей" системной версией. Как только устройство успешно загрузит новый образ, защита от отката начнет действовать и вы не сможете вернуться к предыдущей версии. Но пока вы не загрузите новое изображение, защита от отката не будет считать его текущим системным образом.

Если устанавливать обновление во время работы системы, это не будет медленно?

При обновлении без A/B-разделов цель состоит в том, чтобы установить обновление как можно быстрее, поскольку пользователь ждет и не может использовать свое устройство, пока применяется обновление. При A/B-обновлениях все наоборот: поскольку пользователь продолжает работать с устройством, цель состоит в том, чтобы как можно меньше влиять на его работу, поэтому обновление намеренно выполняется медленно. Кроме того, Android пытается выбрать время, когда пользователи не используют свои устройства. Это делается с помощью логики в клиенте обновлений системы Java (для Google это GmsCore, основной пакет, предоставляемый GMS). Платформа поддерживает приостановку и возобновление обновления, и клиент может использовать эту функцию, чтобы приостановить обновление, если пользователь начинает использовать устройство, и возобновить его, когда устройство снова будет бездействовать.

Процесс обновления по беспроводной сети состоит из двух этапов, которые четко обозначены в интерфейсе как Шаг 1 из 2 и Шаг 2 из 2 под индикатором выполнения. Шаг 1 соответствует записи блоков данных, а шаг 2 – предварительной компиляции DEX-файлов. Эти два этапа сильно различаются по степени влияния на производительность. Первый этап – простой ввод-вывод. Это требует мало ресурсов (ОЗУ, ЦП, ввод-вывод), поскольку просто медленно копирует блоки.

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

Это похоже на то, как Google Play устанавливает обновления приложений в фоновом режиме, а затем показывает уведомление Обновлено приложений: 5.

Что если пользователь ждет обновления?

Текущая реализация в GmsCore не различает фоновые обновления и обновления, инициированные пользователем, но в будущем это может измениться. Если пользователь явно запросил установку обновления или смотрит на экран с информацией о ходе обновления, мы будем отдавать приоритет этой задаче, поскольку предполагаем, что он активно ждет ее завершения.

Что произойдет, если не удастся применить обновление?

Если при обновлении без использования разделов A/B возникала ошибка, устройство обычно становилось непригодным для использования. Исключение составляли случаи, когда сбой происходил до запуска приложения (например, из-за того, что не удалось проверить пакет). При использовании A/B-обновлений сбой при установке обновления не влияет на работу системы. Повторите попытку позже.