1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 import java.io.File; 20 21 import android.content.res.Resources; 22 import android.os.storage.IMountService; 23 24 /** 25 * Provides access to environment variables. 26 */ 27 public class Environment { 28 29 private static final File ROOT_DIRECTORY 30 = getDirectory("ANDROID_ROOT", "/system"); 31 32 private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled"; 33 34 private static IMountService mMntSvc = null; 35 36 /** 37 * Gets the Android root directory. 38 */ 39 public static File getRootDirectory() { 40 return ROOT_DIRECTORY; 41 } 42 43 /** 44 * Gets the system directory available for secure storage. 45 * If Encrypted File system is enabled, it returns an encrypted directory (/data/secure/system). 46 * Otherwise, it returns the unencrypted /data/system directory. 47 * @return File object representing the secure storage system directory. 48 * @hide 49 */ 50 public static File getSystemSecureDirectory() { 51 if (isEncryptedFilesystemEnabled()) { 52 return new File(SECURE_DATA_DIRECTORY, "system"); 53 } else { 54 return new File(DATA_DIRECTORY, "system"); 55 } 56 } 57 58 /** 59 * Gets the data directory for secure storage. 60 * If Encrypted File system is enabled, it returns an encrypted directory (/data/secure). 61 * Otherwise, it returns the unencrypted /data directory. 62 * @return File object representing the data directory for secure storage. 63 * @hide 64 */ 65 public static File getSecureDataDirectory() { 66 if (isEncryptedFilesystemEnabled()) { 67 return SECURE_DATA_DIRECTORY; 68 } else { 69 return DATA_DIRECTORY; 70 } 71 } 72 73 /** 74 * Returns whether the Encrypted File System feature is enabled on the device or not. 75 * @return <code>true</code> if Encrypted File System feature is enabled, <code>false</code> 76 * if disabled. 77 * @hide 78 */ 79 public static boolean isEncryptedFilesystemEnabled() { 80 return SystemProperties.getBoolean(SYSTEM_PROPERTY_EFS_ENABLED, false); 81 } 82 83 private static final File DATA_DIRECTORY 84 = getDirectory("ANDROID_DATA", "/data"); 85 86 /** 87 * @hide 88 */ 89 private static final File SECURE_DATA_DIRECTORY 90 = getDirectory("ANDROID_SECURE_DATA", "/data/secure"); 91 92 private static final File EXTERNAL_STORAGE_DIRECTORY 93 = getDirectory("EXTERNAL_STORAGE", "/sdcard"); 94 95 private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY 96 = new File (new File(getDirectory("EXTERNAL_STORAGE", "/sdcard"), 97 "Android"), "data"); 98 99 private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY 100 = new File (new File(getDirectory("EXTERNAL_STORAGE", "/sdcard"), 101 "Android"), "media"); 102 103 private static final File DOWNLOAD_CACHE_DIRECTORY 104 = getDirectory("DOWNLOAD_CACHE", "/cache"); 105 106 /** 107 * Gets the Android data directory. 108 */ 109 public static File getDataDirectory() { 110 return DATA_DIRECTORY; 111 } 112 113 /** 114 * Gets the Android external storage directory. This directory may not 115 * currently be accessible if it has been mounted by the user on their 116 * computer, has been removed from the device, or some other problem has 117 * happened. You can determine its current state with 118 * {@link #getExternalStorageState()}. 119 * 120 * <p><em>Note: don't be confused by the word "external" here. This 121 * directory can better be thought as media/shared storage. It is a 122 * filesystem that can hold a relatively large amount of data and that 123 * is shared across all applications (does not enforce permissions). 124 * Traditionally this is an SD card, but it may also be implemented as 125 * built-in storage in a device that is distinct from the protected 126 * internal storage and can be mounted as a filesystem on a computer.</em></p> 127 * 128 * <p>In devices with multiple "external" storage directories (such as 129 * both secure app storage and mountable shared storage), this directory 130 * represents the "primary" external storage that the user will interact 131 * with.</p> 132 * 133 * <p>Applications should not directly use this top-level directory, in 134 * order to avoid polluting the user's root namespace. Any files that are 135 * private to the application should be placed in a directory returned 136 * by {@link android.content.Context#getExternalFilesDir 137 * Context.getExternalFilesDir}, which the system will take care of deleting 138 * if the application is uninstalled. Other shared files should be placed 139 * in one of the directories returned by 140 * {@link #getExternalStoragePublicDirectory}. 141 * 142 * <p>Here is an example of typical code to monitor the state of 143 * external storage:</p> 144 * 145 * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java 146 * monitor_storage} 147 * 148 * @see #getExternalStorageState() 149 * @see #isExternalStorageRemovable() 150 */ 151 public static File getExternalStorageDirectory() { 152 return EXTERNAL_STORAGE_DIRECTORY; 153 } 154 155 /** 156 * Standard directory in which to place any audio files that should be 157 * in the regular list of music for the user. 158 * This may be combined with 159 * {@link #DIRECTORY_PODCASTS}, {@link #DIRECTORY_NOTIFICATIONS}, 160 * {@link #DIRECTORY_ALARMS}, and {@link #DIRECTORY_RINGTONES} as a series 161 * of directories to categories a particular audio file as more than one 162 * type. 163 */ 164 public static String DIRECTORY_MUSIC = "Music"; 165 166 /** 167 * Standard directory in which to place any audio files that should be 168 * in the list of podcasts that the user can select (not as regular 169 * music). 170 * This may be combined with {@link #DIRECTORY_MUSIC}, 171 * {@link #DIRECTORY_NOTIFICATIONS}, 172 * {@link #DIRECTORY_ALARMS}, and {@link #DIRECTORY_RINGTONES} as a series 173 * of directories to categories a particular audio file as more than one 174 * type. 175 */ 176 public static String DIRECTORY_PODCASTS = "Podcasts"; 177 178 /** 179 * Standard directory in which to place any audio files that should be 180 * in the list of ringtones that the user can select (not as regular 181 * music). 182 * This may be combined with {@link #DIRECTORY_MUSIC}, 183 * {@link #DIRECTORY_PODCASTS}, {@link #DIRECTORY_NOTIFICATIONS}, and 184 * {@link #DIRECTORY_ALARMS} as a series 185 * of directories to categories a particular audio file as more than one 186 * type. 187 */ 188 public static String DIRECTORY_RINGTONES = "Ringtones"; 189 190 /** 191 * Standard directory in which to place any audio files that should be 192 * in the list of alarms that the user can select (not as regular 193 * music). 194 * This may be combined with {@link #DIRECTORY_MUSIC}, 195 * {@link #DIRECTORY_PODCASTS}, {@link #DIRECTORY_NOTIFICATIONS}, 196 * and {@link #DIRECTORY_RINGTONES} as a series 197 * of directories to categories a particular audio file as more than one 198 * type. 199 */ 200 public static String DIRECTORY_ALARMS = "Alarms"; 201 202 /** 203 * Standard directory in which to place any audio files that should be 204 * in the list of notifications that the user can select (not as regular 205 * music). 206 * This may be combined with {@link #DIRECTORY_MUSIC}, 207 * {@link #DIRECTORY_PODCASTS}, 208 * {@link #DIRECTORY_ALARMS}, and {@link #DIRECTORY_RINGTONES} as a series 209 * of directories to categories a particular audio file as more than one 210 * type. 211 */ 212 public static String DIRECTORY_NOTIFICATIONS = "Notifications"; 213 214 /** 215 * Standard directory in which to place pictures that are available to 216 * the user. Note that this is primarily a convention for the top-level 217 * public directory, as the media scanner will find and collect pictures 218 * in any directory. 219 */ 220 public static String DIRECTORY_PICTURES = "Pictures"; 221 222 /** 223 * Standard directory in which to place movies that are available to 224 * the user. Note that this is primarily a convention for the top-level 225 * public directory, as the media scanner will find and collect movies 226 * in any directory. 227 */ 228 public static String DIRECTORY_MOVIES = "Movies"; 229 230 /** 231 * Standard directory in which to place files that have been downloaded by 232 * the user. Note that this is primarily a convention for the top-level 233 * public directory, you are free to download files anywhere in your own 234 * private directories. Also note that though the constant here is 235 * named DIRECTORY_DOWNLOADS (plural), the actual file name is non-plural for 236 * backwards compatibility reasons. 237 */ 238 public static String DIRECTORY_DOWNLOADS = "Download"; 239 240 /** 241 * The traditional location for pictures and videos when mounting the 242 * device as a camera. Note that this is primarily a convention for the 243 * top-level public directory, as this convention makes no sense elsewhere. 244 */ 245 public static String DIRECTORY_DCIM = "DCIM"; 246 247 /** 248 * Get a top-level public external storage directory for placing files of 249 * a particular type. This is where the user will typically place and 250 * manage their own files, so you should be careful about what you put here 251 * to ensure you don't erase their files or get in the way of their own 252 * organization. 253 * 254 * <p>Here is an example of typical code to manipulate a picture on 255 * the public external storage:</p> 256 * 257 * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java 258 * public_picture} 259 * 260 * @param type The type of storage directory to return. Should be one of 261 * {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS}, 262 * {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS}, 263 * {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES}, 264 * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, or 265 * {@link #DIRECTORY_DCIM}. May not be null. 266 * 267 * @return Returns the File path for the directory. Note that this 268 * directory may not yet exist, so you must make sure it exists before 269 * using it such as with {@link File#mkdirs File.mkdirs()}. 270 */ 271 public static File getExternalStoragePublicDirectory(String type) { 272 return new File(getExternalStorageDirectory(), type); 273 } 274 275 /** 276 * Returns the path for android-specific data on the SD card. 277 * @hide 278 */ 279 public static File getExternalStorageAndroidDataDir() { 280 return EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY; 281 } 282 283 /** 284 * Generates the raw path to an application's data 285 * @hide 286 */ 287 public static File getExternalStorageAppDataDirectory(String packageName) { 288 return new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY, packageName); 289 } 290 291 /** 292 * Generates the raw path to an application's media 293 * @hide 294 */ 295 public static File getExternalStorageAppMediaDirectory(String packageName) { 296 return new File(EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY, packageName); 297 } 298 299 /** 300 * Generates the path to an application's files. 301 * @hide 302 */ 303 public static File getExternalStorageAppFilesDirectory(String packageName) { 304 return new File(new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY, 305 packageName), "files"); 306 } 307 308 /** 309 * Generates the path to an application's cache. 310 * @hide 311 */ 312 public static File getExternalStorageAppCacheDirectory(String packageName) { 313 return new File(new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY, 314 packageName), "cache"); 315 } 316 317 /** 318 * Gets the Android Download/Cache content directory. 319 */ 320 public static File getDownloadCacheDirectory() { 321 return DOWNLOAD_CACHE_DIRECTORY; 322 } 323 324 /** 325 * getExternalStorageState() returns MEDIA_REMOVED if the media is not present. 326 */ 327 public static final String MEDIA_REMOVED = "removed"; 328 329 /** 330 * getExternalStorageState() returns MEDIA_UNMOUNTED if the media is present 331 * but not mounted. 332 */ 333 public static final String MEDIA_UNMOUNTED = "unmounted"; 334 335 /** 336 * getExternalStorageState() returns MEDIA_CHECKING if the media is present 337 * and being disk-checked 338 */ 339 public static final String MEDIA_CHECKING = "checking"; 340 341 /** 342 * getExternalStorageState() returns MEDIA_NOFS if the media is present 343 * but is blank or is using an unsupported filesystem 344 */ 345 public static final String MEDIA_NOFS = "nofs"; 346 347 /** 348 * getExternalStorageState() returns MEDIA_MOUNTED if the media is present 349 * and mounted at its mount point with read/write access. 350 */ 351 public static final String MEDIA_MOUNTED = "mounted"; 352 353 /** 354 * getExternalStorageState() returns MEDIA_MOUNTED_READ_ONLY if the media is present 355 * and mounted at its mount point with read only access. 356 */ 357 public static final String MEDIA_MOUNTED_READ_ONLY = "mounted_ro"; 358 359 /** 360 * getExternalStorageState() returns MEDIA_SHARED if the media is present 361 * not mounted, and shared via USB mass storage. 362 */ 363 public static final String MEDIA_SHARED = "shared"; 364 365 /** 366 * getExternalStorageState() returns MEDIA_BAD_REMOVAL if the media was 367 * removed before it was unmounted. 368 */ 369 public static final String MEDIA_BAD_REMOVAL = "bad_removal"; 370 371 /** 372 * getExternalStorageState() returns MEDIA_UNMOUNTABLE if the media is present 373 * but cannot be mounted. Typically this happens if the file system on the 374 * media is corrupted. 375 */ 376 public static final String MEDIA_UNMOUNTABLE = "unmountable"; 377 378 /** 379 * Gets the current state of the primary "external" storage device. 380 * 381 * <p>See {@link #getExternalStorageDirectory()} for more information. 382 */ 383 public static String getExternalStorageState() { 384 try { 385 if (mMntSvc == null) { 386 mMntSvc = IMountService.Stub.asInterface(ServiceManager 387 .getService("mount")); 388 } 389 return mMntSvc.getVolumeState(getExternalStorageDirectory().toString()); 390 } catch (Exception rex) { 391 return Environment.MEDIA_REMOVED; 392 } 393 } 394 395 /** 396 * Returns whether the primary "external" storage device is removable. 397 * If true is returned, this device is for example an SD card that the 398 * user can remove. If false is returned, the storage is built into 399 * the device and can not be physically removed. 400 * 401 * <p>See {@link #getExternalStorageDirectory()} for more information. 402 */ 403 public static boolean isExternalStorageRemovable() { 404 return Resources.getSystem().getBoolean( 405 com.android.internal.R.bool.config_externalStorageRemovable); 406 } 407 408 static File getDirectory(String variableName, String defaultPath) { 409 String path = System.getenv(variableName); 410 return path == null ? new File(defaultPath) : new File(path); 411 } 412 } 413