Merge "Split MOUNT_FLAG_VISIBLE into MOUNT_FLAG_VISIBLE_FOR_{READ, WRITE}"
This commit is contained in:
@@ -56,11 +56,12 @@ import java.util.UUID;
|
||||
* <ul>
|
||||
* <li>{@link #MOUNT_FLAG_PRIMARY} means the volume provides primary external
|
||||
* storage, historically found at {@code /sdcard}.
|
||||
* <li>{@link #MOUNT_FLAG_VISIBLE} means the volume is visible to third-party
|
||||
* apps for direct filesystem access. The system should send out relevant
|
||||
* storage broadcasts and index any media on visible volumes. Visible volumes
|
||||
* are considered a more stable part of the device, which is why we take the
|
||||
* time to index them. In particular, transient volumes like USB OTG devices
|
||||
* <li>{@link #MOUNT_FLAG_VISIBLE_FOR_READ} and
|
||||
* {@link #MOUNT_FLAG_VISIBLE_FOR_WRITE} mean the volume is visible to
|
||||
* third-party apps for direct filesystem access. The system should send out
|
||||
* relevant storage broadcasts and index any media on visible volumes. Visible
|
||||
* volumes are considered a more stable part of the device, which is why we take
|
||||
* the time to index them. In particular, transient volumes like USB OTG devices
|
||||
* <em>should not</em> be marked as visible; their contents should be surfaced
|
||||
* to apps through the Storage Access Framework.
|
||||
* </ul>
|
||||
@@ -100,7 +101,8 @@ public class VolumeInfo implements Parcelable {
|
||||
public static final int STATE_BAD_REMOVAL = IVold.VOLUME_STATE_BAD_REMOVAL;
|
||||
|
||||
public static final int MOUNT_FLAG_PRIMARY = IVold.MOUNT_FLAG_PRIMARY;
|
||||
public static final int MOUNT_FLAG_VISIBLE = IVold.MOUNT_FLAG_VISIBLE;
|
||||
public static final int MOUNT_FLAG_VISIBLE_FOR_READ = IVold.MOUNT_FLAG_VISIBLE_FOR_READ;
|
||||
public static final int MOUNT_FLAG_VISIBLE_FOR_WRITE = IVold.MOUNT_FLAG_VISIBLE_FOR_WRITE;
|
||||
|
||||
private static SparseArray<String> sStateToEnvironment = new SparseArray<>();
|
||||
private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>();
|
||||
@@ -312,17 +314,31 @@ public class VolumeInfo implements Parcelable {
|
||||
return isPrimary() && (getType() == TYPE_PUBLIC);
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public boolean isVisible() {
|
||||
return (mountFlags & MOUNT_FLAG_VISIBLE) != 0;
|
||||
private boolean isVisibleForRead() {
|
||||
return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_READ) != 0;
|
||||
}
|
||||
|
||||
public boolean isVisibleForUser(int userId) {
|
||||
if ((type == TYPE_PUBLIC || type == TYPE_STUB || type == TYPE_EMULATED)
|
||||
&& mountUserId == userId) {
|
||||
return isVisible();
|
||||
private boolean isVisibleForWrite() {
|
||||
return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_WRITE) != 0;
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public boolean isVisible() {
|
||||
return isVisibleForRead() || isVisibleForWrite();
|
||||
}
|
||||
|
||||
private boolean isVolumeSupportedForUser(int userId) {
|
||||
if (mountUserId != userId) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return type == TYPE_PUBLIC || type == TYPE_STUB || type == TYPE_EMULATED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this volume is visible for {@code userId}, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isVisibleForUser(int userId) {
|
||||
return isVolumeSupportedForUser(userId) && isVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,12 +351,12 @@ public class VolumeInfo implements Parcelable {
|
||||
}
|
||||
|
||||
public boolean isVisibleForRead(int userId) {
|
||||
return isVisibleForUser(userId);
|
||||
return isVolumeSupportedForUser(userId) && isVisibleForRead();
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||
public boolean isVisibleForWrite(int userId) {
|
||||
return isVisibleForUser(userId);
|
||||
return isVolumeSupportedForUser(userId) && isVisibleForWrite();
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
|
||||
@@ -251,7 +251,7 @@ public class ExternalStorageProvider extends FileSystemProvider {
|
||||
if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
|
||||
root.flags |= Root.FLAG_HAS_SETTINGS;
|
||||
}
|
||||
if (volume.isVisibleForRead(userId)) {
|
||||
if (volume.isVisibleForUser(userId)) {
|
||||
root.visiblePath = volume.getPathForUser(userId);
|
||||
} else {
|
||||
root.visiblePath = null;
|
||||
|
||||
@@ -1230,7 +1230,7 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
}
|
||||
for (int i = 0; i < mVolumes.size(); i++) {
|
||||
final VolumeInfo vol = mVolumes.valueAt(i);
|
||||
if (vol.isVisibleForRead(userId) && vol.isMountedReadable()) {
|
||||
if (vol.isVisibleForUser(userId) && vol.isMountedReadable()) {
|
||||
final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
|
||||
mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
|
||||
|
||||
@@ -1558,13 +1558,13 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
&& VolumeInfo.ID_PRIVATE_INTERNAL.equals(privateVol.id)) {
|
||||
Slog.v(TAG, "Found primary storage at " + vol);
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
|
||||
mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
|
||||
|
||||
} else if (Objects.equals(privateVol.fsUuid, mPrimaryStorageUuid)) {
|
||||
Slog.v(TAG, "Found primary storage at " + vol);
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
|
||||
mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
|
||||
}
|
||||
|
||||
@@ -1574,13 +1574,13 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
&& vol.disk.isDefaultPrimary()) {
|
||||
Slog.v(TAG, "Found primary storage at " + vol);
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
|
||||
}
|
||||
|
||||
// Adoptable public disks are visible to apps, since they meet
|
||||
// public API requirement of being in a stable location.
|
||||
if (vol.disk.isAdoptable()) {
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
|
||||
}
|
||||
|
||||
vol.mountUserId = mCurrentUserId;
|
||||
@@ -1591,7 +1591,7 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
|
||||
} else if (vol.type == VolumeInfo.TYPE_STUB) {
|
||||
if (vol.disk.isStubVisible()) {
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
|
||||
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
|
||||
}
|
||||
vol.mountUserId = mCurrentUserId;
|
||||
mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
|
||||
@@ -1738,7 +1738,7 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
// started after this point will trigger additional
|
||||
// user-specific broadcasts.
|
||||
for (int userId : mSystemUnlockedUsers) {
|
||||
if (vol.isVisibleForRead(userId)) {
|
||||
if (vol.isVisibleForUser(userId)) {
|
||||
final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
|
||||
false);
|
||||
mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
|
||||
@@ -3766,7 +3766,7 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
if (forWrite) {
|
||||
match = vol.isVisibleForWrite(userId);
|
||||
} else {
|
||||
match = vol.isVisibleForRead(userId)
|
||||
match = vol.isVisibleForUser(userId)
|
||||
|| (includeInvisible && vol.getPath() != null);
|
||||
}
|
||||
if (!match) continue;
|
||||
|
||||
Reference in New Issue
Block a user