• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
StorageVolume(File path, int descriptionId, boolean primary, boolean removable, boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize, UserHandle owner)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 
StorageVolume(Parcel in)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 
fromTemplate(StorageVolume template, File path, UserHandle owner)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      */
getPath()92     public String getPath() {
93         return mPath.toString();
94     }
95 
getPathFile()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      */
getDescription(Context context)105     public String getDescription(Context context) {
106         return context.getResources().getString(mDescriptionId);
107     }
108 
getDescriptionId()109     public int getDescriptionId() {
110         return mDescriptionId;
111     }
112 
isPrimary()113     public boolean isPrimary() {
114         return mPrimary;
115     }
116 
117     /**
118      * Returns true if the volume is removable.
119      *
120      * @return is removable
121      */
isRemovable()122     public boolean isRemovable() {
123         return mRemovable;
124     }
125 
126     /**
127      * Returns true if the volume is emulated.
128      *
129      * @return is removable
130      */
isEmulated()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      */
getStorageId()141     public int getStorageId() {
142         return mStorageId;
143     }
144 
145     /**
146      * Do not call this unless you are MountService
147      */
setStorageId(int index)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      */
getMtpReserveSpace()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      */
allowMassStorage()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      */
getMaxFileSize()184     public long getMaxFileSize() {
185         return mMaxFileSize;
186     }
187 
getOwner()188     public UserHandle getOwner() {
189         return mOwner;
190     }
191 
192     @Override
equals(Object obj)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
hashCode()202     public int hashCode() {
203         return mPath.hashCode();
204     }
205 
206     @Override
toString()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
describeContents()236     public int describeContents() {
237         return 0;
238     }
239 
240     @Override
writeToParcel(Parcel parcel, int flags)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