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

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

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

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

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

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

Используйте ограниченное хранилище с FUSE

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

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

ПРЕДОХРАНИТЕЛЬ и 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.
  • Разрешения на кэширование для уменьшения количества IPC на системном сервере.
  • Оптимизация для приложений с доступом ко всем файлам для ускорения массовых операций.

Вышеупомянутые настройки могут обеспечить сопоставимую производительность устройств с 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.