blob: 7b0d2a4797024496317b31d038e6f0bd9f012810 [file] [log] [blame]
Mike Lockwood2f6a3882011-05-09 19:08:06 -07001/*
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
Felipe Leme04a5d402016-02-08 16:44:06 -080019import android.annotation.Nullable;
Fabrice Di Meglio13fe2a52012-05-18 18:08:58 -070020import android.content.Context;
Felipe Leme04a5d402016-02-08 16:44:06 -080021import android.content.Intent;
Jeff Sharkey48877892015-03-18 11:27:19 -070022import android.net.TrafficStats;
Felipe Leme04a5d402016-02-08 16:44:06 -080023import android.net.Uri;
24import android.os.Environment;
Mike Lockwood2f6a3882011-05-09 19:08:06 -070025import android.os.Parcel;
26import android.os.Parcelable;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070027import android.os.UserHandle;
Felipe Leme04a5d402016-02-08 16:44:06 -080028import android.provider.DocumentsContract;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070029
Jeff Sharkey5aca2b82013-10-16 16:21:54 -070030import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -070031import com.android.internal.util.Preconditions;
Jeff Sharkey5aca2b82013-10-16 16:21:54 -070032
33import java.io.CharArrayWriter;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070034import java.io.File;
Mike Lockwood2f6a3882011-05-09 19:08:06 -070035
36/**
Felipe Leme04a5d402016-02-08 16:44:06 -080037 * Information about a shared/external storage volume for a specific user.
Jeff Sharkeyb049e212012-09-07 23:16:01 -070038 *
Felipe Leme04a5d402016-02-08 16:44:06 -080039 * <p>
40 * A device always has one (and one only) primary storage volume, but it could have extra volumes,
41 * like SD cards and USB drives. This object represents the logical view of a storage
42 * volume for a specific user: different users might have different views for the same physical
43 * volume (for example, if the volume is a built-in emulated storage).
44 *
45 * <p>
46 * The storage volume is not necessarily mounted, applications should use {@link #getState()} to
47 * verify its state.
48 *
49 * <p>
50 * Applications willing to read or write to this storage volume needs to get a permission from the
51 * user first, which can be achieved in the following ways:
52 *
53 * <ul>
54 * <li>To get access to standard directories (like the {@link Environment#DIRECTORY_PICTURES}), they
55 * can use the {@link #createAccessIntent(String)}. This is the recommend way, since it provides a
56 * simpler API and narrows the access to the given directory (and its descendants).
Felipe Leme53fcc752016-02-17 14:45:52 -080057 * <li>To get access to any directory (and its descendants), they can use the Storage Acess
58 * Framework APIs (such as {@link Intent#ACTION_OPEN_DOCUMENT} and
59 * {@link Intent#ACTION_OPEN_DOCUMENT_TREE}, although these APIs do not guarantee the user will
60 * select this specific volume.
Felipe Leme04a5d402016-02-08 16:44:06 -080061 * <li>To get read and write access to the primary storage volume, applications can declare the
62 * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} and
63 * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions respectively, with the
64 * latter including the former. This approach is discouraged, since users may be hesitant to grant
65 * broad access to all files contained on a storage device.
66 * </ul>
67 *
Jeff Sharkeyc02bfae2016-03-27 15:06:53 -060068 * <p>It can be obtained through {@link StorageManager#getStorageVolumes()} and
69 * {@link StorageManager#getPrimaryStorageVolume()} and also as an extra in some broadcasts
Felipe Leme04a5d402016-02-08 16:44:06 -080070 * (see {@link #EXTRA_STORAGE_VOLUME}).
71 *
72 * <p>
73 * See {@link Environment#getExternalStorageDirectory()} for more info about shared/external
74 * storage semantics.
Mike Lockwood2f6a3882011-05-09 19:08:06 -070075 */
Felipe Leme04a5d402016-02-08 16:44:06 -080076// NOTE: This is a legacy specialization of VolumeInfo which describes the volume for a specific
77// user, but is now part of the public API.
Jeff Sharkey50d1c042016-02-29 16:34:46 -070078public final class StorageVolume implements Parcelable {
Mike Lockwood2f6a3882011-05-09 19:08:06 -070079
Jeff Sharkey48877892015-03-18 11:27:19 -070080 private final String mId;
81 private final int mStorageId;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070082 private final File mPath;
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -070083 private final String mDescription;
Jeff Sharkey9545dc022012-09-06 22:46:30 -070084 private final boolean mPrimary;
Mike Lockwood2f6a3882011-05-09 19:08:06 -070085 private final boolean mRemovable;
86 private final boolean mEmulated;
Jeff Sharkey48877892015-03-18 11:27:19 -070087 private final long mMtpReserveSize;
Mike Lockwood8e8b2802011-06-07 08:03:33 -070088 private final boolean mAllowMassStorage;
Mike Lockwood7a59dd22011-07-11 09:18:03 -040089 private final long mMaxFileSize;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070090 private final UserHandle mOwner;
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -070091 private final String mFsUuid;
Jeff Sharkey48877892015-03-18 11:27:19 -070092 private final String mState;
Jeff Sharkey5aca2b82013-10-16 16:21:54 -070093
Felipe Leme04a5d402016-02-08 16:44:06 -080094 /**
95 * Name of the {@link Parcelable} extra in the {@link Intent#ACTION_MEDIA_REMOVED},
96 * {@link Intent#ACTION_MEDIA_UNMOUNTED}, {@link Intent#ACTION_MEDIA_CHECKING},
97 * {@link Intent#ACTION_MEDIA_NOFS}, {@link Intent#ACTION_MEDIA_MOUNTED},
98 * {@link Intent#ACTION_MEDIA_SHARED}, {@link Intent#ACTION_MEDIA_BAD_REMOVAL},
99 * {@link Intent#ACTION_MEDIA_UNMOUNTABLE}, and {@link Intent#ACTION_MEDIA_EJECT} broadcast that
100 * contains a {@link StorageVolume}.
101 */
102 // Also sent on ACTION_MEDIA_UNSHARED, which is @hide
103 public static final String EXTRA_STORAGE_VOLUME = "android.os.storage.extra.STORAGE_VOLUME";
Mike Lockwooda5250c92011-05-23 13:44:04 -0400104
Felipe Leme34a9d522016-02-17 10:12:04 -0800105 /**
106 * Name of the String extra used by {@link #createAccessIntent(String) createAccessIntent}.
107 *
108 * @hide
109 */
110 public static final String EXTRA_DIRECTORY_NAME = "android.os.storage.extra.DIRECTORY_NAME";
111
112 /**
113 * Name of the intent used by {@link #createAccessIntent(String) createAccessIntent}.
114 */
115 private static final String ACTION_OPEN_EXTERNAL_DIRECTORY =
116 "android.os.storage.action.OPEN_EXTERNAL_DIRECTORY";
117
Felipe Leme04a5d402016-02-08 16:44:06 -0800118 /** {@hide} */
Jeff Sharkey5af1835d2015-07-07 17:26:59 -0700119 public static final int STORAGE_ID_INVALID = 0x00000000;
Felipe Leme04a5d402016-02-08 16:44:06 -0800120 /** {@hide} */
Jeff Sharkey5af1835d2015-07-07 17:26:59 -0700121 public static final int STORAGE_ID_PRIMARY = 0x00010001;
122
Felipe Leme04a5d402016-02-08 16:44:06 -0800123 /** {@hide} */
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700124 public StorageVolume(String id, int storageId, File path, String description, boolean primary,
Jeff Sharkey48877892015-03-18 11:27:19 -0700125 boolean removable, boolean emulated, long mtpReserveSize, boolean allowMassStorage,
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700126 long maxFileSize, UserHandle owner, String fsUuid, String state) {
127 mId = Preconditions.checkNotNull(id);
Jeff Sharkey48877892015-03-18 11:27:19 -0700128 mStorageId = storageId;
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700129 mPath = Preconditions.checkNotNull(path);
130 mDescription = Preconditions.checkNotNull(description);
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700131 mPrimary = primary;
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700132 mRemovable = removable;
133 mEmulated = emulated;
Jeff Sharkey48877892015-03-18 11:27:19 -0700134 mMtpReserveSize = mtpReserveSize;
Mike Lockwood8e8b2802011-06-07 08:03:33 -0700135 mAllowMassStorage = allowMassStorage;
Mike Lockwood7a59dd22011-07-11 09:18:03 -0400136 mMaxFileSize = maxFileSize;
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700137 mOwner = Preconditions.checkNotNull(owner);
138 mFsUuid = fsUuid;
139 mState = Preconditions.checkNotNull(state);
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700140 }
141
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700142 private StorageVolume(Parcel in) {
Jeff Sharkey48877892015-03-18 11:27:19 -0700143 mId = in.readString();
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700144 mStorageId = in.readInt();
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700145 mPath = new File(in.readString());
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700146 mDescription = in.readString();
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700147 mPrimary = in.readInt() != 0;
148 mRemovable = in.readInt() != 0;
149 mEmulated = in.readInt() != 0;
Jeff Sharkey48877892015-03-18 11:27:19 -0700150 mMtpReserveSize = in.readLong();
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700151 mAllowMassStorage = in.readInt() != 0;
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700152 mMaxFileSize = in.readLong();
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700153 mOwner = in.readParcelable(null);
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700154 mFsUuid = in.readString();
Jeff Sharkey1f706c62013-10-17 10:52:17 -0700155 mState = in.readString();
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700156 }
157
Felipe Leme04a5d402016-02-08 16:44:06 -0800158 /** {@hide} */
Jeff Sharkey48877892015-03-18 11:27:19 -0700159 public String getId() {
160 return mId;
Mike Lockwoodfbfe5552011-05-17 17:19:37 -0400161 }
162
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700163 /**
164 * Returns the mount path for the volume.
165 *
166 * @return the mount path
Felipe Leme04a5d402016-02-08 16:44:06 -0800167 * @hide
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700168 */
169 public String getPath() {
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700170 return mPath.toString();
171 }
172
Felipe Leme04a5d402016-02-08 16:44:06 -0800173 /** {@hide} */
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700174 public File getPathFile() {
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700175 return mPath;
176 }
177
178 /**
Felipe Leme04a5d402016-02-08 16:44:06 -0800179 * Returns a user-visible description of the volume.
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700180 *
181 * @return the volume description
182 */
Fabrice Di Meglio13fe2a52012-05-18 18:08:58 -0700183 public String getDescription(Context context) {
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700184 return mDescription;
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700185 }
186
Felipe Leme04a5d402016-02-08 16:44:06 -0800187 /**
188 * Returns true if the volume is the primary shared/external storage, which is the volume
189 * backed by {@link Environment#getExternalStorageDirectory()}.
190 */
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700191 public boolean isPrimary() {
192 return mPrimary;
193 }
194
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700195 /**
196 * Returns true if the volume is removable.
197 *
198 * @return is removable
199 */
200 public boolean isRemovable() {
201 return mRemovable;
202 }
203
204 /**
205 * Returns true if the volume is emulated.
206 *
207 * @return is removable
208 */
209 public boolean isEmulated() {
210 return mEmulated;
211 }
212
213 /**
Mike Lockwoodfbfe5552011-05-17 17:19:37 -0400214 * Returns the MTP storage ID for the volume.
215 * this is also used for the storage_id column in the media provider.
216 *
217 * @return MTP storage ID
Felipe Leme04a5d402016-02-08 16:44:06 -0800218 * @hide
Mike Lockwoodfbfe5552011-05-17 17:19:37 -0400219 */
220 public int getStorageId() {
221 return mStorageId;
222 }
223
224 /**
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700225 * Number of megabytes of space to leave unallocated by MTP.
226 * MTP will subtract this value from the free space it reports back
227 * to the host via GetStorageInfo, and will not allow new files to
228 * be added via MTP if there is less than this amount left free in the storage.
229 * If MTP has dedicated storage this value should be zero, but if MTP is
230 * sharing storage with the rest of the system, set this to a positive value
231 * to ensure that MTP activity does not result in the storage being
232 * too close to full.
233 *
234 * @return MTP reserve space
Felipe Leme04a5d402016-02-08 16:44:06 -0800235 * @hide
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700236 */
237 public int getMtpReserveSpace() {
Jeff Sharkey48877892015-03-18 11:27:19 -0700238 return (int) (mMtpReserveSize / TrafficStats.MB_IN_BYTES);
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700239 }
240
Mike Lockwood8e8b2802011-06-07 08:03:33 -0700241 /**
242 * Returns true if this volume can be shared via USB mass storage.
243 *
244 * @return whether mass storage is allowed
Felipe Leme04a5d402016-02-08 16:44:06 -0800245 * @hide
Mike Lockwood8e8b2802011-06-07 08:03:33 -0700246 */
247 public boolean allowMassStorage() {
248 return mAllowMassStorage;
249 }
250
Mike Lockwood7a59dd22011-07-11 09:18:03 -0400251 /**
252 * Returns maximum file size for the volume, or zero if it is unbounded.
253 *
254 * @return maximum file size
Felipe Leme04a5d402016-02-08 16:44:06 -0800255 * @hide
Mike Lockwood7a59dd22011-07-11 09:18:03 -0400256 */
257 public long getMaxFileSize() {
258 return mMaxFileSize;
259 }
260
Felipe Leme04a5d402016-02-08 16:44:06 -0800261 /** {@hide} */
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700262 public UserHandle getOwner() {
263 return mOwner;
264 }
265
Felipe Leme04a5d402016-02-08 16:44:06 -0800266 /**
267 * Gets the volume UUID, if any.
268 */
269 public @Nullable String getUuid() {
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700270 return mFsUuid;
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700271 }
272
273 /**
274 * Parse and return volume UUID as FAT volume ID, or return -1 if unable to
275 * parse or UUID is unknown.
Felipe Leme04a5d402016-02-08 16:44:06 -0800276 * @hide
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700277 */
278 public int getFatVolumeId() {
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700279 if (mFsUuid == null || mFsUuid.length() != 9) {
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700280 return -1;
281 }
282 try {
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700283 return (int) Long.parseLong(mFsUuid.replace("-", ""), 16);
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700284 } catch (NumberFormatException e) {
285 return -1;
286 }
287 }
288
Felipe Leme04a5d402016-02-08 16:44:06 -0800289 /** {@hide} */
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700290 public String getUserLabel() {
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700291 return mDescription;
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700292 }
293
Felipe Leme04a5d402016-02-08 16:44:06 -0800294 /**
295 * Returns the current state of the volume.
296 *
297 * @return one of {@link Environment#MEDIA_UNKNOWN}, {@link Environment#MEDIA_REMOVED},
298 * {@link Environment#MEDIA_UNMOUNTED}, {@link Environment#MEDIA_CHECKING},
299 * {@link Environment#MEDIA_NOFS}, {@link Environment#MEDIA_MOUNTED},
300 * {@link Environment#MEDIA_MOUNTED_READ_ONLY}, {@link Environment#MEDIA_SHARED},
301 * {@link Environment#MEDIA_BAD_REMOVAL}, or {@link Environment#MEDIA_UNMOUNTABLE}.
302 */
Jeff Sharkey1f706c62013-10-17 10:52:17 -0700303 public String getState() {
304 return mState;
305 }
306
Felipe Leme04a5d402016-02-08 16:44:06 -0800307 /**
Felipe Lemedb892b82016-03-17 18:56:20 -0700308 * Builds an intent to give access to a standard storage directory or entire volume after
309 * obtaining the user's approval.
Felipe Leme04a5d402016-02-08 16:44:06 -0800310 * <p>
311 * When invoked, the system will ask the user to grant access to the requested directory (and
312 * its descendants). The result of the request will be returned to the activity through the
313 * {@code onActivityResult} method.
314 * <p>
315 * To gain access to descendants (child, grandchild, etc) documents, use
316 * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)}, or
317 * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} with the returned URI.
Felipe Leme2ac87692016-03-29 19:06:02 -0700318 * <p>
319 * If your application only needs to store internal data, consider using
Felipe Leme04a5d402016-02-08 16:44:06 -0800320 * {@link Context#getExternalFilesDirs(String) Context.getExternalFilesDirs},
Felipe Leme2ac87692016-03-29 19:06:02 -0700321 * {@link Context#getExternalCacheDirs()}, or {@link Context#getExternalMediaDirs()}, which
322 * require no permissions to read or write.
323 * <p>
324 * Access to the entire volume is only available for non-primary volumes (for the primary
325 * volume, apps can use the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} and
326 * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions) and should be used
327 * with caution, since users are more likely to deny access when asked for entire volume access
328 * rather than specific directories.
Felipe Leme04a5d402016-02-08 16:44:06 -0800329 *
Felipe Leme2ac87692016-03-29 19:06:02 -0700330 * @param directoryName must be one of {@link Environment#DIRECTORY_MUSIC},
331 * {@link Environment#DIRECTORY_PODCASTS}, {@link Environment#DIRECTORY_RINGTONES},
332 * {@link Environment#DIRECTORY_ALARMS}, {@link Environment#DIRECTORY_NOTIFICATIONS},
333 * {@link Environment#DIRECTORY_PICTURES}, {@link Environment#DIRECTORY_MOVIES},
334 * {@link Environment#DIRECTORY_DOWNLOADS}, {@link Environment#DIRECTORY_DCIM}, or
335 * {@link Environment#DIRECTORY_DOCUMENTS}, or {code null} to request access to the
336 * entire volume.
337 * @return intent to request access, or {@code null} if the requested directory is invalid for
338 * that volume.
Felipe Leme04a5d402016-02-08 16:44:06 -0800339 * @see DocumentsContract
340 */
Felipe Leme2ac87692016-03-29 19:06:02 -0700341 public @Nullable Intent createAccessIntent(String directoryName) {
342 if ((isPrimary() && directoryName == null) ||
343 (directoryName != null && !Environment.isStandardDirectory(directoryName))) {
344 return null;
345 }
Felipe Leme34a9d522016-02-17 10:12:04 -0800346 final Intent intent = new Intent(ACTION_OPEN_EXTERNAL_DIRECTORY);
347 intent.putExtra(EXTRA_STORAGE_VOLUME, this);
348 intent.putExtra(EXTRA_DIRECTORY_NAME, directoryName);
Felipe Leme04a5d402016-02-08 16:44:06 -0800349 return intent;
350 }
351
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700352 @Override
353 public boolean equals(Object obj) {
354 if (obj instanceof StorageVolume && mPath != null) {
355 StorageVolume volume = (StorageVolume)obj;
356 return (mPath.equals(volume.mPath));
357 }
358 return false;
359 }
360
361 @Override
362 public int hashCode() {
363 return mPath.hashCode();
364 }
365
366 @Override
367 public String toString() {
Felipe Leme04a5d402016-02-08 16:44:06 -0800368 final StringBuilder buffer = new StringBuilder("StorageVolume: ").append(mDescription);
369 if (mFsUuid != null) {
370 buffer.append(" (").append(mFsUuid).append(")");
371 }
372 return buffer.toString();
373 }
374
375 /** {@hide} */
376 // TODO(b/26742218): find out where toString() is called internally and replace these calls by
377 // dump().
378 public String dump() {
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700379 final CharArrayWriter writer = new CharArrayWriter();
380 dump(new IndentingPrintWriter(writer, " ", 80));
381 return writer.toString();
382 }
383
Felipe Leme04a5d402016-02-08 16:44:06 -0800384 /** {@hide} */
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700385 public void dump(IndentingPrintWriter pw) {
386 pw.println("StorageVolume:");
387 pw.increaseIndent();
Jeff Sharkey48877892015-03-18 11:27:19 -0700388 pw.printPair("mId", mId);
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700389 pw.printPair("mStorageId", mStorageId);
390 pw.printPair("mPath", mPath);
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700391 pw.printPair("mDescription", mDescription);
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700392 pw.printPair("mPrimary", mPrimary);
393 pw.printPair("mRemovable", mRemovable);
394 pw.printPair("mEmulated", mEmulated);
Jeff Sharkey48877892015-03-18 11:27:19 -0700395 pw.printPair("mMtpReserveSize", mMtpReserveSize);
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700396 pw.printPair("mAllowMassStorage", mAllowMassStorage);
397 pw.printPair("mMaxFileSize", mMaxFileSize);
398 pw.printPair("mOwner", mOwner);
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700399 pw.printPair("mFsUuid", mFsUuid);
Jeff Sharkey1f706c62013-10-17 10:52:17 -0700400 pw.printPair("mState", mState);
Jeff Sharkey5aca2b82013-10-16 16:21:54 -0700401 pw.decreaseIndent();
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700402 }
403
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700404 public static final Creator<StorageVolume> CREATOR = new Creator<StorageVolume>() {
405 @Override
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700406 public StorageVolume createFromParcel(Parcel in) {
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700407 return new StorageVolume(in);
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700408 }
409
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700410 @Override
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700411 public StorageVolume[] newArray(int size) {
412 return new StorageVolume[size];
413 }
414 };
415
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700416 @Override
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700417 public int describeContents() {
418 return 0;
419 }
420
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700421 @Override
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700422 public void writeToParcel(Parcel parcel, int flags) {
Jeff Sharkey48877892015-03-18 11:27:19 -0700423 parcel.writeString(mId);
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700424 parcel.writeInt(mStorageId);
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700425 parcel.writeString(mPath.toString());
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700426 parcel.writeString(mDescription);
Jeff Sharkey9545dc022012-09-06 22:46:30 -0700427 parcel.writeInt(mPrimary ? 1 : 0);
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700428 parcel.writeInt(mRemovable ? 1 : 0);
429 parcel.writeInt(mEmulated ? 1 : 0);
Jeff Sharkey48877892015-03-18 11:27:19 -0700430 parcel.writeLong(mMtpReserveSize);
Mike Lockwood8e8b2802011-06-07 08:03:33 -0700431 parcel.writeInt(mAllowMassStorage ? 1 : 0);
Mike Lockwood7a59dd22011-07-11 09:18:03 -0400432 parcel.writeLong(mMaxFileSize);
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700433 parcel.writeParcelable(mOwner, flags);
Jeff Sharkey1b8ef7e2015-04-03 17:14:45 -0700434 parcel.writeString(mFsUuid);
Jeff Sharkey1f706c62013-10-17 10:52:17 -0700435 parcel.writeString(mState);
Mike Lockwood2f6a3882011-05-09 19:08:06 -0700436 }
437}