Android has evolved over time to support a wide variety of storage device types and features. All versions of Android support devices with traditional storage, which includes portable and emulated storage. Portable storage can be provided by physical media, like an SD card or USB, that is for temporary data transfer/ file storage. The physical media may remain with the device for an extended period of time, but is not tied to the device and may be removed. SD cards have been available as portable storage since Android 1.0; Android 6.0 added USB support. Emulated storage is provided by exposing a portion of internal storage through an emulation layer and has been available since Android 3.0.
Starting in Android 6.0, Android supports adoptable storage, which is provided by physical media, like an SD card or USB, that is encrypted and formatted to behave like internal storage. Adoptable storage can store all types of application data.
Access to external storage is protected by various Android
permissions. Starting in Android 1.0, write access is protected with the
WRITE_EXTERNAL_STORAGE permission. Starting in Android 4.1,
read access is protected with the
Starting in Android 4.4, the owner, group and modes of files on external
storage devices are now synthesized based on directory structure. This
enables apps to manage their package-specific directories on external
storage without requiring they hold the broad
WRITE_EXTERNAL_STORAGE permission. For example, the app with
com.example.foo can now freely access
Android/data/com.example.foo/ on external storage devices with
no permissions. These synthesized permissions are accomplished by wrapping
raw storage devices in a FUSE daemon.
Android 6.0 introduces a new runtime permissions model where apps request
capabilities when needed at runtime. Because the new model includes the
READ/WRITE_EXTERNAL_STORAGE permissions, the platform needs to dynamically grant storage access without
killing or restarting already-running apps. It does this by maintaining three
distinct views of all mounted storage devices:
/mnt/runtime/defaultis shown to apps with no special storage permissions, and to the root namespace where
adbdand other system components live.
/mnt/runtime/readis shown to apps with
/mnt/runtime/writeis shown to apps with
At Zygote fork time, we create a mount namespace for each running app and bind
mount the appropriate initial view into place. Later, when runtime permissions
vold jumps into the mount namespace of already-running apps and bind mounts the
upgraded view into place. Note that permission downgrades always result in the
app being killed.
setns() functionality used to implement this feature requires at least Linux 3.8, but
patches have been backported successfully to Linux 3.4. The
PermissionsHostTest CTS test can be used to verify correct kernel behavior.
In Android 6.0, third-party apps don’t have access to the
sdcard_rw GIDs. Instead, access is controlled by mounting only the appropriate runtime
view in place for that app. Cross-user interactions are blocked using the