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