100 lines
5.4 KiB
HTML
100 lines
5.4 KiB
HTML
<html devsite>
|
|
<head>
|
|
<title>Traditional Storage</title>
|
|
<meta name="project_path" value="/_project.yaml" />
|
|
<meta name="book_path" value="/_book.yaml" />
|
|
</head>
|
|
<body>
|
|
<!--
|
|
Copyright 2017 The Android Open Source Project
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
-->
|
|
|
|
|
|
|
|
<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_extstor.png" alt="Android external storage HAL icon"/>
|
|
|
|
<p>Android supports devices with traditional storage, which is defined to be a
|
|
case-insensitive filesystem with immutable POSIX permission classes and modes.
|
|
The notion of traditional storage encompasses emulated and portable storage.
|
|
Portable storage is defined as any external storage that is not <a href="/devices/storage/adoptable.html">
|
|
adopted</a> by the
|
|
system and therefore not formatted and encrypted or tied to a specific device.
|
|
Because traditional external storage offers minimal protection for stored data,
|
|
system code should not store sensitive data on external storage. Specifically,
|
|
configuration and log files should only be stored on internal storage where
|
|
they can be effectively protected.</p>
|
|
|
|
<h2 id="multi-user-external-storage">Multi-user external storage</h2>
|
|
<p>Starting in Android 4.2, devices can support multiple users, and external
|
|
storage must meet the following constraints:</p>
|
|
<ul>
|
|
<li>Each user must have their own isolated primary external storage, and
|
|
must not have access to the primary external storage of other users.</li>
|
|
<li>The <code>/sdcard</code> path must resolve to the correct user-specific
|
|
primary external storage based on the user a process is running as.</li>
|
|
<li>Storage for large OBB files in the <code>Android/obb</code> directory
|
|
may be shared between multiple users as an optimization.</li>
|
|
<li>Secondary external storage must not be writable by apps, except in
|
|
package-specific directories as allowed by synthesized permissions.</li>
|
|
</ul>
|
|
<p>The default platform implementation of this feature leverages Linux kernel
|
|
namespaces to create isolated mount tables for each Zygote-forked process,
|
|
and then uses bind mounts to offer the correct user-specific primary external
|
|
storage into that private namespace.</p>
|
|
<p>At boot, the system mounts a single emulated external storage FUSE daemon
|
|
at <code>EMULATED_STORAGE_SOURCE</code>, which is hidden from apps. After
|
|
the Zygote forks, it bind mounts the appropriate user-specific subdirectory
|
|
from under the FUSE daemon to <code>EMULATED_STORAGE_TARGET</code> so that
|
|
external storage paths resolve correctly for the app. Because an app lacks
|
|
accessible mount points for other users' storage, they can only access
|
|
storage for the user it was started as.</p>
|
|
<p>This implementation also uses the shared subtree kernel feature to
|
|
propagate mount events from the default root namespace into app namespaces,
|
|
which ensures that features like ASEC containers and OBB mounting continue
|
|
working correctly. It does this by mounting the rootfs as shared, and then
|
|
remounting it as slave after each Zygote namespace is created.</p>
|
|
|
|
<h2 id="multiple-external-storage-devices">Multiple external storage devices</h2>
|
|
<p>Starting in Android 4.4, multiple external storage devices are surfaced
|
|
to developers through <code>Context.getExternalFilesDirs()</code>,
|
|
<code>Context.getExternalCacheDirs()</code>, and
|
|
<code>Context.getObbDirs()</code>.</p>
|
|
</p>External storage devices surfaced through these APIs must be a
|
|
semi-permanent part of the device (such as an SD card slot in a battery
|
|
compartment). Developers expect data stored in these locations to be
|
|
available over long periods of time. For this reason, transient storage
|
|
devices (such as USB mass storage drives) should not be surfaced through
|
|
these APIs.</p>
|
|
<p>The <code>WRITE_EXTERNAL_STORAGE</code> permission must only grant write
|
|
access to the primary external storage on a device. Apps must not be
|
|
allowed to write to secondary external storage devices, except in their
|
|
package-specific directories as allowed by synthesized
|
|
permissions. Restricting writes in this way ensures the system can clean
|
|
up files when applications are uninstalled.</p>
|
|
|
|
<h2 id=support_usb_media>USB media support</h2>
|
|
|
|
<p>Android 6.0 supports portable storage devices which are only connected to the
|
|
device for a short period of time, like USB flash drives. When a user inserts a
|
|
new portable device, the platform shows a notification to let them copy or
|
|
manage the contents of that device.</p>
|
|
|
|
<p>In Android 6.0, any device that is not adopted is considered portable. Because
|
|
portable storage is connected for only a short time, the platform avoids heavy
|
|
operations such as media scanning. Third-party apps must go through the <a href="https://developer.android.com/guide/topics/providers/document-provider.html">Storage Access Framework</a> to interact with files on portable storage; direct access is explicitly
|
|
blocked for privacy and security reasons.</p>
|
|
|
|
</body>
|
|
</html>
|