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