Хранилище с заданной областью

Ограниченное хранилище ограничивает доступ приложений к внешнему хранилищу. В Android 11 и более поздних версиях приложения, ориентированные на API 30 или выше, должны использовать ограниченное хранилище. Ранее в Android 10 приложения могли отказаться от использования ограниченного хранилища.

Ограничения доступа к приложению

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

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

  • Доступ для чтения и записи к собственным файлам без каких-либо разрешений
  • Доступ для чтения к медиафайлам других приложений с разрешением READ_EXTERNAL_STORAGE
  • Доступ для записи к медиафайлам других приложений разрешен только с прямого согласия пользователя (исключения предоставлены системной галерее и приложениям, имеющим право на доступ ко всем файлам).
  • Нет доступа на чтение или запись к внешним каталогам данных других приложений.

Используйте хранилище с областью действия с помощью FUSE

Android 11 и более поздние версии поддерживают файловую систему в пользовательском пространстве (FUSE), которая позволяет модулю MediaProvider проверять файловые операции в пользовательском пространстве и ограничивать доступ к файлам на основе политики, разрешая , запрещая или блокируя доступ. Приложения в хранилище с ограниченной областью действия, использующие FUSE, получают функции конфиденциальности хранилища с ограниченной областью действия и возможность доступа к файлам по прямому пути к файлу (сохраняя работоспособность File API в приложениях).

В Android 10 правила хранилища с ограниченной областью применения были применены к файлам, доступным через MediaProvider, но не к прямому доступу к файлу (например, через File API и API NDK) из-за необходимости перехвата вызовов ядра. В результате приложения, работающие в хранилище с ограниченной областью применения, не могли получать доступ к файлам по прямому пути. Это ограничение повлияло на способность разработчиков приложений адаптироваться, поскольку потребовало существенных изменений кода для переписывания доступа через File API к API MediaProvider.

FUSE и SDCardFS

Поддержка FUSE в Android 11 не связана с прекращением поддержки SDCardFS , но предоставляет альтернативу Media Store для устройств, ранее использовавших SDCardFS. Устройства:

  • Запуск с Android 11 или выше с ядром 5.4 или выше не может использовать SDCardFS.
  • Обновление до Android 11 или более поздней версии позволит разместить FUSE поверх SDCardFS для перехвата файловых операций и обеспечения конфиденциальности.

Настройка производительности FUSE

Ранее Android поддерживал FUSE в Android 7 и более ранних версиях, где внешний накопитель монтировался как FUSE. Из-за проблем с производительностью и взаимоблокировками в этой реализации FUSE, в Android 8 была введена SDCardFS. В Android 11 поддержка FUSE возобновлена ​​с использованием улучшенной и более протестированной реализации libfuse , которую можно настроить для решения проблем с производительностью в Android 7 и более ранних версиях.

Настройка FUSE включает в себя следующие изменения:

  • Обход FUSE для каталогов Android/data и Android/obb для повышения производительности игровых приложений, использующих эти каталоги.
  • Оптимизации (такие как настройка коэффициентов опережающего чтения и «грязных» данных файловой системы FUSE) для поддержания производительности чтения и плавного воспроизведения мультимедиа.
  • Использование кэша обратной записи FUSE.
  • Кэширование разрешений для уменьшения количества межпроцессных взаимодействий с системным сервером.
  • Оптимизация приложений с доступом ко всем файлам для ускорения массовых операций.

Вышеуказанные настройки позволяют добиться сопоставимой производительности устройств с FUSE и без FUSE. Например, тестирование настроенного Pixel 2 с FUSE и Pixel 2 с Media Store показало сопоставимую производительность последовательного чтения (например, воспроизведения видео) при доступе к файлам и Media Store. Однако последовательная запись была немного хуже при использовании FUSE, а случайное чтение и запись могли быть до двух раз медленнее.

Показатели производительности могут различаться в зависимости от устройства и конкретных вариантов использования. Поскольку API MediaProvider обеспечивают наиболее стабильную производительность, разработчикам приложений, которым важна производительность, следует использовать API MediaProvider в своих приложениях.

Снизить влияние на производительность FUSE

Влияние FUSE на производительность проявляется только при активном использовании файлов, хранящихся во внешнем общем хранилище. Внешнее частное хранилище (включая каталоги android/data и android/obb ) обходит FUSE, в то время как внутреннее хранилище (например, /data/data , где многие приложения хранят данные в зашифрованном виде и с целью их защиты) не монтируется FUSE.

  • Приложения, которые редко используют общее внешнее хранилище, часто взаимодействуют с ограниченным набором файлов (обычно менее 100). Эти приложения используют существующие оптимизации распространённых операций чтения и записи и не должны испытывать никакого влияния на производительность, связанного с FUSE, в Android 11.

  • Приложения, активно использующие общее внешнее хранилище, обычно выполняют массовые файловые операции, такие как просмотр или удаление каталога с 1000 файлов или создание или удаление каталога с миллионом файлов в файловой системе. FUSE может влиять на массовые файловые операции в Android 11, но если таким приложениям доступно разрешение MANAGE_EXTERNAL_STORAGE , они выиграют от оптимизации производительности, включенной в обновление за октябрь 2020 года.

Чтобы избежать снижения производительности FUSE, приложения могут хранить данные во внешнем частном хранилище или использовать API для пакетной обработки в классе ContentProvider , чтобы обойти FUSE и получить оптимизированный по производительности путь. Кроме того, обновление системного компонента MediaProvider от октября 2020 года включает оптимизацию производительности для файловых менеджеров и аналогичных приложений (таких как резервное копирование/восстановление, антивирусы), имеющих разрешение MANAGE_EXTERNAL_STORAGE .

Конфиденциальность важнее производительности

На устройствах, настроенных для FUSE, большинство критически важных пользовательских действий выполняются одинаково эффективно как на Android 10, так и на Android 11. Однако при тестировании набора файловых операций производительность Android 11 может быть ниже, чем у Android 10. Для шаблонов доступа к файлам, которые работают хуже в Android 11 (например, случайное чтение или запись), мы рекомендуем использовать API MediaProvider, чтобы предоставить приложениям режим доступа без FUSE, что является наилучшим и стабильно производительным вариантом.

Обновления MediaProvider и FUSE

Поведение компонента системы MediaProvider различается в разных версиях Android.

  • В Android 10 и более ранних версиях файловой системой была SDCardFS, а MediaProvider предоставлял интерфейс для работы с коллекциями файлов (например, изображениями, видео, музыкальными файлами и т. д.). Когда приложение создавало файл с помощью File API, оно могло запросить у MediaProvider сканирование файла и запись его в базу данных.

  • В Android 11 и более поздних версиях SDCardFS устарела, и MediaProvider становится обработчиком файловой системы (для FUSE) для внешних накопителей, обеспечивая согласованность файловой системы на внешнем накопителе и базы данных MediaProvider. Как обработчик пользовательского пространства для файловой системы FUSE, MediaProvider может перехватывать вызовы ядра и обеспечивать конфиденциальность файловых операций.

В Android 11 и более поздних версиях MediaProvider также является модульным системным компонентом (модулем Mainline), который можно обновлять вне релизов Android. Это означает, что проблемы производительности, конфиденциальности или безопасности, обнаруженные в MediaProvider, могут быть исправлены и предоставлены «по воздуху» через Google Play Store или другими партнёрскими механизмами. Всё, что ожидается от обработчика FUSE, также может быть обновлено, что позволяет устанавливать обновления для исправления ошибок и снижения производительности FUSE.