Merge "Split VOLUME_EXTERNAL and VOLUME_PRIMARY." into qt-dev am: 457296a084

am: 9949446935

Change-Id: I56e9d0b17fb7031c972cfa3de500b3bf15aae7e2
This commit is contained in:
Jeff Sharkey
2019-04-10 12:26:36 -07:00
committed by android-build-merger
5 changed files with 100 additions and 40 deletions

View File

@@ -38478,8 +38478,8 @@ package android.provider {
public final class MediaStore {
ctor public MediaStore();
method @NonNull public static java.util.Set<java.lang.String> getAllVolumeNames(@NonNull android.content.Context);
method @Nullable public static android.net.Uri getDocumentUri(@NonNull android.content.Context, @NonNull android.net.Uri);
method @NonNull public static java.util.Set<java.lang.String> getExternalVolumeNames(@NonNull android.content.Context);
method public static android.net.Uri getMediaScannerUri();
method @Nullable public static android.net.Uri getMediaUri(@NonNull android.content.Context, @NonNull android.net.Uri);
method @NonNull public static String getVersion(@NonNull android.content.Context);
@@ -38523,6 +38523,7 @@ package android.provider {
field public static final String META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE = "android.media.still_image_camera_preview_service";
field public static final String UNKNOWN_STRING = "<unknown>";
field public static final String VOLUME_EXTERNAL = "external";
field public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";
field public static final String VOLUME_INTERNAL = "internal";
}
@@ -38771,6 +38772,7 @@ package android.provider {
field public static final String RELATIVE_PATH = "relative_path";
field public static final String SIZE = "_size";
field public static final String TITLE = "title";
field public static final String VOLUME_NAME = "volume_name";
field public static final String WIDTH = "width";
}

View File

@@ -514,6 +514,7 @@ package android.provider {
public final class MediaStore {
method @Deprecated @NonNull public static android.net.Uri createPending(@NonNull android.content.Context, @NonNull android.provider.MediaStore.PendingParams);
method @Deprecated @NonNull public static java.util.Set<java.lang.String> getAllVolumeNames(@NonNull android.content.Context);
method @Deprecated @NonNull public static android.provider.MediaStore.PendingSession openPending(@NonNull android.content.Context, @NonNull android.net.Uri);
method @Deprecated @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);

View File

@@ -1130,7 +1130,7 @@ public class StorageManager {
public @NonNull StorageVolume getStorageVolume(@NonNull Uri uri) {
final String volumeName = MediaStore.getVolumeName(uri);
switch (volumeName) {
case MediaStore.VOLUME_EXTERNAL:
case MediaStore.VOLUME_EXTERNAL_PRIMARY:
return getPrimaryStorageVolume();
default:
for (StorageVolume vol : getStorageVolumes()) {

View File

@@ -264,9 +264,14 @@ public final class StorageVolume implements Parcelable {
return mFsUuid;
}
/** {@hide} */
public static @Nullable String normalizeUuid(@Nullable String fsUuid) {
return fsUuid != null ? fsUuid.toLowerCase(Locale.US) : null;
}
/** {@hide} */
public @Nullable String getNormalizedUuid() {
return mFsUuid != null ? mFsUuid.toLowerCase(Locale.US) : null;
return normalizeUuid(mFsUuid);
}
/**

View File

@@ -102,20 +102,40 @@ public final class MediaStore {
public static final @NonNull Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
/**
* Volume name used for content on "internal" storage of device. This
* volume contains media distributed with the device, such as built-in
* ringtones and wallpapers.
* Synthetic volume name that provides a view of all content across the
* "internal" storage of the device.
* <p>
* This synthetic volume provides a merged view of all media distributed
* with the device, such as built-in ringtones and wallpapers.
* <p>
* Because this is a synthetic volume, you can't insert new content into
* this volume.
*/
public static final String VOLUME_INTERNAL = "internal";
/**
* Volume name used for content on "external" storage of device. This only
* includes media on the primary shared storage device; the contents of any
* secondary storage devices can be obtained using
* {@link #getAllVolumeNames(Context)}.
* Synthetic volume name that provides a view of all content across the
* "external" storage of the device.
* <p>
* This synthetic volume provides a merged view of all media across all
* currently attached external storage devices.
* <p>
* Because this is a synthetic volume, you can't insert new content into
* this volume. Instead, you can insert content into a specific storage
* volume obtained from {@link #getExternalVolumeNames(Context)}.
*/
public static final String VOLUME_EXTERNAL = "external";
/**
* Specific volume name that represents the primary external storage device
* at {@link Environment#getExternalStorageDirectory()}.
* <p>
* This volume may not always be available, such as when the user has
* ejected the device. You can find a list of all specific volume names
* using {@link #getExternalVolumeNames(Context)}.
*/
public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";
/** {@hide} */
public static final String SCAN_FILE_CALL = "scan_file";
/** {@hide} */
@@ -1036,6 +1056,16 @@ public final class MediaStore {
@Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
public static final String OWNER_PACKAGE_NAME = "owner_package_name";
/**
* Volume name of the specific storage device where this media item is
* persisted. The value is typically one of the volume names returned
* from {@link MediaStore#getExternalVolumeNames(Context)}.
* <p>
* This is a read-only column that is automatically computed.
*/
@Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
public static final String VOLUME_NAME = "volume_name";
/**
* Relative path of this media item within the storage device where it
* is persisted. For example, an item stored at
@@ -1408,7 +1438,7 @@ public final class MediaStore {
final StorageVolume sv = sm.getStorageVolume(path);
if (sv != null) {
if (sv.isPrimary()) {
return VOLUME_EXTERNAL;
return VOLUME_EXTERNAL_PRIMARY;
} else {
return checkArgumentVolumeName(sv.getNormalizedUuid());
}
@@ -1710,7 +1740,7 @@ public final class MediaStore {
String stringUrl = null; /* value to be returned */
try {
url = cr.insert(EXTERNAL_CONTENT_URI, values);
url = cr.insert(getContentUri(VOLUME_EXTERNAL_PRIMARY), values);
if (source != null) {
try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(
@@ -3224,22 +3254,29 @@ public final class MediaStore {
}
}
/**
* Return list of all volume names currently available. This includes a
* unique name for each shared storage device that is currently mounted.
* <p>
* Each name can be passed to APIs like
* {@link MediaStore.Images.Media#getContentUri(String)} to query media at
* that location.
*/
/** @removed */
@Deprecated
public static @NonNull Set<String> getAllVolumeNames(@NonNull Context context) {
return getExternalVolumeNames(context);
}
/**
* Return list of all specific volume names that make up
* {@link #VOLUME_EXTERNAL}. This includes a unique volume name for each
* shared storage device that is currently attached, which typically
* includes {@link MediaStore#VOLUME_EXTERNAL_PRIMARY}.
* <p>
* Each specific volume name can be passed to APIs like
* {@link MediaStore.Images.Media#getContentUri(String)} to interact with
* media on that storage device.
*/
public static @NonNull Set<String> getExternalVolumeNames(@NonNull Context context) {
final StorageManager sm = context.getSystemService(StorageManager.class);
final Set<String> volumeNames = new ArraySet<>();
volumeNames.add(VOLUME_INTERNAL);
for (VolumeInfo vi : sm.getVolumes()) {
if (vi.isVisibleForUser(UserHandle.myUserId()) && vi.isMountedReadable()) {
if (vi.isPrimary()) {
volumeNames.add(VOLUME_EXTERNAL);
volumeNames.add(VOLUME_EXTERNAL_PRIMARY);
} else {
volumeNames.add(vi.getNormalizedFsUuid());
}
@@ -3270,6 +3307,8 @@ public final class MediaStore {
return volumeName;
} else if (VOLUME_EXTERNAL.equals(volumeName)) {
return volumeName;
} else if (VOLUME_EXTERNAL_PRIMARY.equals(volumeName)) {
return volumeName;
}
// When not one of the well-known values above, it must be a hex UUID
@@ -3285,8 +3324,9 @@ public final class MediaStore {
}
/**
* Return path where the given volume is mounted. Not valid for
* {@link #VOLUME_INTERNAL}.
* Return path where the given specific volume is mounted. Not valid for
* {@link #VOLUME_INTERNAL} or {@link #VOLUME_EXTERNAL}, since those are
* broad collections that cover many paths.
*
* @hide
*/
@@ -3297,8 +3337,12 @@ public final class MediaStore {
throw new IllegalArgumentException();
}
if (VOLUME_EXTERNAL.equals(volumeName)) {
return Environment.getExternalStorageDirectory();
switch (volumeName) {
case VOLUME_INTERNAL:
case VOLUME_EXTERNAL:
throw new FileNotFoundException(volumeName + " has no associated path");
case VOLUME_EXTERNAL_PRIMARY:
return Environment.getExternalStorageDirectory();
}
final StorageManager sm = AppGlobals.getInitialApplication()
@@ -3328,23 +3372,31 @@ public final class MediaStore {
throw new IllegalArgumentException();
}
final Context context = AppGlobals.getInitialApplication();
final UserManager um = context.getSystemService(UserManager.class);
final ArrayList<File> res = new ArrayList<>();
if (VOLUME_INTERNAL.equals(volumeName)) {
addCanoncialFile(res, new File(Environment.getRootDirectory(), "media"));
addCanoncialFile(res, new File(Environment.getOemDirectory(), "media"));
addCanoncialFile(res, new File(Environment.getProductDirectory(), "media"));
addCanonicalFile(res, new File(Environment.getRootDirectory(), "media"));
addCanonicalFile(res, new File(Environment.getOemDirectory(), "media"));
addCanonicalFile(res, new File(Environment.getProductDirectory(), "media"));
} else if (VOLUME_EXTERNAL.equals(volumeName)) {
for (String exactVolume : getExternalVolumeNames(context)) {
addCanonicalFile(res, getVolumePath(exactVolume));
}
if (um.isDemoUser()) {
addCanonicalFile(res, Environment.getDataPreloadsMediaDirectory());
}
} else {
addCanoncialFile(res, getVolumePath(volumeName));
final UserManager um = AppGlobals.getInitialApplication()
.getSystemService(UserManager.class);
if (VOLUME_EXTERNAL.equals(volumeName) && um.isDemoUser()) {
addCanoncialFile(res, Environment.getDataPreloadsMediaDirectory());
addCanonicalFile(res, getVolumePath(volumeName));
if (VOLUME_EXTERNAL_PRIMARY.equals(volumeName) && um.isDemoUser()) {
addCanonicalFile(res, Environment.getDataPreloadsMediaDirectory());
}
}
return res;
}
private static void addCanoncialFile(List<File> list, File file) {
private static void addCanonicalFile(List<File> list, File file) {
try {
list.add(file.getCanonicalFile());
} catch (IOException e) {
@@ -3382,12 +3434,12 @@ public final class MediaStore {
* <p>
* No other assumptions should be made about the meaning of the version.
* <p>
* This method returns the version for {@link MediaStore#VOLUME_EXTERNAL};
* to obtain a version for a different volume, use
* {@link #getVersion(Context, String)}.
* This method returns the version for
* {@link MediaStore#VOLUME_EXTERNAL_PRIMARY}; to obtain a version for a
* different volume, use {@link #getVersion(Context, String)}.
*/
public static @NonNull String getVersion(@NonNull Context context) {
return getVersion(context, VOLUME_EXTERNAL);
return getVersion(context, VOLUME_EXTERNAL_PRIMARY);
}
/**
@@ -3401,7 +3453,7 @@ public final class MediaStore {
*
* @param volumeName specific volume to obtain an opaque version string for.
* Must be one of the values returned from
* {@link #getAllVolumeNames(Context)}.
* {@link #getExternalVolumeNames(Context)}.
*/
public static @NonNull String getVersion(@NonNull Context context, @NonNull String volumeName) {
final ContentResolver resolver = context.getContentResolver();