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

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

Да. Маркетинговое название обновлений A/B — бесшовные обновления . Телефоны Pixel и Pixel XL, выпущенные в октябре 2016 года, поставлялись с A/B, и все Chromebook используют одну и ту же реализацию update_engine A/B. Необходимая реализация кода платформы общедоступна в 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, прошедшей внутреннее тестирование.

Размеры разделов в пикселях А/Б Не-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%. Для устройства 16GiB это будет менее 2%, а для устройства 8GiB почти 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 байт) разбивка самых больших вкладчиков в общий размер образа системы по типам файлов выглядит следующим образом:

.odex 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 «Эволюция искусства» .

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

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

Дополнительные сведения о параметрах настройки, доступных OEM-производителям, см. в разделе Настройка ART .

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

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

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

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

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

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

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

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

Нет. Пиксель не увеличивал размер образа системы (он просто делил пространство на два раздела).

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

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

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

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

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

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

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

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

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

Требуется ли для OTA A/B 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 устанавливает обновление приложения в фоновом режиме, прежде чем показывать уведомление об обновлении 5 приложений , как это делалось в течение многих лет.

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

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

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

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

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

По состоянию на 15.03.2017 у нас есть следующая информация:

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

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