StorageVolume.java revision 5af1835d678031d4a6615edc96ba58c82304b31d
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;
26import com.android.internal.util.Preconditions;
27
28import java.io.CharArrayWriter;
29import java.io.File;
30
31/**
32 * Information about a storage volume that may be mounted. This is a legacy
33 * specialization of {@link VolumeInfo} which describes the volume for a
34 * specific user.
35 * <p>
36 * This class may be deprecated in the future.
37 *
38 * @hide
39 */
40public class StorageVolume implements Parcelable {
41
42    private final String mId;
43    private final int mStorageId;
44    private final File mPath;
45    private final String mDescription;
46    private final boolean mPrimary;
47    private final boolean mRemovable;
48    private final boolean mEmulated;
49    private final long mMtpReserveSize;
50    private final boolean mAllowMassStorage;
51    private final long mMaxFileSize;
52    private final UserHandle mOwner;
53    private final String mFsUuid;
54    private final 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 static final int STORAGE_ID_INVALID = 0x00000000;
62    public static final int STORAGE_ID_PRIMARY = 0x00010001;
63
64    public StorageVolume(String id, int storageId, File path, String description, boolean primary,
65            boolean removable, boolean emulated, long mtpReserveSize, boolean allowMassStorage,
66            long maxFileSize, UserHandle owner, String fsUuid, String state) {
67        mId = Preconditions.checkNotNull(id);
68        mStorageId = storageId;
69        mPath = Preconditions.checkNotNull(path);
70        mDescription = Preconditions.checkNotNull(description);
71        mPrimary = primary;
72        mRemovable = removable;
73        mEmulated = emulated;
74        mMtpReserveSize = mtpReserveSize;
75        mAllowMassStorage = allowMassStorage;
76        mMaxFileSize = maxFileSize;
77        mOwner = Preconditions.checkNotNull(owner);
78        mFsUuid = fsUuid;
79        mState = Preconditions.checkNotNull(state);
80    }
81
82    private StorageVolume(Parcel in) {
83        mId = in.readString();
84        mStorageId = in.readInt();
85        mPath = new File(in.readString());
86        mDescription = in.readString();
87        mPrimary = in.readInt() != 0;
88        mRemovable = in.readInt() != 0;
89        mEmulated = in.readInt() != 0;
90        mMtpReserveSize = in.readLong();
91        mAllowMassStorage = in.readInt() != 0;
92        mMaxFileSize = in.readLong();
93        mOwner = in.readParcelable(null);
94        mFsUuid = 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 mDescription;
122    }
123
124    public boolean isPrimary() {
125        return mPrimary;
126    }
127
128    /**
129     * Returns true if the volume is removable.
130     *
131     * @return is removable
132     */
133    public boolean isRemovable() {
134        return mRemovable;
135    }
136
137    /**
138     * Returns true if the volume is emulated.
139     *
140     * @return is removable
141     */
142    public boolean isEmulated() {
143        return mEmulated;
144    }
145
146    /**
147     * Returns the MTP storage ID for the volume.
148     * this is also used for the storage_id column in the media provider.
149     *
150     * @return MTP storage ID
151     */
152    public int getStorageId() {
153        return mStorageId;
154    }
155
156    /**
157     * Number of megabytes of space to leave unallocated by MTP.
158     * MTP will subtract this value from the free space it reports back
159     * to the host via GetStorageInfo, and will not allow new files to
160     * be added via MTP if there is less than this amount left free in the storage.
161     * If MTP has dedicated storage this value should be zero, but if MTP is
162     * sharing storage with the rest of the system, set this to a positive value
163     * to ensure that MTP activity does not result in the storage being
164     * too close to full.
165     *
166     * @return MTP reserve space
167     */
168    public int getMtpReserveSpace() {
169        return (int) (mMtpReserveSize / TrafficStats.MB_IN_BYTES);
170    }
171
172    /**
173     * Returns true if this volume can be shared via USB mass storage.
174     *
175     * @return whether mass storage is allowed
176     */
177    public boolean allowMassStorage() {
178        return mAllowMassStorage;
179    }
180
181    /**
182     * Returns maximum file size for the volume, or zero if it is unbounded.
183     *
184     * @return maximum file size
185     */
186    public long getMaxFileSize() {
187        return mMaxFileSize;
188    }
189
190    public UserHandle getOwner() {
191        return mOwner;
192    }
193
194    public String getUuid() {
195        return mFsUuid;
196    }
197
198    /**
199     * Parse and return volume UUID as FAT volume ID, or return -1 if unable to
200     * parse or UUID is unknown.
201     */
202    public int getFatVolumeId() {
203        if (mFsUuid == null || mFsUuid.length() != 9) {
204            return -1;
205        }
206        try {
207            return (int) Long.parseLong(mFsUuid.replace("-", ""), 16);
208        } catch (NumberFormatException e) {
209            return -1;
210        }
211    }
212
213    public String getUserLabel() {
214        return mDescription;
215    }
216
217    public String getState() {
218        return mState;
219    }
220
221    @Override
222    public boolean equals(Object obj) {
223        if (obj instanceof StorageVolume && mPath != null) {
224            StorageVolume volume = (StorageVolume)obj;
225            return (mPath.equals(volume.mPath));
226        }
227        return false;
228    }
229
230    @Override
231    public int hashCode() {
232        return mPath.hashCode();
233    }
234
235    @Override
236    public String toString() {
237        final CharArrayWriter writer = new CharArrayWriter();
238        dump(new IndentingPrintWriter(writer, "    ", 80));
239        return writer.toString();
240    }
241
242    public void dump(IndentingPrintWriter pw) {
243        pw.println("StorageVolume:");
244        pw.increaseIndent();
245        pw.printPair("mId", mId);
246        pw.printPair("mStorageId", mStorageId);
247        pw.printPair("mPath", mPath);
248        pw.printPair("mDescription", mDescription);
249        pw.printPair("mPrimary", mPrimary);
250        pw.printPair("mRemovable", mRemovable);
251        pw.printPair("mEmulated", mEmulated);
252        pw.printPair("mMtpReserveSize", mMtpReserveSize);
253        pw.printPair("mAllowMassStorage", mAllowMassStorage);
254        pw.printPair("mMaxFileSize", mMaxFileSize);
255        pw.printPair("mOwner", mOwner);
256        pw.printPair("mFsUuid", mFsUuid);
257        pw.printPair("mState", mState);
258        pw.decreaseIndent();
259    }
260
261    public static final Creator<StorageVolume> CREATOR = new Creator<StorageVolume>() {
262        @Override
263        public StorageVolume createFromParcel(Parcel in) {
264            return new StorageVolume(in);
265        }
266
267        @Override
268        public StorageVolume[] newArray(int size) {
269            return new StorageVolume[size];
270        }
271    };
272
273    @Override
274    public int describeContents() {
275        return 0;
276    }
277
278    @Override
279    public void writeToParcel(Parcel parcel, int flags) {
280        parcel.writeString(mId);
281        parcel.writeInt(mStorageId);
282        parcel.writeString(mPath.toString());
283        parcel.writeString(mDescription);
284        parcel.writeInt(mPrimary ? 1 : 0);
285        parcel.writeInt(mRemovable ? 1 : 0);
286        parcel.writeInt(mEmulated ? 1 : 0);
287        parcel.writeLong(mMtpReserveSize);
288        parcel.writeInt(mAllowMassStorage ? 1 : 0);
289        parcel.writeLong(mMaxFileSize);
290        parcel.writeParcelable(mOwner, flags);
291        parcel.writeString(mFsUuid);
292        parcel.writeString(mState);
293    }
294}
295