| page.title=Traditional Storage |
| @jd:body |
| <!-- |
| Copyright 2015 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. |
| --> |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| <ol id="auto-toc"> |
| </ol> |
| </div> |
| </div> |
| |
| <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="{@docRoot}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> |