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 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