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

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

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

Почему A/B OTA лучше?

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

Как A/B повлияло на размеры разделов Pixel 2016 года?

В следующей таблице приведены сведения о поставляемой конфигурации A/B в сравнении с конфигурацией без A/B, протестированной внутри компании:

Размеры разделов пикселей А/Б Не-А/Б
загрузчик 50*2 50
Ботинок 32*2 32
Восстановление 0 32
Кэш 0 100
Радио 70*2 70
Продавец 300*2 300
Система 2048*2 4096
Общий 5000 4680

Для обновлений A/B требуется увеличение флэш-памяти всего на 320 МБ, при этом 32 МБ экономятся за счет удаления раздела восстановления и еще 100 МБ сохраняются за счет удаления раздела кэша. Это уравновешивает стоимость разделов B для загрузчика, загрузочного раздела и радиораздела. Размер вендорного раздела увеличился вдвое (подавляющее большинство размеров увеличилось). Изображение системы Pixel A/B вдвое меньше исходного изображения системы, отличной от A/B.

Для вариантов Pixel A/B и не-A/B, протестированных внутри компании (поставлялись только A/B), используемое пространство отличалось всего на 320 МБ. На устройстве 32 ГБ это чуть менее 1%. Для устройства 16 ГБ это будет менее 2%, а для устройства 8 ГБ — почти 4% (при условии, что все три устройства имеют одинаковый образ системы).

Почему вы не использовали SquashFS?

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

В частности, SquashFS обеспечил около 50% экономии размера системного раздела, но подавляющее большинство файлов, которые хорошо сжимались, представляли собой предварительно скомпилированные файлы .odex. Эти файлы имели очень высокую степень сжатия (около 80%), но степень сжатия остальной части системного раздела была намного ниже. Кроме того, SquashFS в Android 7.0 вызывал следующие проблемы с производительностью:

  • У Pixel очень быстрая флэш-память по сравнению с более ранними устройствами, но не так много свободных циклов ЦП, поэтому чтение меньшего количества байтов из флэш-памяти, но требующее большего количества ЦП для ввода-вывода, было потенциальным узким местом.
  • Изменения ввода-вывода, которые хорошо работают в искусственном тесте, запущенном в незагруженной системе, иногда не работают хорошо в реальных сценариях использования под реальной нагрузкой (например, криптография на Nexus 6).
  • Бенчмаркинг в некоторых местах показал 85%-ный регресс.

По мере развития SquashFS и добавления функций для снижения нагрузки на процессор (например, белый список общедоступных файлов, которые не следует сжимать), мы продолжим ее оценку и предложим рекомендации производителям устройств.

Как ты без SquashFS уменьшил размер системного раздела вдвое?

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

Пример. Для файла install-files.txt с Nexus 6P под управлением Android 7.1 с общим размером образа системы 2628 МБ (2755792836 байт) распределение крупнейших вкладчиков в общий размер образа системы по типам файлов выглядит следующим образом:

.одекс 1391770312 байт 50,5%
.apk 846878259 байт 30,7%
.so (собственный код C/C++) 202162479 байт 7,3%
Файлы .oat/изображения .art 163892188 байт 5,9%
Шрифты 38952361 байт 1,4%
данные локали icu 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 «Эволюция искусства» .

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

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

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

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

Это немного сложнее... После записи нового образа системы новая версия dex2oat запускается с новыми файлами .dex для создания новых файлов .odex. Это происходит, когда старая система еще работает, поэтому старый и новый файлы .odex одновременно находятся в каталоге /data .

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

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

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

Не увеличивает ли вся эта запись/копирование износ флэш-памяти?

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

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

Нет. Pixel не увеличил размер системного образа (он просто разделил пространство на два раздела).

Разве сохранение файлов .odex на B не приводит к замедлению перезагрузки после сброса заводских данных?

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

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

Не приводит ли сохранение файлов .odex в /data, а не в /system к замедлению перезагрузки после OTA?

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

Можем ли (должны ли) мы отправить устройство A/B емкостью 32 ГБ? 16Гб? 8ГиБ?

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

Требуются ли для AVB2.0 OTA A/B?

Нет. Android Verified Boot всегда требует блочных обновлений, но не обязательно обновлений A/B.

Требуется ли для A/B OTA AVB2.0?

Нет.

Нарушают ли OTA A/B защиту от отката AVB2.0?

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

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

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

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

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

Этот процесс аналогичен тому, когда Google Play устанавливает обновление приложения в фоновом режиме перед отображением уведомления об обновлении пяти приложений , как это делалось в течение многих лет.

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

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

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

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

Какие системы на кристалле (SoC) поддерживают A/B?

По состоянию на 15 марта 2017 г. у нас имеется следующая информация:

Android 7.x и более ранние версии Android 8.x и более поздние версии
Квалкомм В зависимости от запросов OEM Все чипсеты получат поддержку
Медиатек В зависимости от запросов OEM Все чипсеты получат поддержку

Подробную информацию о расписании можно получить у своих контактов SoC. Для систем-на-кристалле, не перечисленных выше, обратитесь непосредственно к вашей системе-на-кристалле.