blob: 1f3f6d9565b6cdb29278632543278a171d7df3da [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Jason parksa3cdaa52011-01-13 14:15:43 -060019import java.io.File;
20
Dianne Hackborn407f6252010-10-04 11:31:17 -070021import android.content.res.Resources;
San Mehatb1043402010-02-05 08:26:50 -080022import android.os.storage.IMountService;
Mike Lockwood2f6a3882011-05-09 19:08:06 -070023import android.os.storage.StorageVolume;
Kenny Rootb2278dc2011-01-18 13:03:28 -080024import android.util.Log;
San Mehat7fd0fee2009-12-17 07:12:23 -080025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026/**
27 * Provides access to environment variables.
28 */
29public class Environment {
Kenny Rootb2278dc2011-01-18 13:03:28 -080030 private static final String TAG = "Environment";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
32 private static final File ROOT_DIRECTORY
33 = getDirectory("ANDROID_ROOT", "/system");
34
Oscar Montemayora8529f62009-11-18 10:14:20 -080035 private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
36
Kenny Roote1ff2142010-10-12 11:20:01 -070037 private static final Object mLock = new Object();
38
Mike Lockwood2f6a3882011-05-09 19:08:06 -070039 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 }
San Mehat7fd0fee2009-12-17 07:12:23 -080058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 /**
60 * Gets the Android root directory.
61 */
62 public static File getRootDirectory() {
63 return ROOT_DIRECTORY;
64 }
65
Jason parksa3cdaa52011-01-13 14:15:43 -060066 /**
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 * Returns whether the Encrypted File System feature is enabled on the device or not.
98 * @return <code>true</code> if Encrypted File System feature is enabled, <code>false</code>
99 * if disabled.
100 * @hide
101 */
102 public static boolean isEncryptedFilesystemEnabled() {
103 return SystemProperties.getBoolean(SYSTEM_PROPERTY_EFS_ENABLED, false);
104 }
105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 private static final File DATA_DIRECTORY
107 = getDirectory("ANDROID_DATA", "/data");
108
Oscar Montemayora8529f62009-11-18 10:14:20 -0800109 /**
110 * @hide
111 */
112 private static final File SECURE_DATA_DIRECTORY
113 = getDirectory("ANDROID_SECURE_DATA", "/data/secure");
114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 private static final File EXTERNAL_STORAGE_DIRECTORY
116 = getDirectory("EXTERNAL_STORAGE", "/sdcard");
117
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800118 private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY
119 = new File (new File(getDirectory("EXTERNAL_STORAGE", "/sdcard"),
120 "Android"), "data");
121
122 private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY
123 = new File (new File(getDirectory("EXTERNAL_STORAGE", "/sdcard"),
124 "Android"), "media");
125
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800126 private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY
127 = new File (new File(getDirectory("EXTERNAL_STORAGE", "/sdcard"),
128 "Android"), "obb");
129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 private static final File DOWNLOAD_CACHE_DIRECTORY
131 = getDirectory("DOWNLOAD_CACHE", "/cache");
132
133 /**
134 * Gets the Android data directory.
135 */
136 public static File getDataDirectory() {
137 return DATA_DIRECTORY;
138 }
139
140 /**
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800141 * Gets the Android external storage directory. This directory may not
142 * currently be accessible if it has been mounted by the user on their
143 * computer, has been removed from the device, or some other problem has
144 * happened. You can determine its current state with
145 * {@link #getExternalStorageState()}.
146 *
Dianne Hackborn407f6252010-10-04 11:31:17 -0700147 * <p><em>Note: don't be confused by the word "external" here. This
148 * directory can better be thought as media/shared storage. It is a
149 * filesystem that can hold a relatively large amount of data and that
150 * is shared across all applications (does not enforce permissions).
151 * Traditionally this is an SD card, but it may also be implemented as
152 * built-in storage in a device that is distinct from the protected
153 * internal storage and can be mounted as a filesystem on a computer.</em></p>
154 *
155 * <p>In devices with multiple "external" storage directories (such as
156 * both secure app storage and mountable shared storage), this directory
157 * represents the "primary" external storage that the user will interact
158 * with.</p>
159 *
Dianne Hackbornacaf0282010-03-30 14:39:35 -0700160 * <p>Applications should not directly use this top-level directory, in
161 * order to avoid polluting the user's root namespace. Any files that are
162 * private to the application should be placed in a directory returned
163 * by {@link android.content.Context#getExternalFilesDir
164 * Context.getExternalFilesDir}, which the system will take care of deleting
165 * if the application is uninstalled. Other shared files should be placed
166 * in one of the directories returned by
167 * {@link #getExternalStoragePublicDirectory}.
168 *
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800169 * <p>Here is an example of typical code to monitor the state of
170 * external storage:</p>
171 *
172 * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
173 * monitor_storage}
Dianne Hackborn407f6252010-10-04 11:31:17 -0700174 *
175 * @see #getExternalStorageState()
176 * @see #isExternalStorageRemovable()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 */
178 public static File getExternalStorageDirectory() {
179 return EXTERNAL_STORAGE_DIRECTORY;
180 }
181
182 /**
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800183 * Standard directory in which to place any audio files that should be
184 * in the regular list of music for the user.
185 * This may be combined with
186 * {@link #DIRECTORY_PODCASTS}, {@link #DIRECTORY_NOTIFICATIONS},
187 * {@link #DIRECTORY_ALARMS}, and {@link #DIRECTORY_RINGTONES} as a series
188 * of directories to categories a particular audio file as more than one
189 * type.
190 */
191 public static String DIRECTORY_MUSIC = "Music";
192
193 /**
194 * Standard directory in which to place any audio files that should be
195 * in the list of podcasts that the user can select (not as regular
196 * music).
197 * This may be combined with {@link #DIRECTORY_MUSIC},
198 * {@link #DIRECTORY_NOTIFICATIONS},
199 * {@link #DIRECTORY_ALARMS}, and {@link #DIRECTORY_RINGTONES} as a series
200 * of directories to categories a particular audio file as more than one
201 * type.
202 */
203 public static String DIRECTORY_PODCASTS = "Podcasts";
204
205 /**
206 * Standard directory in which to place any audio files that should be
207 * in the list of ringtones that the user can select (not as regular
208 * music).
209 * This may be combined with {@link #DIRECTORY_MUSIC},
210 * {@link #DIRECTORY_PODCASTS}, {@link #DIRECTORY_NOTIFICATIONS}, and
211 * {@link #DIRECTORY_ALARMS} as a series
212 * of directories to categories a particular audio file as more than one
213 * type.
214 */
215 public static String DIRECTORY_RINGTONES = "Ringtones";
216
217 /**
218 * Standard directory in which to place any audio files that should be
219 * in the list of alarms that the user can select (not as regular
220 * music).
221 * This may be combined with {@link #DIRECTORY_MUSIC},
222 * {@link #DIRECTORY_PODCASTS}, {@link #DIRECTORY_NOTIFICATIONS},
223 * and {@link #DIRECTORY_RINGTONES} as a series
224 * of directories to categories a particular audio file as more than one
225 * type.
226 */
227 public static String DIRECTORY_ALARMS = "Alarms";
228
229 /**
230 * Standard directory in which to place any audio files that should be
231 * in the list of notifications that the user can select (not as regular
232 * music).
233 * This may be combined with {@link #DIRECTORY_MUSIC},
234 * {@link #DIRECTORY_PODCASTS},
235 * {@link #DIRECTORY_ALARMS}, and {@link #DIRECTORY_RINGTONES} as a series
236 * of directories to categories a particular audio file as more than one
237 * type.
238 */
239 public static String DIRECTORY_NOTIFICATIONS = "Notifications";
240
241 /**
242 * Standard directory in which to place pictures that are available to
243 * the user. Note that this is primarily a convention for the top-level
244 * public directory, as the media scanner will find and collect pictures
245 * in any directory.
246 */
247 public static String DIRECTORY_PICTURES = "Pictures";
248
249 /**
250 * Standard directory in which to place movies that are available to
251 * the user. Note that this is primarily a convention for the top-level
252 * public directory, as the media scanner will find and collect movies
253 * in any directory.
254 */
255 public static String DIRECTORY_MOVIES = "Movies";
256
257 /**
258 * Standard directory in which to place files that have been downloaded by
259 * the user. Note that this is primarily a convention for the top-level
260 * public directory, you are free to download files anywhere in your own
Dianne Hackbornce59fb82010-04-07 17:19:04 -0700261 * private directories. Also note that though the constant here is
262 * named DIRECTORY_DOWNLOADS (plural), the actual file name is non-plural for
263 * backwards compatibility reasons.
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800264 */
Dianne Hackbornce59fb82010-04-07 17:19:04 -0700265 public static String DIRECTORY_DOWNLOADS = "Download";
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800266
267 /**
268 * The traditional location for pictures and videos when mounting the
269 * device as a camera. Note that this is primarily a convention for the
270 * top-level public directory, as this convention makes no sense elsewhere.
271 */
272 public static String DIRECTORY_DCIM = "DCIM";
273
274 /**
275 * Get a top-level public external storage directory for placing files of
276 * a particular type. This is where the user will typically place and
277 * manage their own files, so you should be careful about what you put here
278 * to ensure you don't erase their files or get in the way of their own
279 * organization.
280 *
281 * <p>Here is an example of typical code to manipulate a picture on
282 * the public external storage:</p>
283 *
284 * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
285 * public_picture}
286 *
287 * @param type The type of storage directory to return. Should be one of
288 * {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS},
289 * {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS},
290 * {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES},
291 * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, or
292 * {@link #DIRECTORY_DCIM}. May not be null.
293 *
294 * @return Returns the File path for the directory. Note that this
295 * directory may not yet exist, so you must make sure it exists before
296 * using it such as with {@link File#mkdirs File.mkdirs()}.
297 */
298 public static File getExternalStoragePublicDirectory(String type) {
299 return new File(getExternalStorageDirectory(), type);
300 }
301
302 /**
303 * Returns the path for android-specific data on the SD card.
304 * @hide
305 */
306 public static File getExternalStorageAndroidDataDir() {
307 return EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY;
308 }
309
310 /**
311 * Generates the raw path to an application's data
312 * @hide
313 */
314 public static File getExternalStorageAppDataDirectory(String packageName) {
315 return new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY, packageName);
316 }
317
318 /**
319 * Generates the raw path to an application's media
320 * @hide
321 */
322 public static File getExternalStorageAppMediaDirectory(String packageName) {
323 return new File(EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY, packageName);
324 }
325
326 /**
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800327 * Generates the raw path to an application's OBB files
328 * @hide
329 */
330 public static File getExternalStorageAppObbDirectory(String packageName) {
331 return new File(EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY, packageName);
332 }
333
334 /**
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800335 * Generates the path to an application's files.
336 * @hide
337 */
338 public static File getExternalStorageAppFilesDirectory(String packageName) {
339 return new File(new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY,
340 packageName), "files");
341 }
342
343 /**
344 * Generates the path to an application's cache.
345 * @hide
346 */
347 public static File getExternalStorageAppCacheDirectory(String packageName) {
348 return new File(new File(EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY,
349 packageName), "cache");
350 }
351
352 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 * Gets the Android Download/Cache content directory.
354 */
355 public static File getDownloadCacheDirectory() {
356 return DOWNLOAD_CACHE_DIRECTORY;
357 }
358
359 /**
360 * getExternalStorageState() returns MEDIA_REMOVED if the media is not present.
361 */
362 public static final String MEDIA_REMOVED = "removed";
363
364 /**
365 * getExternalStorageState() returns MEDIA_UNMOUNTED if the media is present
366 * but not mounted.
367 */
368 public static final String MEDIA_UNMOUNTED = "unmounted";
369
370 /**
371 * getExternalStorageState() returns MEDIA_CHECKING if the media is present
372 * and being disk-checked
373 */
374 public static final String MEDIA_CHECKING = "checking";
375
376 /**
377 * getExternalStorageState() returns MEDIA_NOFS if the media is present
378 * but is blank or is using an unsupported filesystem
379 */
380 public static final String MEDIA_NOFS = "nofs";
381
382 /**
383 * getExternalStorageState() returns MEDIA_MOUNTED if the media is present
384 * and mounted at its mount point with read/write access.
385 */
386 public static final String MEDIA_MOUNTED = "mounted";
387
388 /**
389 * getExternalStorageState() returns MEDIA_MOUNTED_READ_ONLY if the media is present
390 * and mounted at its mount point with read only access.
391 */
392 public static final String MEDIA_MOUNTED_READ_ONLY = "mounted_ro";
393
394 /**
395 * getExternalStorageState() returns MEDIA_SHARED if the media is present
396 * not mounted, and shared via USB mass storage.
397 */
398 public static final String MEDIA_SHARED = "shared";
399
400 /**
401 * getExternalStorageState() returns MEDIA_BAD_REMOVAL if the media was
402 * removed before it was unmounted.
403 */
404 public static final String MEDIA_BAD_REMOVAL = "bad_removal";
405
406 /**
407 * getExternalStorageState() returns MEDIA_UNMOUNTABLE if the media is present
408 * but cannot be mounted. Typically this happens if the file system on the
409 * media is corrupted.
410 */
411 public static final String MEDIA_UNMOUNTABLE = "unmountable";
412
413 /**
Dianne Hackborn407f6252010-10-04 11:31:17 -0700414 * Gets the current state of the primary "external" storage device.
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800415 *
Dianne Hackborn407f6252010-10-04 11:31:17 -0700416 * <p>See {@link #getExternalStorageDirectory()} for more information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 */
418 public static String getExternalStorageState() {
San Mehat7fd0fee2009-12-17 07:12:23 -0800419 try {
Kenny Rootb2278dc2011-01-18 13:03:28 -0800420 IMountService mountService = IMountService.Stub.asInterface(ServiceManager
421 .getService("mount"));
422 return mountService.getVolumeState(getExternalStorageDirectory()
Kenny Roote1ff2142010-10-12 11:20:01 -0700423 .toString());
San Mehata6a72812010-01-07 22:39:53 -0800424 } catch (Exception rex) {
San Mehat7fd0fee2009-12-17 07:12:23 -0800425 return Environment.MEDIA_REMOVED;
426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 }
428
Dianne Hackborn407f6252010-10-04 11:31:17 -0700429 /**
430 * Returns whether the primary "external" storage device is removable.
431 * If true is returned, this device is for example an SD card that the
432 * user can remove. If false is returned, the storage is built into
433 * the device and can not be physically removed.
434 *
435 * <p>See {@link #getExternalStorageDirectory()} for more information.
436 */
437 public static boolean isExternalStorageRemovable() {
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700438 StorageVolume volume = getPrimaryVolume();
439 return (volume != null && volume.isRemovable());
Dianne Hackborn407f6252010-10-04 11:31:17 -0700440 }
441
Kenny Roote1ff2142010-10-12 11:20:01 -0700442 /**
443 * Returns whether the device has an external storage device which is
Andy Stadler50c294f2011-03-07 19:13:42 -0800444 * emulated. If true, the device does not have real external storage, and the directory
445 * returned by {@link #getExternalStorageDirectory()} will be allocated using a portion of
446 * the internal storage system.
447 *
448 * <p>Certain system services, such as the package manager, use this
Kenny Roote1ff2142010-10-12 11:20:01 -0700449 * to determine where to install an application.
Andy Stadler50c294f2011-03-07 19:13:42 -0800450 *
451 * <p>Emulated external storage may also be encrypted - see
452 * {@link android.app.admin.DevicePolicyManager#setStorageEncryption(
453 * android.content.ComponentName, boolean)} for additional details.
Kenny Roote1ff2142010-10-12 11:20:01 -0700454 */
455 public static boolean isExternalStorageEmulated() {
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700456 StorageVolume volume = getPrimaryVolume();
457 return (volume != null && volume.isEmulated());
Kenny Roote1ff2142010-10-12 11:20:01 -0700458 }
459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 static File getDirectory(String variableName, String defaultPath) {
461 String path = System.getenv(variableName);
462 return path == null ? new File(defaultPath) : new File(path);
463 }
464}