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