Public APIs for ID-specific Uris, misc items.
We have getContentUri() for entire collections of items, but we
only have ID-specific overloads for some of the MediaStore classes;
let's get them all added for consistency.
Remove primary/secondary directory logic, which was replaced by
new RELATIVE_PATH column before Q launched.
Bug: 137890034
Test: atest --test-mapping packages/providers/MediaProvider
Exempt-From-Owner-Approval: trivial API refactoring
Change-Id: Iae4e7fe57adff071c35af459e31223a1fd05fef2
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 29acd5d..0c6a935 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -64,6 +64,16 @@
public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
/**
+ * The MIME type for data whose type is otherwise unknown.
+ * <p>
+ * Per RFC 2046, the "application" media type is to be used for discrete
+ * data which do not fit in any of the other categories, and the
+ * "octet-stream" subtype is used to indicate that a body contains arbitrary
+ * binary data.
+ */
+ public static final String MIMETYPE_UNKNOWN = "application/octet-stream";
+
+ /**
* The name of the extra used to define a component name when copying/dragging
* an app icon from Launcher.
* <p>
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 9c86359..1f48393 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -475,11 +475,9 @@
*/
public static final String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*";
- /**
- * Default MIME type for files whose type is otherwise unknown.
- * @hide
- */
- public static final String MIME_TYPE_DEFAULT = "application/octet-stream";
+ /** {@hide} */
+ @Deprecated
+ public static final String MIME_TYPE_DEFAULT = ClipDescription.MIMETYPE_UNKNOWN;
/** @hide */
@UnsupportedAppUsage
diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java
index 8223a0b..bdd1f4c 100644
--- a/core/java/android/content/ContentValues.java
+++ b/core/java/android/content/ContentValues.java
@@ -259,8 +259,6 @@
* Indicates whether this collection is empty.
*
* @return true iff size == 0
- * {@hide}
- * TODO: consider exposing this new method publicly
*/
public boolean isEmpty() {
return mMap.isEmpty();
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 3462d1f..6d5fe53b 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -168,8 +168,11 @@
return DIR_ANDROID_ROOT;
}
- /** {@hide} */
- @TestApi
+ /**
+ * Return root directory where all external storage devices will be mounted.
+ * For example, {@link #getExternalStorageDirectory()} will appear under
+ * this location.
+ */
public static @NonNull File getStorageDirectory() {
return DIR_ANDROID_STORAGE;
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index a959913f..079a42d 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -553,7 +553,7 @@
* By default no pending items are returned.
*
* @see MediaColumns#IS_PENDING
- * @see MediaStore#setIncludePending(Uri)
+ * @see MediaStore#getIncludePending(Uri)
*/
public static @NonNull Uri setIncludePending(@NonNull Uri uri) {
return setIncludePending(uri.buildUpon()).build();
@@ -565,6 +565,17 @@
}
/**
+ * Return if any pending media items should be included in calls such as
+ * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
+ *
+ * @see MediaColumns#IS_PENDING
+ * @see MediaStore#setIncludePending(Uri)
+ */
+ public static boolean getIncludePending(@NonNull Uri uri) {
+ return parseBoolean(uri.getQueryParameter(MediaStore.PARAM_INCLUDE_PENDING));
+ }
+
+ /**
* Update the given {@link Uri} to also include any trashed media items from
* calls such as
* {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
@@ -594,12 +605,24 @@
* {@link UnsupportedOperationException} will be thrown when the returned
* {@link Uri} is used, such as when the caller doesn't hold
* {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}.
+ *
+ * @see MediaStore#getRequireOriginal(Uri)
*/
public static @NonNull Uri setRequireOriginal(@NonNull Uri uri) {
return uri.buildUpon().appendQueryParameter(PARAM_REQUIRE_ORIGINAL, "1").build();
}
/**
+ * Return if the caller requires the original file contents when calling
+ * {@link ContentResolver#openFileDescriptor(Uri, String)}.
+ *
+ * @see MediaStore#setRequireOriginal(Uri)
+ */
+ public static boolean getRequireOriginal(@NonNull Uri uri) {
+ return parseBoolean(uri.getQueryParameter(MediaStore.PARAM_REQUIRE_ORIGINAL));
+ }
+
+ /**
* Create a new pending media item using the given parameters. Pending items
* are expected to have a short lifetime, and owners should either
* {@link PendingSession#publish()} or {@link PendingSession#abandon()} a
@@ -666,45 +689,11 @@
(System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS) / 1000);
}
- /**
- * Optionally set the primary directory under which this pending item
- * should be persisted. Only specific well-defined directories from
- * {@link Environment} are allowed based on the media type being
- * inserted.
- * <p>
- * For example, when creating pending {@link MediaStore.Images.Media}
- * items, only {@link Environment#DIRECTORY_PICTURES} or
- * {@link Environment#DIRECTORY_DCIM} are allowed.
- * <p>
- * You may leave this value undefined to store the media in a default
- * location. For example, when this value is left undefined, pending
- * {@link MediaStore.Audio.Media} items are stored under
- * {@link Environment#DIRECTORY_MUSIC}.
- *
- * @see MediaColumns#PRIMARY_DIRECTORY
- */
- public void setPrimaryDirectory(@Nullable String primaryDirectory) {
- if (primaryDirectory == null) {
- this.insertValues.remove(MediaColumns.PRIMARY_DIRECTORY);
+ public void setRelativePath(@Nullable String relativePath) {
+ if (relativePath == null) {
+ this.insertValues.remove(MediaColumns.RELATIVE_PATH);
} else {
- this.insertValues.put(MediaColumns.PRIMARY_DIRECTORY, primaryDirectory);
- }
- }
-
- /**
- * Optionally set the secondary directory under which this pending item
- * should be persisted. Any valid directory name is allowed.
- * <p>
- * You may leave this value undefined to store the media as a direct
- * descendant of the {@link #setPrimaryDirectory(String)} location.
- *
- * @see MediaColumns#SECONDARY_DIRECTORY
- */
- public void setSecondaryDirectory(@Nullable String secondaryDirectory) {
- if (secondaryDirectory == null) {
- this.insertValues.remove(MediaColumns.SECONDARY_DIRECTORY);
- } else {
- this.insertValues.put(MediaColumns.SECONDARY_DIRECTORY, secondaryDirectory);
+ this.insertValues.put(MediaColumns.RELATIVE_PATH, relativePath);
}
}
@@ -1470,7 +1459,14 @@
.appendPath("downloads").build();
}
- /** @hide */
+ /**
+ * Get the content:// style URI for a single row in the downloads table
+ * on the given volume.
+ *
+ * @param volumeName the name of the volume to get the URI for
+ * @param id the download to get the URI for
+ * @return the URI to the downloads table on the given volume
+ */
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
return ContentUris.withAppendedId(getContentUri(volumeName), id);
}
@@ -1795,7 +1791,14 @@
.appendPath("media").build();
}
- /** @hide */
+ /**
+ * Get the content:// style URI for a single row in the images table
+ * on the given volume.
+ *
+ * @param volumeName the name of the volume to get the URI for
+ * @param id the image to get the URI for
+ * @return the URI to the images table on the given volume
+ */
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
return ContentUris.withAppendedId(getContentUri(volumeName), id);
}
@@ -2282,7 +2285,14 @@
.appendPath("media").build();
}
- /** @hide */
+ /**
+ * Get the content:// style URI for a single row in the audio table
+ * on the given volume.
+ *
+ * @param volumeName the name of the volume to get the URI for
+ * @param id the audio to get the URI for
+ * @return the URI to the audio table on the given volume
+ */
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
return ContentUris.withAppendedId(getContentUri(volumeName), id);
}
@@ -3031,7 +3041,14 @@
.appendPath("media").build();
}
- /** @hide */
+ /**
+ * Get the content:// style URI for a single row in the videos table
+ * on the given volume.
+ *
+ * @param volumeName the name of the volume to get the URI for
+ * @param id the video to get the URI for
+ * @return the URI to the videos table on the given volume
+ */
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
return ContentUris.withAppendedId(getContentUri(volumeName), id);
}
@@ -3296,6 +3313,13 @@
return volumeName;
}
+ private static boolean parseBoolean(@Nullable String value) {
+ if (value == null) return false;
+ if ("1".equals(value)) return true;
+ if ("true".equalsIgnoreCase(value)) return true;
+ return false;
+ }
+
/**
* Return path where the given specific volume is mounted. Not valid for
* {@link #VOLUME_INTERNAL} or {@link #VOLUME_EXTERNAL}, since those are