* commit '95661575a058f72ec6db5f455b6319816334a5ee': Generate stable MTP storage IDs.
This commit is contained in:
@@ -58,6 +58,9 @@ public class StorageVolume implements Parcelable {
|
|||||||
// ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts.
|
// ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts.
|
||||||
public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
|
public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
|
||||||
|
|
||||||
|
public static final int STORAGE_ID_INVALID = 0x00000000;
|
||||||
|
public static final int STORAGE_ID_PRIMARY = 0x00010001;
|
||||||
|
|
||||||
public StorageVolume(String id, int storageId, File path, String description, boolean primary,
|
public StorageVolume(String id, int storageId, File path, String description, boolean primary,
|
||||||
boolean removable, boolean emulated, long mtpReserveSize, boolean allowMassStorage,
|
boolean removable, boolean emulated, long mtpReserveSize, boolean allowMassStorage,
|
||||||
long maxFileSize, UserHandle owner, String fsUuid, String state) {
|
long maxFileSize, UserHandle owner, String fsUuid, String state) {
|
||||||
|
|||||||
@@ -147,15 +147,11 @@ public class VolumeInfo implements Parcelable {
|
|||||||
public String path;
|
public String path;
|
||||||
public String internalPath;
|
public String internalPath;
|
||||||
|
|
||||||
/** Framework state */
|
public VolumeInfo(String id, int type, DiskInfo disk, String partGuid) {
|
||||||
public final int mtpIndex;
|
|
||||||
|
|
||||||
public VolumeInfo(String id, int type, DiskInfo disk, String partGuid, int mtpIndex) {
|
|
||||||
this.id = Preconditions.checkNotNull(id);
|
this.id = Preconditions.checkNotNull(id);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.disk = disk;
|
this.disk = disk;
|
||||||
this.partGuid = partGuid;
|
this.partGuid = partGuid;
|
||||||
this.mtpIndex = mtpIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VolumeInfo(Parcel parcel) {
|
public VolumeInfo(Parcel parcel) {
|
||||||
@@ -175,7 +171,6 @@ public class VolumeInfo implements Parcelable {
|
|||||||
fsLabel = parcel.readString();
|
fsLabel = parcel.readString();
|
||||||
path = parcel.readString();
|
path = parcel.readString();
|
||||||
internalPath = parcel.readString();
|
internalPath = parcel.readString();
|
||||||
mtpIndex = parcel.readInt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NonNull String getEnvironmentForState(int state) {
|
public static @NonNull String getEnvironmentForState(int state) {
|
||||||
@@ -308,7 +303,6 @@ public class VolumeInfo implements Parcelable {
|
|||||||
final boolean removable;
|
final boolean removable;
|
||||||
final boolean emulated;
|
final boolean emulated;
|
||||||
final boolean allowMassStorage = false;
|
final boolean allowMassStorage = false;
|
||||||
final int mtpStorageId = MtpStorage.getStorageIdForIndex(mtpIndex);
|
|
||||||
final String envState = getEnvironmentForState(state);
|
final String envState = getEnvironmentForState(state);
|
||||||
|
|
||||||
File userPath = getPathForUser(userId);
|
File userPath = getPathForUser(userId);
|
||||||
@@ -326,9 +320,15 @@ public class VolumeInfo implements Parcelable {
|
|||||||
|
|
||||||
long mtpReserveSize = 0;
|
long mtpReserveSize = 0;
|
||||||
long maxFileSize = 0;
|
long maxFileSize = 0;
|
||||||
|
int mtpStorageId = StorageVolume.STORAGE_ID_INVALID;
|
||||||
|
|
||||||
if (type == TYPE_EMULATED) {
|
if (type == TYPE_EMULATED) {
|
||||||
emulated = true;
|
emulated = true;
|
||||||
|
|
||||||
|
if (isPrimary()) {
|
||||||
|
mtpStorageId = StorageVolume.STORAGE_ID_PRIMARY;
|
||||||
|
}
|
||||||
|
|
||||||
mtpReserveSize = StorageManager.from(context).getStorageLowBytes(userPath);
|
mtpReserveSize = StorageManager.from(context).getStorageLowBytes(userPath);
|
||||||
|
|
||||||
if (ID_EMULATED_INTERNAL.equals(id)) {
|
if (ID_EMULATED_INTERNAL.equals(id)) {
|
||||||
@@ -341,6 +341,14 @@ public class VolumeInfo implements Parcelable {
|
|||||||
emulated = false;
|
emulated = false;
|
||||||
removable = true;
|
removable = true;
|
||||||
|
|
||||||
|
if (isPrimary()) {
|
||||||
|
mtpStorageId = StorageVolume.STORAGE_ID_PRIMARY;
|
||||||
|
} else {
|
||||||
|
// Since MediaProvider currently persists this value, we need a
|
||||||
|
// value that is stable over time.
|
||||||
|
mtpStorageId = buildStableMtpStorageId(fsUuid);
|
||||||
|
}
|
||||||
|
|
||||||
if ("vfat".equals(fsType)) {
|
if ("vfat".equals(fsType)) {
|
||||||
maxFileSize = 4294967295L;
|
maxFileSize = 4294967295L;
|
||||||
}
|
}
|
||||||
@@ -354,6 +362,24 @@ public class VolumeInfo implements Parcelable {
|
|||||||
fsUuid, envState);
|
fsUuid, envState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int buildStableMtpStorageId(String fsUuid) {
|
||||||
|
if (TextUtils.isEmpty(fsUuid)) {
|
||||||
|
return StorageVolume.STORAGE_ID_INVALID;
|
||||||
|
} else {
|
||||||
|
int hash = 0;
|
||||||
|
for (int i = 0; i < fsUuid.length(); ++i) {
|
||||||
|
hash = 31 * hash + fsUuid.charAt(i);
|
||||||
|
}
|
||||||
|
hash = (hash ^ (hash << 16)) & 0xffff0000;
|
||||||
|
// Work around values that the spec doesn't allow, or that we've
|
||||||
|
// reserved for primary
|
||||||
|
if (hash == 0x00000000) hash = 0x00020000;
|
||||||
|
if (hash == 0x00010000) hash = 0x00020000;
|
||||||
|
if (hash == 0xffff0000) hash = 0xfffe0000;
|
||||||
|
return hash | 0x0001;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: avoid this layering violation
|
// TODO: avoid this layering violation
|
||||||
private static final String DOCUMENT_AUTHORITY = "com.android.externalstorage.documents";
|
private static final String DOCUMENT_AUTHORITY = "com.android.externalstorage.documents";
|
||||||
private static final String DOCUMENT_ROOT_PRIMARY_EMULATED = "primary";
|
private static final String DOCUMENT_ROOT_PRIMARY_EMULATED = "primary";
|
||||||
@@ -402,7 +428,6 @@ public class VolumeInfo implements Parcelable {
|
|||||||
pw.println();
|
pw.println();
|
||||||
pw.printPair("path", path);
|
pw.printPair("path", path);
|
||||||
pw.printPair("internalPath", internalPath);
|
pw.printPair("internalPath", internalPath);
|
||||||
pw.printPair("mtpIndex", mtpIndex);
|
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.println();
|
pw.println();
|
||||||
}
|
}
|
||||||
@@ -469,6 +494,5 @@ public class VolumeInfo implements Parcelable {
|
|||||||
parcel.writeString(fsLabel);
|
parcel.writeString(fsLabel);
|
||||||
parcel.writeString(path);
|
parcel.writeString(path);
|
||||||
parcel.writeString(internalPath);
|
parcel.writeString(internalPath);
|
||||||
parcel.writeInt(mtpIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,18 +53,6 @@ public class MtpStorage {
|
|||||||
return mStorageId;
|
return mStorageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a storage ID for storage of given index.
|
|
||||||
* Index 0 is for primary external storage
|
|
||||||
*
|
|
||||||
* @return the storage ID
|
|
||||||
*/
|
|
||||||
public static int getStorageIdForIndex(int index) {
|
|
||||||
// storage ID is 0x00010001 for primary storage,
|
|
||||||
// then 0x00020001, 0x00030001, etc. for secondary storages
|
|
||||||
return ((index + 1) << 16) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the file path for the storage unit's storage in the file system
|
* Returns the file path for the storage unit's storage in the file system
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -402,16 +402,6 @@ class MountService extends IMountService.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int sNextMtpIndex = 1;
|
|
||||||
|
|
||||||
private static int allocateMtpIndex(String volId) {
|
|
||||||
if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volId)) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return sNextMtpIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** List of crypto types.
|
/** List of crypto types.
|
||||||
* These must match CRYPT_TYPE_XXX in cryptfs.h AND their
|
* These must match CRYPT_TYPE_XXX in cryptfs.h AND their
|
||||||
* corresponding commands in CommandListener.cpp */
|
* corresponding commands in CommandListener.cpp */
|
||||||
@@ -742,7 +732,7 @@ class MountService extends IMountService.Stub
|
|||||||
|
|
||||||
// Create a stub volume that represents internal storage
|
// Create a stub volume that represents internal storage
|
||||||
final VolumeInfo internal = new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL,
|
final VolumeInfo internal = new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL,
|
||||||
VolumeInfo.TYPE_PRIVATE, null, null, 0);
|
VolumeInfo.TYPE_PRIVATE, null, null);
|
||||||
internal.state = VolumeInfo.STATE_MOUNTED;
|
internal.state = VolumeInfo.STATE_MOUNTED;
|
||||||
internal.path = Environment.getDataDirectory().getAbsolutePath();
|
internal.path = Environment.getDataDirectory().getAbsolutePath();
|
||||||
mVolumes.put(internal.id, internal);
|
mVolumes.put(internal.id, internal);
|
||||||
@@ -967,8 +957,7 @@ class MountService extends IMountService.Stub
|
|||||||
final String partGuid = TextUtils.nullIfEmpty(cooked[4]);
|
final String partGuid = TextUtils.nullIfEmpty(cooked[4]);
|
||||||
|
|
||||||
final DiskInfo disk = mDisks.get(diskId);
|
final DiskInfo disk = mDisks.get(diskId);
|
||||||
final int mtpIndex = allocateMtpIndex(id);
|
final VolumeInfo vol = new VolumeInfo(id, type, disk, partGuid);
|
||||||
final VolumeInfo vol = new VolumeInfo(id, type, disk, partGuid, mtpIndex);
|
|
||||||
mVolumes.put(id, vol);
|
mVolumes.put(id, vol);
|
||||||
onVolumeCreatedLocked(vol);
|
onVolumeCreatedLocked(vol);
|
||||||
break;
|
break;
|
||||||
@@ -2604,7 +2593,7 @@ class MountService extends IMountService.Stub
|
|||||||
final String uuid = null;
|
final String uuid = null;
|
||||||
final String state = Environment.MEDIA_REMOVED;
|
final String state = Environment.MEDIA_REMOVED;
|
||||||
|
|
||||||
res.add(0, new StorageVolume(id, MtpStorage.getStorageIdForIndex(0), path,
|
res.add(0, new StorageVolume(id, StorageVolume.STORAGE_ID_INVALID, path,
|
||||||
description, primary, removable, emulated, mtpReserveSize,
|
description, primary, removable, emulated, mtpReserveSize,
|
||||||
allowMassStorage, maxFileSize, owner, uuid, state));
|
allowMassStorage, maxFileSize, owner, uuid, state));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user