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