Home | History | Annotate | Download | only in os
      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 
     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      * 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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    466     public static boolean isExternalStorageEmulated() {
    467         StorageVolume volume = getPrimaryVolume();
    468         return (volume != null && volume.isEmulated());
    469     }
    470 
    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