Merge "Split MOUNT_FLAG_VISIBLE into MOUNT_FLAG_VISIBLE_FOR_{READ, WRITE}"

This commit is contained in:
Treehugger Robot
2021-11-26 03:02:16 +00:00
committed by Gerrit Code Review
3 changed files with 41 additions and 25 deletions

View File

@@ -56,11 +56,12 @@ import java.util.UUID;
* <ul> * <ul>
* <li>{@link #MOUNT_FLAG_PRIMARY} means the volume provides primary external * <li>{@link #MOUNT_FLAG_PRIMARY} means the volume provides primary external
* storage, historically found at {@code /sdcard}. * storage, historically found at {@code /sdcard}.
* <li>{@link #MOUNT_FLAG_VISIBLE} means the volume is visible to third-party * <li>{@link #MOUNT_FLAG_VISIBLE_FOR_READ} and
* apps for direct filesystem access. The system should send out relevant * {@link #MOUNT_FLAG_VISIBLE_FOR_WRITE} mean the volume is visible to
* storage broadcasts and index any media on visible volumes. Visible volumes * third-party apps for direct filesystem access. The system should send out
* are considered a more stable part of the device, which is why we take the * relevant storage broadcasts and index any media on visible volumes. Visible
* time to index them. In particular, transient volumes like USB OTG devices * 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 * <em>should not</em> be marked as visible; their contents should be surfaced
* to apps through the Storage Access Framework. * to apps through the Storage Access Framework.
* </ul> * </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 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_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 SparseArray<String> sStateToEnvironment = new SparseArray<>();
private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>(); private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>();
@@ -312,17 +314,31 @@ public class VolumeInfo implements Parcelable {
return isPrimary() && (getType() == TYPE_PUBLIC); return isPrimary() && (getType() == TYPE_PUBLIC);
} }
@UnsupportedAppUsage private boolean isVisibleForRead() {
public boolean isVisible() { return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_READ) != 0;
return (mountFlags & MOUNT_FLAG_VISIBLE) != 0;
} }
public boolean isVisibleForUser(int userId) { private boolean isVisibleForWrite() {
if ((type == TYPE_PUBLIC || type == TYPE_STUB || type == TYPE_EMULATED) return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_WRITE) != 0;
&& mountUserId == userId) { }
return isVisible();
@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) { public boolean isVisibleForRead(int userId) {
return isVisibleForUser(userId); return isVolumeSupportedForUser(userId) && isVisibleForRead();
} }
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isVisibleForWrite(int userId) { public boolean isVisibleForWrite(int userId) {
return isVisibleForUser(userId); return isVolumeSupportedForUser(userId) && isVisibleForWrite();
} }
@UnsupportedAppUsage @UnsupportedAppUsage

View File

@@ -251,7 +251,7 @@ public class ExternalStorageProvider extends FileSystemProvider {
if (volume.getType() == VolumeInfo.TYPE_PUBLIC) { if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
root.flags |= Root.FLAG_HAS_SETTINGS; root.flags |= Root.FLAG_HAS_SETTINGS;
} }
if (volume.isVisibleForRead(userId)) { if (volume.isVisibleForUser(userId)) {
root.visiblePath = volume.getPathForUser(userId); root.visiblePath = volume.getPathForUser(userId);
} else { } else {
root.visiblePath = null; root.visiblePath = null;

View File

@@ -1230,7 +1230,7 @@ class StorageManagerService extends IStorageManager.Stub
} }
for (int i = 0; i < mVolumes.size(); i++) { for (int i = 0; i < mVolumes.size(); i++) {
final VolumeInfo vol = mVolumes.valueAt(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); final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget(); mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
@@ -1558,13 +1558,13 @@ class StorageManagerService extends IStorageManager.Stub
&& VolumeInfo.ID_PRIVATE_INTERNAL.equals(privateVol.id)) { && VolumeInfo.ID_PRIVATE_INTERNAL.equals(privateVol.id)) {
Slog.v(TAG, "Found primary storage at " + vol); Slog.v(TAG, "Found primary storage at " + vol);
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY; 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(); mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
} else if (Objects.equals(privateVol.fsUuid, mPrimaryStorageUuid)) { } else if (Objects.equals(privateVol.fsUuid, mPrimaryStorageUuid)) {
Slog.v(TAG, "Found primary storage at " + vol); Slog.v(TAG, "Found primary storage at " + vol);
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY; 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(); mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
} }
@@ -1574,13 +1574,13 @@ class StorageManagerService extends IStorageManager.Stub
&& vol.disk.isDefaultPrimary()) { && vol.disk.isDefaultPrimary()) {
Slog.v(TAG, "Found primary storage at " + vol); Slog.v(TAG, "Found primary storage at " + vol);
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY; 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 // Adoptable public disks are visible to apps, since they meet
// public API requirement of being in a stable location. // public API requirement of being in a stable location.
if (vol.disk.isAdoptable()) { if (vol.disk.isAdoptable()) {
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE; vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
} }
vol.mountUserId = mCurrentUserId; vol.mountUserId = mCurrentUserId;
@@ -1591,7 +1591,7 @@ class StorageManagerService extends IStorageManager.Stub
} else if (vol.type == VolumeInfo.TYPE_STUB) { } else if (vol.type == VolumeInfo.TYPE_STUB) {
if (vol.disk.isStubVisible()) { if (vol.disk.isStubVisible()) {
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE; vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
} }
vol.mountUserId = mCurrentUserId; vol.mountUserId = mCurrentUserId;
mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget(); mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
@@ -1738,7 +1738,7 @@ class StorageManagerService extends IStorageManager.Stub
// started after this point will trigger additional // started after this point will trigger additional
// user-specific broadcasts. // user-specific broadcasts.
for (int userId : mSystemUnlockedUsers) { for (int userId : mSystemUnlockedUsers) {
if (vol.isVisibleForRead(userId)) { if (vol.isVisibleForUser(userId)) {
final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
false); false);
mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget(); mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
@@ -3766,7 +3766,7 @@ class StorageManagerService extends IStorageManager.Stub
if (forWrite) { if (forWrite) {
match = vol.isVisibleForWrite(userId); match = vol.isVisibleForWrite(userId);
} else { } else {
match = vol.isVisibleForRead(userId) match = vol.isVisibleForUser(userId)
|| (includeInvisible && vol.getPath() != null); || (includeInvisible && vol.getPath() != null);
} }
if (!match) continue; if (!match) continue;