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>
|
* <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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user