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