Scoped storage limits app access to external storage. In Android 11 or higher, apps targeting API 30 or higher must use scoped storage. Previously in Android 10, apps could opt out of scoped storage.
App access restrictions
The goal of scoped storage is to protect the privacy of app and user data. This includes protecting user information (such as photo metadata), preventing apps from modifying or deleting user files without explicit permission, and protecting sensitive user documents downloaded to Download or other folders.
Apps using scoped storage can have the following levels of access (actual access is implementation specific).
- Read and write access to their own files with no permissions
- Read access to other apps' media files with
- Write access to other apps' media files is allowed only with direct user consent (exceptions granted to System Gallery and apps that are eligible for All Files access)
- No read or write access to other apps' external app data directories
Using scoped storage with FUSE
Android 11 or higher supports Filesystem in Userspace (FUSE), which enables the MediaProvider module to examine file operations in user space and to gate access to files based on the policy to allow, deny, or redact access. Apps in scoped storage that use FUSE get the privacy features of scoped storage and the ability to access files using a direct file path (keeping File APIs working in apps).
Android 10 enforced scoped storage rules on file accesses by MediaProvider, but not for direct file path access (for example, using File API and NDK APIs) due to the effort required in intercepting kernel calls. As a result, apps in scoped storage couldn't access files using a direct file path. This restriction impacted app developers' ability to adapt as it required substantial code changes to rewrite File API access to the MediaProvider API.
FUSE and SDCardFS
Android 11 support for FUSE is unrelated to the deprecation of SDCardFS, but does provide an alternative to Media Store for devices that previously used SDCardFS. Devices:
- Launching with Android 11 or higher using kernel 5.4 or higher can't use SDCardFS.
- Upgrading to Android 11 or higher can host FUSE on top of SDCardFS to intercept the file operations and meet privacy goals.
FUSE performance tuning
Android previously supported FUSE in Android 7 or lower, in which external
storage was mounted as FUSE. Due to performance and deadlock issues with that
FUSE implementation, Android 8 introduced SDCardFS. Android
11 reintroduces support for FUSE using an improved,
better-tested implementation of
libfuse that can be tuned to resolve the
performance issues in Android 7 or lower.
FUSE tuning includes the following tweaks:
- Bypassing FUSE for the
Android/obbdirectories to improve performance for game apps that rely on these directories.
- Optimizations (such as tuning the read-ahead and dirty ratios of the FUSE file system) to keep reads performant and media playback smooth.
- Using the FUSE write-back cache.
- Caching permissions to reduce IPCs to the system server.
- Optimizations for apps with All Files access to make bulk operations faster.
The above tuning tweaks can produce comparable performance between FUSE and non-FUSE devices. For example, testing a tuned Pixel 2 using FUSE and a Pixel 2 using Media Store found comparable sequential read performance (for example, video playback) between file path access and Media Store. However, sequential writes were slightly worse with FUSE, and random reads and writes could be up to twice as slow.
Performance measurements can change from device to device and between specific use cases. Because MediaProvider APIs give the most consistent performance, app developers that are concerned about performance should use MediaProvider APIs for their apps.
Mitigating FUSE performance impact
FUSE performance impact is limited to heavy users of files stored on external
shared storage only. External private storage (which includes
android/obb directories) is bypassed by FUSE, while internal storage (such
/data/data, where many apps store data to keep it encrypted and secure)
isn't FUSE mounted.
Apps that are light users of shared external storage often interact with a limited set of files (typically fewer than 100 files). These apps benefit from existing optimizations of common read and write operations and shouldn't see any FUSE-related performance impact in Android 11.
Apps that are heavy users of shared external storage typically perform bulk file operations, such as listing or removing a directory with a 1000 files, or creating or deleting a directory with a million files on the file system. Bulk file operations might be impacted by FUSE on Android 11, but if such apps are eligible for the
MANAGE_EXTERNAL_STORAGEpermission, they benefit from the performance optimizations included in the October 2020 update.
To avoid FUSE performance overhead, apps can store data in external private
storage or use bulk APIs in the
ContentProvider class to bypass FUSE and get a
performance-optimized path. In addition, the October 2020 update to the
MediaProvider system component includes performance optimizations for file
managers and similar apps (such as backup/restore, antivirus) that hold the
Privacy over performance
On devices that have been tuned for FUSE, most critical user journeys are equally performant between Android 10 and Android 11. However, when testing benchmarks over a set of file operations, Android 11 might perform worse than Android 10. For file access patterns that perform worse in Android 11 (for example, random reads or writes), we recommend using MediaProvider APIs to give apps a non-FUSE access mode, which is the best and consistently performant option.
MediaProvider and FUSE updates
The MediaProvider system component behavior differs between Android releases.
In Android 10 and lower, SDCardFS was the file system and MediaProvider provided an interface to collections of files (for example, images, videos, music files, etc.). When an app created a file using File API, it could ask MediaProvider to scan the file and record it in the database.
In Android 11 or higher, SDCardFS is deprecated and MediaProvider becomes the file system handler (for FUSE) for external storage, making the file system on external storage and the MediaProvider database consistent. As the userspace handler for the FUSE file system, MediaProvider can intercept kernel calls and ensure the file operations are privacy safe.
In Android 11 and higher, MediaProvider is also a modular system component (a Mainline module) that can be updated outside of Android releases. This means that performance, privacy, or security issues found in MediaProvider can be fixed and delivered over the air from the Google Play Store or other partner-provided mechanisms. Anything in the scope of what's expected from a FUSE handler is also updatable, enabling updates to fix FUSE performance regressions and bugs.