Loading core/java/android/os/storage/VolumeInfo.java +30 −14 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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<>(); Loading Loading @@ -312,18 +314,32 @@ public class VolumeInfo implements Parcelable { return isPrimary() && (getType() == TYPE_PUBLIC); } private boolean isVisibleForRead() { return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_READ) != 0; } private boolean isVisibleForWrite() { return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_WRITE) != 0; } @UnsupportedAppUsage public boolean isVisible() { return (mountFlags & MOUNT_FLAG_VISIBLE) != 0; return isVisibleForRead() || isVisibleForWrite(); } public boolean isVisibleForUser(int userId) { if ((type == TYPE_PUBLIC || type == TYPE_STUB || type == TYPE_EMULATED) && mountUserId == userId) { return isVisible(); } private boolean isVolumeSupportedForUser(int userId) { if (mountUserId != userId) { 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(); } /** * Returns {@code true} if this volume is the primary emulated volume for {@code userId}, Loading @@ -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 Loading packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading services/core/java/com/android/server/StorageManagerService.java +7 −7 Original line number Diff line number Diff line Loading @@ -1223,7 +1223,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(); Loading Loading @@ -1570,7 +1570,7 @@ class StorageManagerService extends IStorageManager.Stub || 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(); } Loading @@ -1580,13 +1580,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; Loading @@ -1597,7 +1597,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(); Loading Loading @@ -1744,7 +1744,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(); Loading Loading @@ -3783,7 +3783,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; Loading Loading
core/java/android/os/storage/VolumeInfo.java +30 −14 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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<>(); Loading Loading @@ -312,18 +314,32 @@ public class VolumeInfo implements Parcelable { return isPrimary() && (getType() == TYPE_PUBLIC); } private boolean isVisibleForRead() { return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_READ) != 0; } private boolean isVisibleForWrite() { return (mountFlags & MOUNT_FLAG_VISIBLE_FOR_WRITE) != 0; } @UnsupportedAppUsage public boolean isVisible() { return (mountFlags & MOUNT_FLAG_VISIBLE) != 0; return isVisibleForRead() || isVisibleForWrite(); } public boolean isVisibleForUser(int userId) { if ((type == TYPE_PUBLIC || type == TYPE_STUB || type == TYPE_EMULATED) && mountUserId == userId) { return isVisible(); } private boolean isVolumeSupportedForUser(int userId) { if (mountUserId != userId) { 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(); } /** * Returns {@code true} if this volume is the primary emulated volume for {@code userId}, Loading @@ -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 Loading
packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
services/core/java/com/android/server/StorageManagerService.java +7 −7 Original line number Diff line number Diff line Loading @@ -1223,7 +1223,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(); Loading Loading @@ -1570,7 +1570,7 @@ class StorageManagerService extends IStorageManager.Stub || 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(); } Loading @@ -1580,13 +1580,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; Loading @@ -1597,7 +1597,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(); Loading Loading @@ -1744,7 +1744,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(); Loading Loading @@ -3783,7 +3783,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; Loading