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.net.TrafficStats; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.os.UserHandle; 24 25 import com.android.internal.util.IndentingPrintWriter; 26 import com.android.internal.util.Preconditions; 27 28 import java.io.CharArrayWriter; 29 import 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 */ 40 public 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 StorageVolume(String id, int storageId, File path, String description, boolean primary, boolean removable, boolean emulated, long mtpReserveSize, boolean allowMassStorage, long maxFileSize, UserHandle owner, String fsUuid, String state)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 StorageVolume(Parcel in)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 getId()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 */ getPath()107 public String getPath() { 108 return mPath.toString(); 109 } 110 getPathFile()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 */ getDescription(Context context)120 public String getDescription(Context context) { 121 return mDescription; 122 } 123 isPrimary()124 public boolean isPrimary() { 125 return mPrimary; 126 } 127 128 /** 129 * Returns true if the volume is removable. 130 * 131 * @return is removable 132 */ isRemovable()133 public boolean isRemovable() { 134 return mRemovable; 135 } 136 137 /** 138 * Returns true if the volume is emulated. 139 * 140 * @return is removable 141 */ isEmulated()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 */ getStorageId()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 */ getMtpReserveSpace()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 */ allowMassStorage()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 */ getMaxFileSize()186 public long getMaxFileSize() { 187 return mMaxFileSize; 188 } 189 getOwner()190 public UserHandle getOwner() { 191 return mOwner; 192 } 193 getUuid()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 */ getFatVolumeId()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 getUserLabel()213 public String getUserLabel() { 214 return mDescription; 215 } 216 getState()217 public String getState() { 218 return mState; 219 } 220 221 @Override equals(Object obj)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 hashCode()231 public int hashCode() { 232 return mPath.hashCode(); 233 } 234 235 @Override toString()236 public String toString() { 237 final CharArrayWriter writer = new CharArrayWriter(); 238 dump(new IndentingPrintWriter(writer, " ", 80)); 239 return writer.toString(); 240 } 241 dump(IndentingPrintWriter pw)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 describeContents()274 public int describeContents() { 275 return 0; 276 } 277 278 @Override writeToParcel(Parcel parcel, int flags)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