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 com.android.internal.util.IndentingPrintWriter;
     25 
     26 import java.io.CharArrayWriter;
     27 import java.io.File;
     28 
     29 /**
     30  * Description of a storage volume and its capabilities, including the
     31  * filesystem path where it may be mounted.
     32  *
     33  * @hide
     34  */
     35 public class StorageVolume implements Parcelable {
     36 
     37     // TODO: switch to more durable token
     38     private int mStorageId;
     39 
     40     private final File mPath;
     41     private final int mDescriptionId;
     42     private final boolean mPrimary;
     43     private final boolean mRemovable;
     44     private final boolean mEmulated;
     45     private final int mMtpReserveSpace;
     46     private final boolean mAllowMassStorage;
     47     /** Maximum file size for the storage, or zero for no limit */
     48     private final long mMaxFileSize;
     49     /** When set, indicates exclusive ownership of this volume */
     50     private final UserHandle mOwner;
     51 
     52     private String mUuid;
     53     private String mUserLabel;
     54     private String mState;
     55 
     56     // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING,
     57     // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED,
     58     // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts.
     59     public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
     60 
     61     public StorageVolume(File path, int descriptionId, boolean primary, boolean removable,
     62             boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize,
     63             UserHandle owner) {
     64         mPath = path;
     65         mDescriptionId = descriptionId;
     66         mPrimary = primary;
     67         mRemovable = removable;
     68         mEmulated = emulated;
     69         mMtpReserveSpace = mtpReserveSpace;
     70         mAllowMassStorage = allowMassStorage;
     71         mMaxFileSize = maxFileSize;
     72         mOwner = owner;
     73     }
     74 
     75     private StorageVolume(Parcel in) {
     76         mStorageId = in.readInt();
     77         mPath = new File(in.readString());
     78         mDescriptionId = in.readInt();
     79         mPrimary = in.readInt() != 0;
     80         mRemovable = in.readInt() != 0;
     81         mEmulated = in.readInt() != 0;
     82         mMtpReserveSpace = in.readInt();
     83         mAllowMassStorage = in.readInt() != 0;
     84         mMaxFileSize = in.readLong();
     85         mOwner = in.readParcelable(null);
     86         mUuid = in.readString();
     87         mUserLabel = in.readString();
     88         mState = in.readString();
     89     }
     90 
     91     public static StorageVolume fromTemplate(StorageVolume template, File path, UserHandle owner) {
     92         return new StorageVolume(path, template.mDescriptionId, template.mPrimary,
     93                 template.mRemovable, template.mEmulated, template.mMtpReserveSpace,
     94                 template.mAllowMassStorage, template.mMaxFileSize, owner);
     95     }
     96 
     97     /**
     98      * Returns the mount path for the volume.
     99      *
    100      * @return the mount path
    101      */
    102     public String getPath() {
    103         return mPath.toString();
    104     }
    105 
    106     public File getPathFile() {
    107         return mPath;
    108     }
    109 
    110     /**
    111      * Returns a user visible description of the volume.
    112      *
    113      * @return the volume description
    114      */
    115     public String getDescription(Context context) {
    116         return context.getResources().getString(mDescriptionId);
    117     }
    118 
    119     public int getDescriptionId() {
    120         return mDescriptionId;
    121     }
    122 
    123     public boolean isPrimary() {
    124         return mPrimary;
    125     }
    126 
    127     /**
    128      * Returns true if the volume is removable.
    129      *
    130      * @return is removable
    131      */
    132     public boolean isRemovable() {
    133         return mRemovable;
    134     }
    135 
    136     /**
    137      * Returns true if the volume is emulated.
    138      *
    139      * @return is removable
    140      */
    141     public boolean isEmulated() {
    142         return mEmulated;
    143     }
    144 
    145     /**
    146      * Returns the MTP storage ID for the volume.
    147      * this is also used for the storage_id column in the media provider.
    148      *
    149      * @return MTP storage ID
    150      */
    151     public int getStorageId() {
    152         return mStorageId;
    153     }
    154 
    155     /**
    156      * Do not call this unless you are MountService
    157      */
    158     public void setStorageId(int index) {
    159         // storage ID is 0x00010001 for primary storage,
    160         // then 0x00020001, 0x00030001, etc. for secondary storages
    161         mStorageId = ((index + 1) << 16) + 1;
    162     }
    163 
    164     /**
    165      * Number of megabytes of space to leave unallocated by MTP.
    166      * MTP will subtract this value from the free space it reports back
    167      * to the host via GetStorageInfo, and will not allow new files to
    168      * be added via MTP if there is less than this amount left free in the storage.
    169      * If MTP has dedicated storage this value should be zero, but if MTP is
    170      * sharing storage with the rest of the system, set this to a positive value
    171      * to ensure that MTP activity does not result in the storage being
    172      * too close to full.
    173      *
    174      * @return MTP reserve space
    175      */
    176     public int getMtpReserveSpace() {
    177         return mMtpReserveSpace;
    178     }
    179 
    180     /**
    181      * Returns true if this volume can be shared via USB mass storage.
    182      *
    183      * @return whether mass storage is allowed
    184      */
    185     public boolean allowMassStorage() {
    186         return mAllowMassStorage;
    187     }
    188 
    189     /**
    190      * Returns maximum file size for the volume, or zero if it is unbounded.
    191      *
    192      * @return maximum file size
    193      */
    194     public long getMaxFileSize() {
    195         return mMaxFileSize;
    196     }
    197 
    198     public UserHandle getOwner() {
    199         return mOwner;
    200     }
    201 
    202     public void setUuid(String uuid) {
    203         mUuid = uuid;
    204     }
    205 
    206     public String getUuid() {
    207         return mUuid;
    208     }
    209 
    210     /**
    211      * Parse and return volume UUID as FAT volume ID, or return -1 if unable to
    212      * parse or UUID is unknown.
    213      */
    214     public int getFatVolumeId() {
    215         if (mUuid == null || mUuid.length() != 9) {
    216             return -1;
    217         }
    218         try {
    219             return Integer.parseInt(mUuid.replace("-", ""), 16);
    220         } catch (NumberFormatException e) {
    221             return -1;
    222         }
    223     }
    224 
    225     public void setUserLabel(String userLabel) {
    226         mUserLabel = userLabel;
    227     }
    228 
    229     public String getUserLabel() {
    230         return mUserLabel;
    231     }
    232 
    233     public void setState(String state) {
    234         mState = state;
    235     }
    236 
    237     public String getState() {
    238         return mState;
    239     }
    240 
    241     @Override
    242     public boolean equals(Object obj) {
    243         if (obj instanceof StorageVolume && mPath != null) {
    244             StorageVolume volume = (StorageVolume)obj;
    245             return (mPath.equals(volume.mPath));
    246         }
    247         return false;
    248     }
    249 
    250     @Override
    251     public int hashCode() {
    252         return mPath.hashCode();
    253     }
    254 
    255     @Override
    256     public String toString() {
    257         final CharArrayWriter writer = new CharArrayWriter();
    258         dump(new IndentingPrintWriter(writer, "    ", 80));
    259         return writer.toString();
    260     }
    261 
    262     public void dump(IndentingPrintWriter pw) {
    263         pw.println("StorageVolume:");
    264         pw.increaseIndent();
    265         pw.printPair("mStorageId", mStorageId);
    266         pw.printPair("mPath", mPath);
    267         pw.printPair("mDescriptionId", mDescriptionId);
    268         pw.printPair("mPrimary", mPrimary);
    269         pw.printPair("mRemovable", mRemovable);
    270         pw.printPair("mEmulated", mEmulated);
    271         pw.printPair("mMtpReserveSpace", mMtpReserveSpace);
    272         pw.printPair("mAllowMassStorage", mAllowMassStorage);
    273         pw.printPair("mMaxFileSize", mMaxFileSize);
    274         pw.printPair("mOwner", mOwner);
    275         pw.printPair("mUuid", mUuid);
    276         pw.printPair("mUserLabel", mUserLabel);
    277         pw.printPair("mState", mState);
    278         pw.decreaseIndent();
    279     }
    280 
    281     public static final Creator<StorageVolume> CREATOR = new Creator<StorageVolume>() {
    282         @Override
    283         public StorageVolume createFromParcel(Parcel in) {
    284             return new StorageVolume(in);
    285         }
    286 
    287         @Override
    288         public StorageVolume[] newArray(int size) {
    289             return new StorageVolume[size];
    290         }
    291     };
    292 
    293     @Override
    294     public int describeContents() {
    295         return 0;
    296     }
    297 
    298     @Override
    299     public void writeToParcel(Parcel parcel, int flags) {
    300         parcel.writeInt(mStorageId);
    301         parcel.writeString(mPath.toString());
    302         parcel.writeInt(mDescriptionId);
    303         parcel.writeInt(mPrimary ? 1 : 0);
    304         parcel.writeInt(mRemovable ? 1 : 0);
    305         parcel.writeInt(mEmulated ? 1 : 0);
    306         parcel.writeInt(mMtpReserveSpace);
    307         parcel.writeInt(mAllowMassStorage ? 1 : 0);
    308         parcel.writeLong(mMaxFileSize);
    309         parcel.writeParcelable(mOwner, flags);
    310         parcel.writeString(mUuid);
    311         parcel.writeString(mUserLabel);
    312         parcel.writeString(mState);
    313     }
    314 }
    315