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