Clay Murphy | f9d451e | 2014-10-21 18:11:12 -0700 | [diff] [blame^] | 1 | page.title=External Storage |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 2 | @jd:body |
| 3 | |
| 4 | <!-- |
Clay Murphy | f9d451e | 2014-10-21 18:11:12 -0700 | [diff] [blame^] | 5 | Copyright 2014 The Android Open Source Project |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 6 | |
| 7 | Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | you may not use this file except in compliance with the License. |
| 9 | You may obtain a copy of the License at |
| 10 | |
| 11 | http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | |
| 13 | Unless required by applicable law or agreed to in writing, software |
| 14 | distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 16 | See the License for the specific language governing permissions and |
| 17 | limitations under the License. |
| 18 | --> |
Ken Sumrall | 93c0b9c | 2013-04-16 15:43:27 -0700 | [diff] [blame] | 19 | |
Jeff Sharkey | 790c02d | 2013-10-18 13:57:33 -0700 | [diff] [blame] | 20 | |
| 21 | <p>Android supports devices with external storage, which is defined to be a |
| 22 | case-insensitive filesystem with immutable POSIX permission classes and |
| 23 | modes. External storage can be provided by physical media (such as an SD |
| 24 | card), or by exposing a portion of internal storage through an emulation |
| 25 | layer. Devices may contain multiple instances of external storage.</p> |
| 26 | |
| 27 | <p>Access to external storage is protected by various Android |
| 28 | permissions. Starting in Android 1.0, write access is protected with the |
| 29 | <code>WRITE_EXTERNAL_STORAGE</code> permission. Starting in Android 4.1, |
| 30 | read access is protected with the <code>READ_EXTERNAL_STORAGE</code> |
| 31 | permission.</p> |
| 32 | |
| 33 | <p>Starting in Android 4.4, the owner, group and modes of files on external |
| 34 | storage devices are now synthesized based on directory structure. This |
| 35 | enables apps to manage their package-specific directories on external |
| 36 | storage without requiring they hold the broad |
| 37 | <code>WRITE_EXTERNAL_STORAGE</code> permission. For example, the app with |
| 38 | package name <code>com.example.foo</code> can now freely access |
| 39 | <code>Android/data/com.example.foo/</code> on external storage devices with |
| 40 | no permissions. These synthesized permissions are accomplished by wrapping |
| 41 | raw storage devices in a FUSE daemon.</p> |
| 42 | |
| 43 | <p>Since external storage offers minimal protection for stored data, system |
| 44 | code should not store sensitive data on external storage. Specifically, |
| 45 | configuration and log files should only be stored on internal storage where |
| 46 | they can be effectively protected.</p> |
| 47 | |
| 48 | |
| 49 | <h2 id="multiple-external-storage-devices">Multiple external storage devices</h2> |
| 50 | |
| 51 | <p>Starting in Android 4.4, multiple external storage devices are surfaced |
| 52 | to developers through <code>Context.getExternalFilesDirs()</code>, |
| 53 | <code>Context.getExternalCacheDirs()</code>, and |
| 54 | <code>Context.getObbDirs()</code>.</p> |
| 55 | |
| 56 | </p>External storage devices surfaced through these APIs must be a |
| 57 | semi-permanent part of the device (such as an SD card slot in a battery |
| 58 | compartment). Developers expect data stored in these locations to be |
| 59 | available over long periods of time. For this reason, transient storage |
| 60 | devices (such as USB mass storage drives) should not be surfaced through |
| 61 | these APIs.</p> |
| 62 | |
| 63 | <p>The <code>WRITE_EXTERNAL_STORAGE</code> permission must only grant write |
| 64 | access to the primary external storage on a device. Apps must not be |
| 65 | allowed to write to secondary external storage devices, except in their |
| 66 | package-specific directories as allowed by synthesized |
| 67 | permissions. Restricting writes in this way ensures the system can clean |
| 68 | up files when applications are uninstalled.</p> |
| 69 | |
| 70 | |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 71 | <h2 id="multi-user-external-storage">Multi-user external storage</h2> |
Jeff Sharkey | 790c02d | 2013-10-18 13:57:33 -0700 | [diff] [blame] | 72 | |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 73 | <p>Starting in Android 4.2, devices can support multiple users, and external |
| 74 | storage must meet the following constraints:</p> |
Jeff Sharkey | 790c02d | 2013-10-18 13:57:33 -0700 | [diff] [blame] | 75 | |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 76 | <ul> |
Jeff Sharkey | 790c02d | 2013-10-18 13:57:33 -0700 | [diff] [blame] | 77 | <li>Each user must have their own isolated primary external storage, and |
| 78 | must not have access to the primary external storage of other users.</li> |
| 79 | <li>The <code>/sdcard</code> path must resolve to the correct user-specific |
| 80 | primary external storage based on the user a process is running as.</li> |
| 81 | <li>Storage for large OBB files in the <code>Android/obb</code> directory |
| 82 | may be shared between multiple users as an optimization.</li> |
| 83 | <li>Secondary external storage must not be writable by apps, except in |
| 84 | package-specific directories as allowed by synthesized permissions.</li> |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 85 | </ul> |
Jeff Sharkey | 790c02d | 2013-10-18 13:57:33 -0700 | [diff] [blame] | 86 | |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 87 | <p>The default platform implementation of this feature leverages Linux kernel |
Jeff Sharkey | 790c02d | 2013-10-18 13:57:33 -0700 | [diff] [blame] | 88 | namespaces to create isolated mount tables for each Zygote-forked process, |
| 89 | and then uses bind mounts to offer the correct user-specific primary external |
Robert Ly | 35f2fda | 2013-01-29 16:27:05 -0800 | [diff] [blame] | 90 | storage into that private namespace.</p> |
Jeff Sharkey | 790c02d | 2013-10-18 13:57:33 -0700 | [diff] [blame] | 91 | |
| 92 | <p>At boot, the system mounts a single emulated external storage FUSE daemon |
| 93 | at <code>EMULATED_STORAGE_SOURCE</code>, which is hidden from apps. After |
| 94 | the Zygote forks, it bind mounts the appropriate user-specific subdirectory |
| 95 | from under the FUSE daemon to <code>EMULATED_STORAGE_TARGET</code> so that |
| 96 | external storage paths resolve correctly for the app. Because an app lacks |
| 97 | accessible mount points for other users' storage, they can only access |
| 98 | storage for the user it was started as.</p> |
| 99 | |
| 100 | <p>This implementation also uses the shared subtree kernel feature to |
| 101 | propagate mount events from the default root namespace into app namespaces, |
| 102 | which ensures that features like ASEC containers and OBB mounting continue |
| 103 | working correctly. It does this by mounting the rootfs as shared, and then |
| 104 | remounting it as slave after each Zygote namespace is created.</p> |