Incremental File System

Модуль ядра Incremental File System (IncFS), представленный в Android 11, позволяет ОС Android получать APK-файлы, передаваемые через Android Debug Bridge (ADB).

Этот автономный модуль ядра создает новую виртуальную файловую систему, которая располагается поверх существующей файловой системы Android. Это дополняет изменения в фреймворке и SDK, которые позволяют разработчикам приложений и игр развертывать большие APK-файлы через ADB на устройствах с Android 11 или более поздней версии.

Изменения в ядре позволяют использовать новый формат схемы подписи APK версии 4 и поддерживают изменения в Android Package Manager, новые системные службы и изменения в ADB.

Реализация

Чтобы реализовать IncFS, производители устройств и систем на кристалле должны добавить в сборки устройств Android новый драйвер ядра.

Только для Android 11. Если драйвер ядра создан как модуль, он загружается по запросу. Если на устройстве нет приложений, установленных с помощью инкрементной установки ADB, оно не загружает драйвер ядра.

В противном случае, когда он создается как часть образа ядра, драйвер загружается всегда. Этот способ подходит для Android 12 и более новых версий, а также может использоваться в Android 11. Информацию о том, как обновить драйвер ядра до Android 12, можно найти в разделе Обновление драйвера ядра.

Драйвер ядра – это часть более крупной системы, которая позволяет устанавливать APK-файлы в потоковом режиме. Производителям оригинального оборудования и поставщикам не обязательно использовать код IncFS, предоставленный в примерах реализаций. Однако, чтобы обеспечить единообразный интерфейс на разных устройствах, необходимо убедиться, что в реализации API используется файловая система с функциями чтения файлов и чтения-записи каталогов, как описано в документации по интерфейсу пользовательского пространства для инкрементной файловой системы.

Кроме того, в реализациях должны быть параметры монтирования и специальные файлы, которые функционально соответствуют образцу реализации IncFS.

Ниже перечислены необходимые изменения.

  1. Настройте машину для разработки, чтобы создать ядро.
  2. Используйте общее ядро из ветки common-android-mainline.
    repo init -u https://android.googlesource.com/kernel/manifest -b common-android-mainline
    repo sync
  3. Убедитесь, что в ветке checkout есть следующие изменения, необходимые для IncFS:
  4. Добавьте CONFIG_INCREMENTAL_FS=y или CONFIG_INCREMENTAL_FS=m (только для Android 11) в конец файла defconfig. Чтобы посмотреть пример, нажмите на одну из ссылок ниже:
  5. Как создать ядро
  6. Встройте ядро в сборку образа устройства Android.
  7. Для целевого устройства Android добавьте в файл device.mk одну из следующих строк системных свойств, относящихся к определенному поставщику (необязательно для устройств с Android 12 и более поздних версий):
  8. Если вы используете тип CONFIG_INCREMENTAL_FS=y, добавьте в конец файла один из следующих элементов:

    • PRODUCT_PROPERTY_OVERRIDES += \
    • ro.incremental.enable=yes

    Если вы используете CONFIG_INCREMENTAL_FS=m (только для Android 11), добавьте в файл одну из следующих строк:

    • PRODUCT_PROPERTY_OVERRIDES += \
    • ro.incremental.enable=module:/vendor/lib/modules/incrementalfs.ko
  9. Примеры файлов device.mk для эмулятора Android и Pixel 4.
  10. Только для Android 11. Если вы используете CONFIG_INCREMENTAL_FS=m, добавьте правила SE Linux.
  11. Создайте файл vold.te и добавьте его в папку /system/sepolicy/vendor на устройстве со следующим содержимым:

    • vold.te

    Разрешите загрузку драйвера инкрементной файловой системы:

    • allow vold self:capability sys_module;
    • allow vold vendor_incremental_module:file r_file_perms;
    • allow vold vendor_incremental_module:system module_load;

    Добавьте следующие правила SE Linux в существующий файл file.te, который находится в папке /system/sepolicy/vendor:

    • file.te. Пример можно посмотреть в этом файле file.te.
    • Драйвер Incremental File System
    • type vendor_incremental_module, vendor_file_type, file_type;

    Добавьте следующие правила SE Linux в существующий файл file_contents, который находится в папке /system/sepolicy/vendor:

    • file_contents – пример можно посмотреть в file_contentsэтом файле.
    • # Incremental file system driver
    • /vendor/lib/modules/incrementalfs\.ko
    • u:object_r:vendor_incremental_module:s0

Обновление драйвера ядра

На устройствах, обновленных до Android 12, может быть установлена более старая версия драйвера IncFS. Для таких устройств AOSP рекомендует обновить драйвер IncFS до текущей версии (в данном случае v2) по следующим причинам:

  • Версия, выпущенная с Android 11, – это первая реализация IncFS, предназначенная только для поддержки установки через ADB.
  • В Android 12 для потоковой установки игр из Google Play используется драйвер IncFS. Чтобы обеспечить удобство для пользователей, требуются новые функции и оптимизации IncFS версии 2.
  • Версия 1 поддерживает стриминг игр, но при этом снижается производительность и увеличивается расход заряда батареи, а также ресурсов ЦП и ОЗУ по сравнению с версией 2.
  • В версии 2 улучшен UX для стриминга: добавлены плавные анимации прогресса, точные отчеты об использовании места на диске и защита от вмешательства сторонних приложений.

Чтобы обновить драйвер IncFS в ядре, примените следующие исправления для ядра 4.14 или 4.19:

Для всех остальных версий ядра перенесите один из наборов исправлений. Они влияют только на каталог fs/incfs и легко применяются к существующему коду версии 1.

Продолжайте использовать драйвер IncFS так же, как и в исходной версии Android 11, либо как встроенную часть образа ядра, либо как отдельный модуль. Не меняйте системную плату или конфигурацию свойств системы.

Новые устройства, использующие образ ядра GKI, автоматически получают последнюю версию (v2) драйвера IncFS, настроенную как часть образа ядра. Дополнительных действий не требуется.

Конфигурация загружаемых модулей была объявлена устаревшей в Android 12 и не поддерживается на новых устройствах. Это разрешено только для обновлений или для заморозки образа поставщика, если исходное ядро уже было создано как модуль.

Примеры реализации

Этот код может быть частью образа ядра или (только для Android 11) загружаемым модулем.

Загружаемый модуль (устройство Pixel 4) Эмулятор Android (как часть образа ядра)

Проверка и тестирование

Проверьте реализацию с помощью тестов Feature Unit Tests, CTS и GTS.

CTS

Войдите в аккаунт пользователя CtsIncrementalInstallHostTestCases.

GTS

atest GtsIncrementalInstallTestCases:

/gts-tests/tests/packageinstaller/incremental/src/com/google/android/packageinstaller/incremental/gts/IncrementalInstallerTest.java

Как протестировать IncFS

  1. Настройте среду разработки.
  2. Выполните задачи по внедрению, описанные в разделе "Внедрение".
  3. Выполните следующие тесты вручную:
    mmma system/incremental_delivery/incfs/tests
    atest libincfs-test
    atest IncrementalServiceTest
    atest PackageManagerShellCommandTest
    PackageManagerShellCommandIncrementalTest

Как протестировать IncFS с помощью Android SDK (ADB и apksigner)

  • Настройте среду разработки.
  • Выполните задачи по внедрению, описанные в разделе "Внедрение".
  • Установите сборку на целевое физическое устройство или эмулятор.
  • Создайте или получите существующий APK-файл.
  • Создайте ключ подписи для отладки.
  • Подпишите APK-файл с помощью формата подписи версии 4 из папки build-tools.
    ./apksigner sign --ks debug.keystore game.apk
  • Установите APK-файл на устройство из папки platform-tools.
    ./adb install game.apk
Пример установки
Рисунок 1. Пример установки.

Как найти эти тесты