Ограниченное хранилище ограничивает доступ приложений к внешнему хранилищу. В 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.