Merge "Merge "Split VOLUME_EXTERNAL and VOLUME_PRIMARY." into qt-dev am: 457296a084 am: 9949446935"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f83e9ddb63
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user