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      * 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 
    106     private static final File DATA_DIRECTORY
    107             = getDirectory("ANDROID_DATA", "/data");
    108 
    109     /**
    110      * @hide
    111      */
    112     private static final File SECURE_DATA_DIRECTORY
    113             = getDirectory("ANDROID_SECURE_DATA", "/data/secure");
    114 
    115     private static final File EXTERNAL_STORAGE_DIRECTORY
    116             = getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard");
    117 
    118     private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY
    119             = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
    120                     "Android"), "data");
    121 
    122     private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY
    123             = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
    124                     "Android"), "media");
    125 
    126     private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY
    127             = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
    128                     "Android"), "obb");
    129 
    130     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     /**
    141      * 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      *
    147      * <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      *
    160      * <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      *
    169      * <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}
    174      *
    175      * @see #getExternalStorageState()
    176      * @see #isExternalStorageRemovable()
    177      */
    178     public static File getExternalStorageDirectory() {
    179         return EXTERNAL_STORAGE_DIRECTORY;
    180     }
    181 
    182     /**
    183      * 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
    261      * 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.
    264      */
    265     public static String DIRECTORY_DOWNLOADS = "Download";
    266 
    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     /**
    327      * 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     /**
    335      * 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     /**
    353      * Gets the Android Download/Cache content directory.
    354      */
    355     public static File getDownloadCacheDirectory() {
    356         return DOWNLOAD_CACHE_DIRECTORY;
    357     }
    358 
    359     /**
    360      * {@link #getExternalStorageState()} returns MEDIA_REMOVED if the media is not present.
    361      */
    362     public static final String MEDIA_REMOVED = "removed";
    363 
    364     /**
    365      * {@link #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      * {@link #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      * {@link #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      * {@link #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      * {@link #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      * {@link #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      * {@link #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      * {@link #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     /**
    414      * Gets the current state of the primary "external" storage device.
    415      *
    416      * <p>See {@link #getExternalStorageDirectory()} for more information.
    417      */
    418     public static String getExternalStorageState() {
    419         try {
    420             IMountService mountService = IMountService.Stub.asInterface(ServiceManager
    421                     .getService("mount"));
    422             return mountService.getVolumeState(getExternalStorageDirectory()
    423                     .toString());
    424         } catch (Exception rex) {
    425             return Environment.MEDIA_REMOVED;
    426         }
    427     }
    428 
    429     /**
    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() {
    438         StorageVolume volume = getPrimaryVolume();
    439         return (volume != null && volume.isRemovable());
    440     }
    441 
    442     /**
    443      * Returns whether the device has an external storage device which is
    444      * 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
    449      * to determine where to install an application.
    450      *
    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.
    454      */
    455     public static boolean isExternalStorageEmulated() {
    456         StorageVolume volume = getPrimaryVolume();
    457         return (volume != null && volume.isEmulated());
    458     }
    459 
    460     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 }
    465