Home | History | Annotate | Download | only in storage
      1 /*
      2  * Copyright (C) 2011 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.storage;
     18 
     19 import android.content.Context;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 import android.os.UserHandle;
     23 
     24 import java.io.File;
     25 
     26 /**
     27  * Description of a storage volume and its capabilities, including the
     28  * filesystem path where it may be mounted.
     29  *
     30  * @hide
     31  */
     32 public class StorageVolume implements Parcelable {
     33 
     34     // TODO: switch to more durable token
     35     private int mStorageId;
     36 
     37     private final File mPath;
     38     private final int mDescriptionId;
     39     private final boolean mPrimary;
     40     private final boolean mRemovable;
     41     private final boolean mEmulated;
     42     private final int mMtpReserveSpace;
     43     private final boolean mAllowMassStorage;
     44     /** Maximum file size for the storage, or zero for no limit */
     45     private final long mMaxFileSize;
     46     /** When set, indicates exclusive ownership of this volume */
     47     private final UserHandle mOwner;
     48 
     49     // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING,
     50     // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED,
     51     // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts.
     52     public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
     53 
     54     public StorageVolume(File path, int descriptionId, boolean primary, boolean removable,
     55             boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize,
     56             UserHandle owner) {
     57         mPath = path;
     58         mDescriptionId = descriptionId;
     59         mPrimary = primary;
     60         mRemovable = removable;
     61         mEmulated = emulated;
     62         mMtpReserveSpace = mtpReserveSpace;
     63         mAllowMassStorage = allowMassStorage;
     64         mMaxFileSize = maxFileSize;
     65         mOwner = owner;
     66     }
     67 
     68     private StorageVolume(Parcel in) {
     69         mStorageId = in.readInt();
     70         mPath = new File(in.readString());
     71         mDescriptionId = in.readInt();
     72         mPrimary = in.readInt() != 0;
     73         mRemovable = in.readInt() != 0;
     74         mEmulated = in.readInt() != 0;
     75         mMtpReserveSpace = in.readInt();
     76         mAllowMassStorage = in.readInt() != 0;
     77         mMaxFileSize = in.readLong();
     78         mOwner = in.readParcelable(null);
     79     }
     80 
     81     public static StorageVolume fromTemplate(StorageVolume template, File path, UserHandle owner) {
     82         return new StorageVolume(path, template.mDescriptionId, template.mPrimary,
     83                 template.mRemovable, template.mEmulated, template.mMtpReserveSpace,
     84                 template.mAllowMassStorage, template.mMaxFileSize, owner);
     85     }
     86 
     87     /**
     88      * Returns the mount path for the volume.
     89      *
     90      * @return the mount path
     91      */
     92     public String getPath() {
     93         return mPath.toString();
     94     }
     95 
     96     public File getPathFile() {
     97         return mPath;
     98     }
     99 
    100     /**
    101      * Returns a user visible description of the volume.
    102      *
    103      * @return the volume description
    104      */
    105     public String getDescription(Context context) {
    106         return context.getResources().getString(mDescriptionId);
    107     }
    108 
    109     public int getDescriptionId() {
    110         return mDescriptionId;
    111     }
    112 
    113     public boolean isPrimary() {
    114         return mPrimary;
    115     }
    116 
    117     /**
    118      * Returns true if the volume is removable.
    119      *
    120      * @return is removable
    121      */
    122     public boolean isRemovable() {
    123         return mRemovable;
    124     }
    125 
    126     /**
    127      * Returns true if the volume is emulated.
    128      *
    129      * @return is removable
    130      */
    131     public boolean isEmulated() {
    132         return mEmulated;
    133     }
    134 
    135     /**
    136      * Returns the MTP storage ID for the volume.
    137      * this is also used for the storage_id column in the media provider.
    138      *
    139      * @return MTP storage ID
    140      */
    141     public int getStorageId() {
    142         return mStorageId;
    143     }
    144 
    145     /**
    146      * Do not call this unless you are MountService
    147      */
    148     public void setStorageId(int index) {
    149         // storage ID is 0x00010001 for primary storage,
    150         // then 0x00020001, 0x00030001, etc. for secondary storages
    151         mStorageId = ((index + 1) << 16) + 1;
    152     }
    153 
    154     /**
    155      * Number of megabytes of space to leave unallocated by MTP.
    156      * MTP will subtract this value from the free space it reports back
    157      * to the host via GetStorageInfo, and will not allow new files to
    158      * be added via MTP if there is less than this amount left free in the storage.
    159      * If MTP has dedicated storage this value should be zero, but if MTP is
    160      * sharing storage with the rest of the system, set this to a positive value
    161      * to ensure that MTP activity does not result in the storage being
    162      * too close to full.
    163      *
    164      * @return MTP reserve space
    165      */
    166     public int getMtpReserveSpace() {
    167         return mMtpReserveSpace;
    168     }
    169 
    170     /**
    171      * Returns true if this volume can be shared via USB mass storage.
    172      *
    173      * @return whether mass storage is allowed
    174      */
    175     public boolean allowMassStorage() {
    176         return mAllowMassStorage;
    177     }
    178 
    179     /**
    180      * Returns maximum file size for the volume, or zero if it is unbounded.
    181      *
    182      * @return maximum file size
    183      */
    184     public long getMaxFileSize() {
    185         return mMaxFileSize;
    186     }
    187 
    188     public UserHandle getOwner() {
    189         return mOwner;
    190     }
    191 
    192     @Override
    193     public boolean equals(Object obj) {
    194         if (obj instanceof StorageVolume && mPath != null) {
    195             StorageVolume volume = (StorageVolume)obj;
    196             return (mPath.equals(volume.mPath));
    197         }
    198         return false;
    199     }
    200 
    201     @Override
    202     public int hashCode() {
    203         return mPath.hashCode();
    204     }
    205 
    206     @Override
    207     public String toString() {
    208         final StringBuilder builder = new StringBuilder("StorageVolume [");
    209         builder.append("mStorageId=").append(mStorageId);
    210         builder.append(" mPath=").append(mPath);
    211         builder.append(" mDescriptionId=").append(mDescriptionId);
    212         builder.append(" mPrimary=").append(mPrimary);
    213         builder.append(" mRemovable=").append(mRemovable);
    214         builder.append(" mEmulated=").append(mEmulated);
    215         builder.append(" mMtpReserveSpace=").append(mMtpReserveSpace);
    216         builder.append(" mAllowMassStorage=").append(mAllowMassStorage);
    217         builder.append(" mMaxFileSize=").append(mMaxFileSize);
    218         builder.append(" mOwner=").append(mOwner);
    219         builder.append("]");
    220         return builder.toString();
    221     }
    222 
    223     public static final Creator<StorageVolume> CREATOR = new Creator<StorageVolume>() {
    224         @Override
    225         public StorageVolume createFromParcel(Parcel in) {
    226             return new StorageVolume(in);
    227         }
    228 
    229         @Override
    230         public StorageVolume[] newArray(int size) {
    231             return new StorageVolume[size];
    232         }
    233     };
    234 
    235     @Override
    236     public int describeContents() {
    237         return 0;
    238     }
    239 
    240     @Override
    241     public void writeToParcel(Parcel parcel, int flags) {
    242         parcel.writeInt(mStorageId);
    243         parcel.writeString(mPath.toString());
    244         parcel.writeInt(mDescriptionId);
    245         parcel.writeInt(mPrimary ? 1 : 0);
    246         parcel.writeInt(mRemovable ? 1 : 0);
    247         parcel.writeInt(mEmulated ? 1 : 0);
    248         parcel.writeInt(mMtpReserveSpace);
    249         parcel.writeInt(mAllowMassStorage ? 1 : 0);
    250         parcel.writeLong(mMaxFileSize);
    251         parcel.writeParcelable(mOwner, flags);
    252     }
    253 }
    254