Expose StorageVolume.isStub() as @SystemApi API

StorageVolume.isStub() indicates whether the volume is a StubVolume,
i.e. whether it is a volume managed from outside Android (e.g. from
Chrome OS).
It needs to be exposed as a @SystemApi API because the MediaProvider
module will use it to decide whether default folders like Music, Movies,
Pictures, etc. should be automatically created inside a volume; when the
volume is a StubVolume, such automatic creation should be avoided.

Bug: 206019156
Test: m
Test: atest MtpTests
Test: atest StorageManagerTest#testGetPrimaryVolume

Change-Id: I9a9bd170408c5d92c94eac33cdab9aea394b324e
This commit is contained in:
Youkichi Hosoi
2021-11-16 18:05:57 +09:00
parent a7c80fad92
commit 3632fde851
7 changed files with 36 additions and 12 deletions

View File

@@ -9112,6 +9112,7 @@ package android.os.storage {
public final class StorageVolume implements android.os.Parcelable {
method @NonNull public String getId();
method public boolean isStub();
}
}

View File

@@ -99,6 +99,7 @@ public final class StorageVolume implements Parcelable {
@UnsupportedAppUsage
private final boolean mRemovable;
private final boolean mEmulated;
private final boolean mStub;
private final boolean mAllowMassStorage;
private final long mMaxFileSize;
private final UserHandle mOwner;
@@ -137,8 +138,9 @@ public final class StorageVolume implements Parcelable {
/** {@hide} */
public StorageVolume(String id, File path, File internalPath, String description,
boolean primary, boolean removable, boolean emulated, boolean allowMassStorage,
long maxFileSize, UserHandle owner, UUID uuid, String fsUuid, String state) {
boolean primary, boolean removable, boolean emulated, boolean stub,
boolean allowMassStorage, long maxFileSize, UserHandle owner, UUID uuid, String fsUuid,
String state) {
mId = Preconditions.checkNotNull(id);
mPath = Preconditions.checkNotNull(path);
mInternalPath = Preconditions.checkNotNull(internalPath);
@@ -146,6 +148,7 @@ public final class StorageVolume implements Parcelable {
mPrimary = primary;
mRemovable = removable;
mEmulated = emulated;
mStub = stub;
mAllowMassStorage = allowMassStorage;
mMaxFileSize = maxFileSize;
mOwner = Preconditions.checkNotNull(owner);
@@ -162,6 +165,7 @@ public final class StorageVolume implements Parcelable {
mPrimary = in.readInt() != 0;
mRemovable = in.readInt() != 0;
mEmulated = in.readInt() != 0;
mStub = in.readInt() != 0;
mAllowMassStorage = in.readInt() != 0;
mMaxFileSize = in.readLong();
mOwner = in.readParcelable(null);
@@ -264,12 +268,22 @@ public final class StorageVolume implements Parcelable {
/**
* Returns true if the volume is emulated.
*
* @return is removable
* @return is emulated
*/
public boolean isEmulated() {
return mEmulated;
}
/**
* Returns true if the volume is a stub volume (a volume managed from outside Android).
*
* @hide
*/
@SystemApi
public boolean isStub() {
return mStub;
}
/**
* Returns true if this volume can be shared via USB mass storage.
*
@@ -506,6 +520,7 @@ public final class StorageVolume implements Parcelable {
pw.printPair("mPrimary", mPrimary);
pw.printPair("mRemovable", mRemovable);
pw.printPair("mEmulated", mEmulated);
pw.printPair("mStub", mStub);
pw.printPair("mAllowMassStorage", mAllowMassStorage);
pw.printPair("mMaxFileSize", mMaxFileSize);
pw.printPair("mOwner", mOwner);
@@ -540,6 +555,7 @@ public final class StorageVolume implements Parcelable {
parcel.writeInt(mPrimary ? 1 : 0);
parcel.writeInt(mRemovable ? 1 : 0);
parcel.writeInt(mEmulated ? 1 : 0);
parcel.writeInt(mStub ? 1 : 0);
parcel.writeInt(mAllowMassStorage ? 1 : 0);
parcel.writeLong(mMaxFileSize);
parcel.writeParcelable(mOwner, flags);
@@ -621,6 +637,7 @@ public final class StorageVolume implements Parcelable {
mPrimary,
mRemovable,
mEmulated,
/* stub= */ false,
/* allowMassStorage= */ false,
/* maxFileSize= */ 0,
mOwner,

View File

@@ -388,6 +388,7 @@ public class VolumeInfo implements Parcelable {
final boolean removable;
final boolean emulated;
final boolean stub = type == TYPE_STUB;
final boolean allowMassStorage = false;
final String envState = reportUnmounted
? Environment.MEDIA_UNMOUNTED : getEnvironmentForState(state);
@@ -443,8 +444,8 @@ public class VolumeInfo implements Parcelable {
}
return new StorageVolume(id, userPath, internalPath, description, isPrimary(), removable,
emulated, allowMassStorage, maxFileSize, new UserHandle(userId),
uuid, derivedFsUuid, envState);
emulated, stub, allowMassStorage, maxFileSize, new UserHandle(userId), uuid,
derivedFsUuid, envState);
}
@UnsupportedAppUsage

View File

@@ -105,6 +105,7 @@ public class VolumeRecord implements Parcelable {
final boolean primary = false;
final boolean removable = true;
final boolean emulated = false;
final boolean stub = false;
final boolean allowMassStorage = false;
final long maxFileSize = 0;
final UserHandle user = new UserHandle(UserHandle.USER_NULL);
@@ -116,7 +117,8 @@ public class VolumeRecord implements Parcelable {
}
return new StorageVolume(id, userPath, internalPath, description, primary, removable,
emulated, allowMassStorage, maxFileSize, user, null /* uuid */, fsUuid, envState);
emulated, stub, allowMassStorage, maxFileSize, user, null /* uuid */, fsUuid,
envState);
}
public void dump(IndentingPrintWriter pw) {

View File

@@ -132,7 +132,7 @@ public class MtpDatabaseTest {
StorageVolume mainStorage = new StorageVolume(MAIN_STORAGE_ID_STR,
mMainStorageDir, mMainStorageDir, "Primary Storage",
true, false, true, false, -1, UserHandle.CURRENT, null /* uuid */, "", "");
true, false, true, false, false, -1, UserHandle.CURRENT, null /* uuid */, "", "");
final StorageVolume primary = mainStorage;

View File

@@ -132,9 +132,10 @@ public class MtpStorageManagerTest {
secondaryStorageDir = createNewDir(TEMP_DIR_FILE);
StorageVolume mainStorage = new StorageVolume("1", mainStorageDir, mainStorageDir,
"", true, false, true, false, -1, UserHandle.CURRENT, null /* uuid */, "", "");
"", true, false, true, false, false, -1, UserHandle.CURRENT, null /* uuid */, "",
"");
StorageVolume secondaryStorage = new StorageVolume("2", secondaryStorageDir,
secondaryStorageDir, "", false, false, true, false, -1, UserHandle.CURRENT,
secondaryStorageDir, "", false, false, true, false, false, -1, UserHandle.CURRENT,
null /* uuid */, "", "");
objectsAdded = new ArrayList<>();

View File

@@ -3830,14 +3830,15 @@ class StorageManagerService extends IStorageManager.Stub
final boolean primary = false;
final boolean removable = false;
final boolean emulated = true;
final boolean stub = false;
final boolean allowMassStorage = false;
final long maxFileSize = 0;
final UserHandle user = new UserHandle(userId);
final String envState = Environment.MEDIA_MOUNTED_READ_ONLY;
final String description = mContext.getString(android.R.string.unknownName);
res.add(new StorageVolume(id, path, path, description, primary, removable,
emulated, allowMassStorage, maxFileSize, user, null /*uuid */, id, envState));
res.add(new StorageVolume(id, path, path, description, primary, removable, emulated,
stub, allowMassStorage, maxFileSize, user, null /*uuid */, id, envState));
}
if (!foundPrimary) {
@@ -3852,6 +3853,7 @@ class StorageManagerService extends IStorageManager.Stub
final boolean primary = true;
final boolean removable = primaryPhysical;
final boolean emulated = !primaryPhysical;
final boolean stub = false;
final boolean allowMassStorage = false;
final long maxFileSize = 0L;
final UserHandle owner = new UserHandle(userId);
@@ -3860,7 +3862,7 @@ class StorageManagerService extends IStorageManager.Stub
final String state = Environment.MEDIA_REMOVED;
res.add(0, new StorageVolume(id, path, path,
description, primary, removable, emulated,
description, primary, removable, emulated, stub,
allowMassStorage, maxFileSize, owner, uuid, fsUuid, state));
}