Scoped storage ограничивает доступ приложений к внешнему хранилищу. В Android 11 и выше приложения, ориентированные на API 30 или выше, должны использовать scoped storage. Ранее в Android 10 приложения могли отказаться от scoped storage.
Ограничения доступа к приложению
Целью хранилища scoped является защита конфиденциальности данных приложений и пользователей. Это включает защиту информации пользователя (например, метаданных фотографий), предотвращение изменения или удаления файлов пользователя приложениями без явного разрешения и защиту конфиденциальных документов пользователя, загруженных в папку Download или другие папки.
Приложения, использующие ограниченное хранилище, могут иметь следующие уровни доступа (фактический доступ зависит от реализации).
- Доступ для чтения и записи к собственным файлам без каких-либо разрешений
- Доступ для чтения к медиафайлам других приложений с разрешением
READ_EXTERNAL_STORAGE
- Доступ на запись к медиафайлам других приложений разрешен только с прямого согласия пользователя (исключения предоставлены для Системной галереи и приложений, имеющих право на доступ ко всем файлам)
- Нет доступа на чтение или запись к внешним каталогам данных других приложений.
Используйте хранилище с областью действия с помощью FUSE
Android 11 или выше поддерживает Filesystem in Userspace (FUSE), что позволяет модулю MediaProvider проверять файловые операции в пользовательском пространстве и ограничивать доступ к файлам на основе политики, разрешая , запрещая или запрещая доступ. Приложения в хранилище с ограниченной областью действия, использующие FUSE, получают функции конфиденциальности хранилища с ограниченной областью действия и возможность доступа к файлам с использованием прямого пути к файлу (сохраняя работоспособность API файлов в приложениях).
Android 10 применяет правила хранилища scoped для доступа к файлам через MediaProvider, но не для прямого доступа к пути к файлу (например, с использованием API File и NDK) из-за усилий, необходимых для перехвата вызовов ядра. В результате приложения в хранилище scoped не могут получить доступ к файлам с использованием прямого пути к файлу. Это ограничение влияет на способность разработчиков приложений адаптироваться, поскольку для переписывания доступа API File к 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 и ошибок.