StorageVolume.java revision 5aca2b8dc4f4ff2d466a64587d06666c7bbd9749
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.os.Parcel; 21import android.os.Parcelable; 22import android.os.UserHandle; 23 24import com.android.internal.util.IndentingPrintWriter; 25 26import java.io.CharArrayWriter; 27import java.io.File; 28 29/** 30 * Description of a storage volume and its capabilities, including the 31 * filesystem path where it may be mounted. 32 * 33 * @hide 34 */ 35public class StorageVolume implements Parcelable { 36 37 // TODO: switch to more durable token 38 private int mStorageId; 39 40 private final File mPath; 41 private final int mDescriptionId; 42 private final boolean mPrimary; 43 private final boolean mRemovable; 44 private final boolean mEmulated; 45 private final int mMtpReserveSpace; 46 private final boolean mAllowMassStorage; 47 /** Maximum file size for the storage, or zero for no limit */ 48 private final long mMaxFileSize; 49 /** When set, indicates exclusive ownership of this volume */ 50 private final UserHandle mOwner; 51 52 private String mUuid; 53 private String mUserLabel; 54 55 // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING, 56 // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED, 57 // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts. 58 public static final String EXTRA_STORAGE_VOLUME = "storage_volume"; 59 60 public StorageVolume(File path, int descriptionId, boolean primary, boolean removable, 61 boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize, 62 UserHandle owner) { 63 mPath = path; 64 mDescriptionId = descriptionId; 65 mPrimary = primary; 66 mRemovable = removable; 67 mEmulated = emulated; 68 mMtpReserveSpace = mtpReserveSpace; 69 mAllowMassStorage = allowMassStorage; 70 mMaxFileSize = maxFileSize; 71 mOwner = owner; 72 } 73 74 private StorageVolume(Parcel in) { 75 mStorageId = in.readInt(); 76 mPath = new File(in.readString()); 77 mDescriptionId = in.readInt(); 78 mPrimary = in.readInt() != 0; 79 mRemovable = in.readInt() != 0; 80 mEmulated = in.readInt() != 0; 81 mMtpReserveSpace = in.readInt(); 82 mAllowMassStorage = in.readInt() != 0; 83 mMaxFileSize = in.readLong(); 84 mOwner = in.readParcelable(null); 85 mUuid = in.readString(); 86 mUserLabel = in.readString(); 87 } 88 89 public static StorageVolume fromTemplate(StorageVolume template, File path, UserHandle owner) { 90 return new StorageVolume(path, template.mDescriptionId, template.mPrimary, 91 template.mRemovable, template.mEmulated, template.mMtpReserveSpace, 92 template.mAllowMassStorage, template.mMaxFileSize, owner); 93 } 94 95 /** 96 * Returns the mount path for the volume. 97 * 98 * @return the mount path 99 */ 100 public String getPath() { 101 return mPath.toString(); 102 } 103 104 public File getPathFile() { 105 return mPath; 106 } 107 108 /** 109 * Returns a user visible description of the volume. 110 * 111 * @return the volume description 112 */ 113 public String getDescription(Context context) { 114 return context.getResources().getString(mDescriptionId); 115 } 116 117 public int getDescriptionId() { 118 return mDescriptionId; 119 } 120 121 public boolean isPrimary() { 122 return mPrimary; 123 } 124 125 /** 126 * Returns true if the volume is removable. 127 * 128 * @return is removable 129 */ 130 public boolean isRemovable() { 131 return mRemovable; 132 } 133 134 /** 135 * Returns true if the volume is emulated. 136 * 137 * @return is removable 138 */ 139 public boolean isEmulated() { 140 return mEmulated; 141 } 142 143 /** 144 * Returns the MTP storage ID for the volume. 145 * this is also used for the storage_id column in the media provider. 146 * 147 * @return MTP storage ID 148 */ 149 public int getStorageId() { 150 return mStorageId; 151 } 152 153 /** 154 * Do not call this unless you are MountService 155 */ 156 public void setStorageId(int index) { 157 // storage ID is 0x00010001 for primary storage, 158 // then 0x00020001, 0x00030001, etc. for secondary storages 159 mStorageId = ((index + 1) << 16) + 1; 160 } 161 162 /** 163 * Number of megabytes of space to leave unallocated by MTP. 164 * MTP will subtract this value from the free space it reports back 165 * to the host via GetStorageInfo, and will not allow new files to 166 * be added via MTP if there is less than this amount left free in the storage. 167 * If MTP has dedicated storage this value should be zero, but if MTP is 168 * sharing storage with the rest of the system, set this to a positive value 169 * to ensure that MTP activity does not result in the storage being 170 * too close to full. 171 * 172 * @return MTP reserve space 173 */ 174 public int getMtpReserveSpace() { 175 return mMtpReserveSpace; 176 } 177 178 /** 179 * Returns true if this volume can be shared via USB mass storage. 180 * 181 * @return whether mass storage is allowed 182 */ 183 public boolean allowMassStorage() { 184 return mAllowMassStorage; 185 } 186 187 /** 188 * Returns maximum file size for the volume, or zero if it is unbounded. 189 * 190 * @return maximum file size 191 */ 192 public long getMaxFileSize() { 193 return mMaxFileSize; 194 } 195 196 public UserHandle getOwner() { 197 return mOwner; 198 } 199 200 public void setUuid(String uuid) { 201 mUuid = uuid; 202 } 203 204 public String getUuid() { 205 return mUuid; 206 } 207 208 /** 209 * Parse and return volume UUID as FAT volume ID, or return -1 if unable to 210 * parse or UUID is unknown. 211 */ 212 public int getFatVolumeId() { 213 if (mUuid == null || mUuid.length() != 9) { 214 return -1; 215 } 216 try { 217 return Integer.parseInt(mUuid.replace("-", ""), 16); 218 } catch (NumberFormatException e) { 219 return -1; 220 } 221 } 222 223 public void setUserLabel(String userLabel) { 224 mUserLabel = userLabel; 225 } 226 227 public String getUserLabel() { 228 return mUserLabel; 229 } 230 231 @Override 232 public boolean equals(Object obj) { 233 if (obj instanceof StorageVolume && mPath != null) { 234 StorageVolume volume = (StorageVolume)obj; 235 return (mPath.equals(volume.mPath)); 236 } 237 return false; 238 } 239 240 @Override 241 public int hashCode() { 242 return mPath.hashCode(); 243 } 244 245 @Override 246 public String toString() { 247 final CharArrayWriter writer = new CharArrayWriter(); 248 dump(new IndentingPrintWriter(writer, " ", 80)); 249 return writer.toString(); 250 } 251 252 public void dump(IndentingPrintWriter pw) { 253 pw.println("StorageVolume:"); 254 pw.increaseIndent(); 255 pw.printPair("mStorageId", mStorageId); 256 pw.printPair("mPath", mPath); 257 pw.printPair("mDescriptionId", mDescriptionId); 258 pw.printPair("mPrimary", mPrimary); 259 pw.printPair("mRemovable", mRemovable); 260 pw.printPair("mEmulated", mEmulated); 261 pw.printPair("mMtpReserveSpace", mMtpReserveSpace); 262 pw.printPair("mAllowMassStorage", mAllowMassStorage); 263 pw.printPair("mMaxFileSize", mMaxFileSize); 264 pw.printPair("mOwner", mOwner); 265 pw.printPair("mUuid", mUuid); 266 pw.printPair("mUserLabel", mUserLabel); 267 pw.decreaseIndent(); 268 } 269 270 public static final Creator<StorageVolume> CREATOR = new Creator<StorageVolume>() { 271 @Override 272 public StorageVolume createFromParcel(Parcel in) { 273 return new StorageVolume(in); 274 } 275 276 @Override 277 public StorageVolume[] newArray(int size) { 278 return new StorageVolume[size]; 279 } 280 }; 281 282 @Override 283 public int describeContents() { 284 return 0; 285 } 286 287 @Override 288 public void writeToParcel(Parcel parcel, int flags) { 289 parcel.writeInt(mStorageId); 290 parcel.writeString(mPath.toString()); 291 parcel.writeInt(mDescriptionId); 292 parcel.writeInt(mPrimary ? 1 : 0); 293 parcel.writeInt(mRemovable ? 1 : 0); 294 parcel.writeInt(mEmulated ? 1 : 0); 295 parcel.writeInt(mMtpReserveSpace); 296 parcel.writeInt(mAllowMassStorage ? 1 : 0); 297 parcel.writeLong(mMaxFileSize); 298 parcel.writeParcelable(mOwner, flags); 299 parcel.writeString(mUuid); 300 parcel.writeString(mUserLabel); 301 } 302} 303