12f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood/* 22f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * Copyright (C) 2011 The Android Open Source Project 32f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 42f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 52f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * you may not use this file except in compliance with the License. 62f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * You may obtain a copy of the License at 72f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 82f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 92f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 102f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * Unless required by applicable law or agreed to in writing, software 112f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 122f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * See the License for the specific language governing permissions and 142f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * limitations under the License. 152f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood */ 162f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 172f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwoodpackage android.os.storage; 182f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 1904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Lemeimport android.annotation.Nullable; 2013fe2a5330a5df662d7b1b136e7b08fe34c94a42Fabrice Di Meglioimport android.content.Context; 2104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Lemeimport android.content.Intent; 224887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkeyimport android.net.TrafficStats; 2304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Lemeimport android.net.Uri; 2404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Lemeimport android.os.Environment; 252f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwoodimport android.os.Parcel; 262f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwoodimport android.os.Parcelable; 27b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkeyimport android.os.UserHandle; 2804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Lemeimport android.provider.DocumentsContract; 29b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey 305aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkeyimport com.android.internal.util.IndentingPrintWriter; 311b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkeyimport com.android.internal.util.Preconditions; 325aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey 335aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkeyimport java.io.CharArrayWriter; 34b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkeyimport java.io.File; 352f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 362f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood/** 3704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * Information about a shared/external storage volume for a specific user. 3804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * 3904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <p> 4004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * A device always has one (and one only) primary storage volume, but it could have extra volumes, 4104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * like SD cards and USB drives. This object represents the logical view of a storage 4204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * volume for a specific user: different users might have different views for the same physical 4304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * volume (for example, if the volume is a built-in emulated storage). 4404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * 451b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey * <p> 4604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * The storage volume is not necessarily mounted, applications should use {@link #getState()} to 4704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * verify its state. 4804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * 4904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <p> 5004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * Applications willing to read or write to this storage volume needs to get a permission from the 5104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * user first, which can be achieved in the following ways: 5204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * 5304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <ul> 5404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <li>To get access to standard directories (like the {@link Environment#DIRECTORY_PICTURES}), they 5504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * can use the {@link #createAccessIntent(String)}. This is the recommend way, since it provides a 5604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * simpler API and narrows the access to the given directory (and its descendants). 5753fcc756d06ed382e7b02b266631f7848d1b9c4fFelipe Leme * <li>To get access to any directory (and its descendants), they can use the Storage Acess 5853fcc756d06ed382e7b02b266631f7848d1b9c4fFelipe Leme * Framework APIs (such as {@link Intent#ACTION_OPEN_DOCUMENT} and 5953fcc756d06ed382e7b02b266631f7848d1b9c4fFelipe Leme * {@link Intent#ACTION_OPEN_DOCUMENT_TREE}, although these APIs do not guarantee the user will 6053fcc756d06ed382e7b02b266631f7848d1b9c4fFelipe Leme * select this specific volume. 6104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <li>To get read and write access to the primary storage volume, applications can declare the 6204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} and 6304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions respectively, with the 6404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * latter including the former. This approach is discouraged, since users may be hesitant to grant 6504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * broad access to all files contained on a storage device. 6604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * </ul> 6704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * 68c02bfae73e139f2a1c56cc6b051bfc7877b8cf1dJeff Sharkey * <p>It can be obtained through {@link StorageManager#getStorageVolumes()} and 69c02bfae73e139f2a1c56cc6b051bfc7877b8cf1dJeff Sharkey * {@link StorageManager#getPrimaryStorageVolume()} and also as an extra in some broadcasts 7004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * (see {@link #EXTRA_STORAGE_VOLUME}). 71b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey * 7204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <p> 7304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * See {@link Environment#getExternalStorageDirectory()} for more info about shared/external 7404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * storage semantics. 752f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood */ 7604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme// NOTE: This is a legacy specialization of VolumeInfo which describes the volume for a specific 7704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme// user, but is now part of the public API. 7850d1c044b5ce4b6fef532dc6e083cef903f554b2Jeff Sharkeypublic final class StorageVolume implements Parcelable { 792f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 804887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey private final String mId; 814887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey private final int mStorageId; 82b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey private final File mPath; 831b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey private final String mDescription; 849545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey private final boolean mPrimary; 852f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood private final boolean mRemovable; 862f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood private final boolean mEmulated; 874887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey private final long mMtpReserveSize; 888e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood private final boolean mAllowMassStorage; 897a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood private final long mMaxFileSize; 90b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey private final UserHandle mOwner; 911b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey private final String mFsUuid; 924887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey private final String mState; 935aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey 9404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** 9504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * Name of the {@link Parcelable} extra in the {@link Intent#ACTION_MEDIA_REMOVED}, 9604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Intent#ACTION_MEDIA_UNMOUNTED}, {@link Intent#ACTION_MEDIA_CHECKING}, 9704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Intent#ACTION_MEDIA_NOFS}, {@link Intent#ACTION_MEDIA_MOUNTED}, 9804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Intent#ACTION_MEDIA_SHARED}, {@link Intent#ACTION_MEDIA_BAD_REMOVAL}, 9904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Intent#ACTION_MEDIA_UNMOUNTABLE}, and {@link Intent#ACTION_MEDIA_EJECT} broadcast that 10004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * contains a {@link StorageVolume}. 10104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme */ 10204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme // Also sent on ACTION_MEDIA_UNSHARED, which is @hide 10304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme public static final String EXTRA_STORAGE_VOLUME = "android.os.storage.extra.STORAGE_VOLUME"; 104a5250c93928e256738125b265e10c96c3575597eMike Lockwood 10534a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme /** 10634a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme * Name of the String extra used by {@link #createAccessIntent(String) createAccessIntent}. 10734a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme * 10834a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme * @hide 10934a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme */ 11034a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme public static final String EXTRA_DIRECTORY_NAME = "android.os.storage.extra.DIRECTORY_NAME"; 11134a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme 11234a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme /** 11334a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme * Name of the intent used by {@link #createAccessIntent(String) createAccessIntent}. 11434a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme */ 11534a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme private static final String ACTION_OPEN_EXTERNAL_DIRECTORY = 11634a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme "android.os.storage.action.OPEN_EXTERNAL_DIRECTORY"; 11734a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme 11804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 1195af1835d678031d4a6615edc96ba58c82304b31dJeff Sharkey public static final int STORAGE_ID_INVALID = 0x00000000; 12004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 1215af1835d678031d4a6615edc96ba58c82304b31dJeff Sharkey public static final int STORAGE_ID_PRIMARY = 0x00010001; 1225af1835d678031d4a6615edc96ba58c82304b31dJeff Sharkey 12304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 1241b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey public StorageVolume(String id, int storageId, File path, String description, boolean primary, 1254887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey boolean removable, boolean emulated, long mtpReserveSize, boolean allowMassStorage, 1261b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey long maxFileSize, UserHandle owner, String fsUuid, String state) { 1271b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mId = Preconditions.checkNotNull(id); 1284887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey mStorageId = storageId; 1291b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mPath = Preconditions.checkNotNull(path); 1301b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mDescription = Preconditions.checkNotNull(description); 1319545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey mPrimary = primary; 1322f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood mRemovable = removable; 1332f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood mEmulated = emulated; 1344887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey mMtpReserveSize = mtpReserveSize; 1358e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood mAllowMassStorage = allowMassStorage; 1367a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood mMaxFileSize = maxFileSize; 1371b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mOwner = Preconditions.checkNotNull(owner); 1381b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mFsUuid = fsUuid; 1391b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mState = Preconditions.checkNotNull(state); 1402f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 1412f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 1429545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey private StorageVolume(Parcel in) { 1434887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey mId = in.readString(); 1449545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey mStorageId = in.readInt(); 145b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey mPath = new File(in.readString()); 1461b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mDescription = in.readString(); 147b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey mPrimary = in.readInt() != 0; 148b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey mRemovable = in.readInt() != 0; 149b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey mEmulated = in.readInt() != 0; 1504887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey mMtpReserveSize = in.readLong(); 151b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey mAllowMassStorage = in.readInt() != 0; 1529545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey mMaxFileSize = in.readLong(); 153b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey mOwner = in.readParcelable(null); 1541b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey mFsUuid = in.readString(); 1551f706c6cd1cb841adadc2babc57a34e5728983ecJeff Sharkey mState = in.readString(); 156b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey } 157b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey 15804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 1594887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey public String getId() { 1604887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey return mId; 161fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood } 162fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood 1632f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood /** 1642f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * Returns the mount path for the volume. 1652f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 1662f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * @return the mount path 16704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @hide 1682f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood */ 1692f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public String getPath() { 170b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey return mPath.toString(); 171b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey } 172b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey 17304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 174b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey public File getPathFile() { 1752f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return mPath; 1762f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 1772f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 1782f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood /** 17904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * Returns a user-visible description of the volume. 1802f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 1812f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * @return the volume description 1822f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood */ 18313fe2a5330a5df662d7b1b136e7b08fe34c94a42Fabrice Di Meglio public String getDescription(Context context) { 1841b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey return mDescription; 1852f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 1862f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 18704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** 18804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * Returns true if the volume is the primary shared/external storage, which is the volume 18904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * backed by {@link Environment#getExternalStorageDirectory()}. 19004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme */ 1919545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey public boolean isPrimary() { 1929545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey return mPrimary; 1939545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey } 1949545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey 1952f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood /** 1962f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * Returns true if the volume is removable. 1972f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 1982f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * @return is removable 1992f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood */ 2002f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public boolean isRemovable() { 2012f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return mRemovable; 2022f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 2032f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 2042f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood /** 2052f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * Returns true if the volume is emulated. 2062f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 2072f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * @return is removable 2082f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood */ 2092f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public boolean isEmulated() { 2102f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return mEmulated; 2112f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 2122f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 2132f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood /** 214fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood * Returns the MTP storage ID for the volume. 215fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood * this is also used for the storage_id column in the media provider. 216fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood * 217fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood * @return MTP storage ID 21804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @hide 219fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood */ 220fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood public int getStorageId() { 221fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood return mStorageId; 222fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood } 223fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood 224fbfe55512596fd00c1fb51caa851e17dae60fd43Mike Lockwood /** 2252f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * Number of megabytes of space to leave unallocated by MTP. 2262f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * MTP will subtract this value from the free space it reports back 2272f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * to the host via GetStorageInfo, and will not allow new files to 2282f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * be added via MTP if there is less than this amount left free in the storage. 2292f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * If MTP has dedicated storage this value should be zero, but if MTP is 2302f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * sharing storage with the rest of the system, set this to a positive value 2312f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * to ensure that MTP activity does not result in the storage being 2322f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * too close to full. 2332f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * 2342f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood * @return MTP reserve space 23504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @hide 2362f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood */ 2372f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public int getMtpReserveSpace() { 2384887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey return (int) (mMtpReserveSize / TrafficStats.MB_IN_BYTES); 2392f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 2402f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 2418e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood /** 2428e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood * Returns true if this volume can be shared via USB mass storage. 2438e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood * 2448e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood * @return whether mass storage is allowed 24504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @hide 2468e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood */ 2478e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood public boolean allowMassStorage() { 2488e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood return mAllowMassStorage; 2498e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood } 2508e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood 2517a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood /** 2527a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood * Returns maximum file size for the volume, or zero if it is unbounded. 2537a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood * 2547a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood * @return maximum file size 25504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @hide 2567a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood */ 2577a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood public long getMaxFileSize() { 2587a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood return mMaxFileSize; 2597a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood } 2607a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood 26104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 262b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey public UserHandle getOwner() { 263b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey return mOwner; 264b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey } 265b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey 26604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** 26704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * Gets the volume UUID, if any. 26804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme */ 26904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme public @Nullable String getUuid() { 2701b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey return mFsUuid; 2715aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey } 2725aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey 2735aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey /** 2745aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey * Parse and return volume UUID as FAT volume ID, or return -1 if unable to 2755aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey * parse or UUID is unknown. 27604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @hide 2775aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey */ 2785aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey public int getFatVolumeId() { 2791b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey if (mFsUuid == null || mFsUuid.length() != 9) { 2805aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey return -1; 2815aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey } 2825aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey try { 2831b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey return (int) Long.parseLong(mFsUuid.replace("-", ""), 16); 2845aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey } catch (NumberFormatException e) { 2855aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey return -1; 2865aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey } 2875aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey } 2885aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey 28904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 2905aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey public String getUserLabel() { 2911b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey return mDescription; 2925aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey } 2935aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey 29404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** 29504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * Returns the current state of the volume. 29604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * 29704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @return one of {@link Environment#MEDIA_UNKNOWN}, {@link Environment#MEDIA_REMOVED}, 29804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Environment#MEDIA_UNMOUNTED}, {@link Environment#MEDIA_CHECKING}, 29904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Environment#MEDIA_NOFS}, {@link Environment#MEDIA_MOUNTED}, 30004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Environment#MEDIA_MOUNTED_READ_ONLY}, {@link Environment#MEDIA_SHARED}, 30104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Environment#MEDIA_BAD_REMOVAL}, or {@link Environment#MEDIA_UNMOUNTABLE}. 30204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme */ 3031f706c6cd1cb841adadc2babc57a34e5728983ecJeff Sharkey public String getState() { 3041f706c6cd1cb841adadc2babc57a34e5728983ecJeff Sharkey return mState; 3051f706c6cd1cb841adadc2babc57a34e5728983ecJeff Sharkey } 3061f706c6cd1cb841adadc2babc57a34e5728983ecJeff Sharkey 30704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** 308db892b84e513f174d29f67d293435407a0ac7c6cFelipe Leme * Builds an intent to give access to a standard storage directory or entire volume after 309db892b84e513f174d29f67d293435407a0ac7c6cFelipe Leme * obtaining the user's approval. 31004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <p> 31104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * When invoked, the system will ask the user to grant access to the requested directory (and 31204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * its descendants). The result of the request will be returned to the activity through the 31304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@code onActivityResult} method. 31404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * <p> 31504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * To gain access to descendants (child, grandchild, etc) documents, use 31604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)}, or 31704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} with the returned URI. 3182ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * <p> 3192ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * If your application only needs to store internal data, consider using 32004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * {@link Context#getExternalFilesDirs(String) Context.getExternalFilesDirs}, 3212ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * {@link Context#getExternalCacheDirs()}, or {@link Context#getExternalMediaDirs()}, which 3222ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * require no permissions to read or write. 3232ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * <p> 3242ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * Access to the entire volume is only available for non-primary volumes (for the primary 3252ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * volume, apps can use the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} and 3262ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions) and should be used 3272ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * with caution, since users are more likely to deny access when asked for entire volume access 3282ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * rather than specific directories. 32904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * 3302ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * @param directoryName must be one of {@link Environment#DIRECTORY_MUSIC}, 3312ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * {@link Environment#DIRECTORY_PODCASTS}, {@link Environment#DIRECTORY_RINGTONES}, 3322ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * {@link Environment#DIRECTORY_ALARMS}, {@link Environment#DIRECTORY_NOTIFICATIONS}, 3332ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * {@link Environment#DIRECTORY_PICTURES}, {@link Environment#DIRECTORY_MOVIES}, 3342ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * {@link Environment#DIRECTORY_DOWNLOADS}, {@link Environment#DIRECTORY_DCIM}, or 3352ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * {@link Environment#DIRECTORY_DOCUMENTS}, or {code null} to request access to the 3362ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * entire volume. 3372ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * @return intent to request access, or {@code null} if the requested directory is invalid for 3382ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme * that volume. 33904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme * @see DocumentsContract 34004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme */ 3412ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme public @Nullable Intent createAccessIntent(String directoryName) { 3422ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme if ((isPrimary() && directoryName == null) || 3432ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme (directoryName != null && !Environment.isStandardDirectory(directoryName))) { 3442ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme return null; 3452ac876945bfb388fed8b796c6d8c8e7f2e97f0d4Felipe Leme } 34634a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme final Intent intent = new Intent(ACTION_OPEN_EXTERNAL_DIRECTORY); 34734a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme intent.putExtra(EXTRA_STORAGE_VOLUME, this); 34834a9d5271915fb82c22811e6d17691a34b6c52c1Felipe Leme intent.putExtra(EXTRA_DIRECTORY_NAME, directoryName); 34904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme return intent; 35004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme } 35104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme 3522f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood @Override 3532f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public boolean equals(Object obj) { 3542f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood if (obj instanceof StorageVolume && mPath != null) { 3552f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood StorageVolume volume = (StorageVolume)obj; 3562f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return (mPath.equals(volume.mPath)); 3572f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 3582f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return false; 3592f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 3602f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 3612f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood @Override 3622f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public int hashCode() { 3632f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return mPath.hashCode(); 3642f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 3652f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 3662f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood @Override 3672f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public String toString() { 36804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme final StringBuilder buffer = new StringBuilder("StorageVolume: ").append(mDescription); 36904a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme if (mFsUuid != null) { 37004a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme buffer.append(" (").append(mFsUuid).append(")"); 37104a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme } 37204a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme return buffer.toString(); 37304a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme } 37404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme 37504a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 37604a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme // TODO(b/26742218): find out where toString() is called internally and replace these calls by 37704a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme // dump(). 37804a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme public String dump() { 3795aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey final CharArrayWriter writer = new CharArrayWriter(); 3805aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey dump(new IndentingPrintWriter(writer, " ", 80)); 3815aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey return writer.toString(); 3825aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey } 3835aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey 38404a5d40cf35fb2c2fca2c1bfd573e5916d804ef6Felipe Leme /** {@hide} */ 3855aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey public void dump(IndentingPrintWriter pw) { 3865aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.println("StorageVolume:"); 3875aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.increaseIndent(); 3884887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey pw.printPair("mId", mId); 3895aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mStorageId", mStorageId); 3905aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mPath", mPath); 3911b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey pw.printPair("mDescription", mDescription); 3925aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mPrimary", mPrimary); 3935aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mRemovable", mRemovable); 3945aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mEmulated", mEmulated); 3954887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey pw.printPair("mMtpReserveSize", mMtpReserveSize); 3965aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mAllowMassStorage", mAllowMassStorage); 3975aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mMaxFileSize", mMaxFileSize); 3985aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.printPair("mOwner", mOwner); 3991b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey pw.printPair("mFsUuid", mFsUuid); 4001f706c6cd1cb841adadc2babc57a34e5728983ecJeff Sharkey pw.printPair("mState", mState); 4015aca2b8dc4f4ff2d466a64587d06666c7bbd9749Jeff Sharkey pw.decreaseIndent(); 4022f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 4032f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 4049545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey public static final Creator<StorageVolume> CREATOR = new Creator<StorageVolume>() { 4059545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey @Override 4062f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public StorageVolume createFromParcel(Parcel in) { 4079545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey return new StorageVolume(in); 4082f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 4092f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 4109545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey @Override 4112f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public StorageVolume[] newArray(int size) { 4122f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return new StorageVolume[size]; 4132f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 4142f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood }; 4152f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 4169545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey @Override 4172f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public int describeContents() { 4182f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood return 0; 4192f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 4202f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood 4219545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey @Override 4222f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood public void writeToParcel(Parcel parcel, int flags) { 4234887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey parcel.writeString(mId); 4249545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey parcel.writeInt(mStorageId); 425b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey parcel.writeString(mPath.toString()); 4261b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey parcel.writeString(mDescription); 4279545dc020ea11649d70dcbe911a8e82a3254a4eaJeff Sharkey parcel.writeInt(mPrimary ? 1 : 0); 4282f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood parcel.writeInt(mRemovable ? 1 : 0); 4292f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood parcel.writeInt(mEmulated ? 1 : 0); 4304887789e44cdb16b042a35e8ec03983213e88ac6Jeff Sharkey parcel.writeLong(mMtpReserveSize); 4318e8b280bd19fa6cb69bb19e1d90cf03a47ba2d72Mike Lockwood parcel.writeInt(mAllowMassStorage ? 1 : 0); 4327a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood parcel.writeLong(mMaxFileSize); 433b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey parcel.writeParcelable(mOwner, flags); 4341b8ef7e3165ff9aa52a4905dafc8d0f83e7403f9Jeff Sharkey parcel.writeString(mFsUuid); 4351f706c6cd1cb841adadc2babc57a34e5728983ecJeff Sharkey parcel.writeString(mState); 4362f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood } 4372f6a3885533a52758c2cd4f81f6123a712be8ae6Mike Lockwood} 438