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