Merge "Revert "APIs for reviewing, listing volumes, hashes.""
diff --git a/api/current.txt b/api/current.txt
index 721fe67..8a50ec7 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -36900,7 +36900,6 @@
 
   public final class MediaStore {
     ctor public MediaStore();
-    method public static java.util.Set<java.lang.String> getAllVolumeNames(android.content.Context);
     method public static android.net.Uri getDocumentUri(android.content.Context, android.net.Uri);
     method public static android.net.Uri getMediaScannerUri();
     method public static android.net.Uri getMediaUri(android.content.Context, android.net.Uri);
@@ -36908,12 +36907,9 @@
     method public static java.lang.String getVolumeName(android.net.Uri);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
     field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
-    field public static final java.lang.String ACTION_REVIEW = "android.provider.action.REVIEW";
-    field public static final java.lang.String ACTION_REVIEW_SECURE = "android.provider.action.REVIEW_SECURE";
     field public static final java.lang.String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";
     field public static final java.lang.String AUTHORITY = "media";
     field public static final android.net.Uri AUTHORITY_URI;
-    field public static final java.lang.String EXTRA_BRIGHTNESS = "android.provider.extra.BRIGHTNESS";
     field public static final java.lang.String EXTRA_DURATION_LIMIT = "android.intent.extra.durationLimit";
     field public static final java.lang.String EXTRA_FINISH_ON_COMPLETION = "android.intent.extra.finishOnCompletion";
     field public static final java.lang.String EXTRA_FULL_SCREEN = "android.intent.extra.fullScreen";
@@ -37039,7 +37035,7 @@
   public static final class MediaStore.Audio.Media implements android.provider.MediaStore.Audio.AudioColumns {
     ctor public MediaStore.Audio.Media();
     method public static android.net.Uri getContentUri(java.lang.String);
-    method public static deprecated android.net.Uri getContentUriForPath(java.lang.String);
+    method public static android.net.Uri getContentUriForPath(java.lang.String);
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/audio";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "title_key";
     field public static final java.lang.String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/audio";
@@ -37161,7 +37157,6 @@
     field public static final java.lang.String DATE_ADDED = "date_added";
     field public static final java.lang.String DATE_MODIFIED = "date_modified";
     field public static final java.lang.String DISPLAY_NAME = "_display_name";
-    field public static final java.lang.String HASH = "_hash";
     field public static final java.lang.String HEIGHT = "height";
     field public static final java.lang.String MIME_TYPE = "mime_type";
     field public static final java.lang.String SIZE = "_size";
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 4c5cfd9..1fce8e6 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -21,8 +21,6 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.UnsupportedAppUsage;
-import android.app.Activity;
-import android.app.AppGlobals;
 import android.content.ClipData;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
@@ -39,27 +37,21 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.os.Environment;
 import android.os.OperationCanceledException;
 import android.os.RemoteException;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
-import android.os.storage.VolumeInfo;
 import android.service.media.CameraPrewarmService;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 
-import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 /**
  * The Media provider contains meta data for all available media on both internal
@@ -73,8 +65,7 @@
     /** A content:// style uri to the authority for the media provider */
     public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
 
-    private static final String VOLUME_INTERNAL = "internal";
-    private static final String VOLUME_EXTERNAL = "external";
+    private static final String CONTENT_AUTHORITY_SLASH = "content://" + AUTHORITY + "/";
 
     /**
      * The method name used by the media scanner and mtp to tell the media provider to
@@ -275,7 +266,7 @@
      * any personal content like existing photos or videos on the device. The
      * applications should be careful not to share any photo or video with other
      * applications or internet. The activity should use {@link
-     * Activity#setShowWhenLocked} to display
+     * android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} to display
      * on top of the lock screen while secured. There is no activity stack when
      * this flag is used, so launching more than one activity is strongly
      * discouraged.
@@ -320,8 +311,8 @@
      * it when the device is secured (e.g. with a pin, password, pattern, or face unlock).
      * Applications responding to this intent must not expose any personal content like existing
      * photos or videos on the device. The applications should be careful not to share any photo
-     * or video with other applications or Internet. The activity should use {@link
-     * Activity#setShowWhenLocked} to display on top of the
+     * or video with other applications or internet. The activity should use {@link
+     * android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} to display on top of the
      * lock screen while secured. There is no activity stack when this flag is used, so
      * launching more than one activity is strongly discouraged.
      * <p>
@@ -373,55 +364,6 @@
     public final static String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";
 
     /**
-     * Standard action that can be sent to review the given media file.
-     * <p>
-     * The launched application is expected to provide a large-scale view of the
-     * given media file, while allowing the user to quickly access other
-     * recently captured media files.
-     * <p>
-     * Input: {@link Intent#getData} is URI of the primary media item to
-     * initially display.
-     *
-     * @see #ACTION_REVIEW_SECURE
-     * @see #EXTRA_BRIGHTNESS
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public final static String ACTION_REVIEW = "android.provider.action.REVIEW";
-
-    /**
-     * Standard action that can be sent to review the given media file when the
-     * device is secured (e.g. with a pin, password, pattern, or face unlock).
-     * The applications should be careful not to share any media with other
-     * applications or Internet. The activity should use
-     * {@link Activity#setShowWhenLocked} to display on top of the lock screen
-     * while secured. There is no activity stack when this flag is used, so
-     * launching more than one activity is strongly discouraged.
-     * <p>
-     * The launched application is expected to provide a large-scale view of the
-     * given primary media file, while only allowing the user to quickly access
-     * other media from an explicit secondary list.
-     * <p>
-     * Input: {@link Intent#getData} is URI of the primary media item to
-     * initially display. {@link Intent#getClipData} is the limited list of
-     * secondary media items that the user is allowed to review. If
-     * {@link Intent#getClipData} is undefined, then no other media access
-     * should be allowed.
-     *
-     * @see #EXTRA_BRIGHTNESS
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public final static String ACTION_REVIEW_SECURE = "android.provider.action.REVIEW_SECURE";
-
-    /**
-     * When defined, the launched application is requested to set the given
-     * brightness value via
-     * {@link android.view.WindowManager.LayoutParams#screenBrightness} to help
-     * ensure a smooth transition when launching {@Link #ACTION_REVIEW} or
-     * {@link #ACTION_REVIEW_SECURE} intents.
-     */
-    public final static String EXTRA_BRIGHTNESS = "android.provider.extra.BRIGHTNESS";
-
-    /**
      * The name of the Intent-extra used to control the quality of a recorded video. This is an
      * integer property. Currently value 0 means low quality, suitable for MMS messages, and
      * value 1 means high quality. In the future other quality levels may be added.
@@ -478,23 +420,6 @@
         public static final String DATA = "_data";
 
         /**
-         * Hash of the file on disk.
-         * <p>
-         * Contains a 20-byte binary blob which is the SHA-1 hash of the file as
-         * persisted on disk. For performance reasons, the hash may not be
-         * immediately available, in which case a {@code NULL} value will be
-         * returned. If the underlying file is modified, this value will be
-         * cleared and recalculated.
-         * <p>
-         * If you require the hash of a specific item, you can call
-         * {@link ContentResolver#canonicalize(Uri)}, which will block until the
-         * hash is calculated.
-         * <p>
-         * Type: BLOB
-         */
-        public static final String HASH = "_hash";
-
-        /**
          * The size of the file in bytes
          * <P>Type: INTEGER (long)</P>
          */
@@ -584,7 +509,8 @@
          * @return the URI to the files table on the given volume
          */
         public static Uri getContentUri(String volumeName) {
-            return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("file").build();
+            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                    "/file");
         }
 
         /**
@@ -597,7 +523,8 @@
          */
         public static final Uri getContentUri(String volumeName,
                 long rowId) {
-            return ContentUris.withAppendedId(getContentUri(volumeName), rowId);
+            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
+                    + "/file/" + rowId);
         }
 
         /**
@@ -606,7 +533,8 @@
          */
         @UnsupportedAppUsage
         public static Uri getMtpObjectsUri(String volumeName) {
-            return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("object").build();
+            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                    "/object");
         }
 
         /**
@@ -616,7 +544,8 @@
         @UnsupportedAppUsage
         public static final Uri getMtpObjectsUri(String volumeName,
                 long fileId) {
-            return ContentUris.withAppendedId(getMtpObjectsUri(volumeName), fileId);
+            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
+                    + "/object/" + fileId);
         }
 
         /**
@@ -626,8 +555,8 @@
         @UnsupportedAppUsage
         public static final Uri getMtpReferencesUri(String volumeName,
                 long fileId) {
-            return getMtpObjectsUri(volumeName, fileId).buildUpon().appendPath("references")
-                    .build();
+            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
+                    + "/object/" + fileId + "/references");
         }
 
         /**
@@ -635,7 +564,7 @@
          * @hide
          */
         public static final Uri getDirectoryUri(String volumeName) {
-            return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("dir").build();
+            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/dir");
         }
 
         /**
@@ -848,7 +777,7 @@
              * <P>Type: INTEGER</P>
              *
              * @deprecated all thumbnails should be obtained via
-             *             {@link MediaStore.Images.Thumbnails#getThumbnail}, as this
+             *             {@link Images.Thumbnails#getThumbnail}, as this
              *             value is no longer supported.
              */
             @Deprecated
@@ -992,8 +921,8 @@
              * @return the URI to the image media table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("images")
-                        .appendPath("media").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/images/media");
             }
 
             /**
@@ -1134,8 +1063,8 @@
              * @return the URI to the image media table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("images")
-                        .appendPath("thumbnails").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/images/thumbnails");
             }
 
             /**
@@ -1442,29 +1371,14 @@
              * @return the URI to the audio media table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
-                        .appendPath("media").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/audio/media");
             }
 
-            /**
-             * Get the content:// style URI for the given audio media file.
-             *
-             * @deprecated Apps may not have filesystem permissions to directly
-             *             access this path.
-             */
-            public static @Nullable Uri getContentUriForPath(@NonNull String path) {
-                final StorageManager sm = AppGlobals.getInitialApplication()
-                        .getSystemService(StorageManager.class);
-                final StorageVolume sv = sm.getStorageVolume(new File(path));
-                if (sv != null) {
-                    if (sv.isPrimary()) {
-                        return EXTERNAL_CONTENT_URI;
-                    } else {
-                        return getContentUri(sv.getUuid());
-                    }
-                } else {
-                    return INTERNAL_CONTENT_URI;
-                }
+            public static Uri getContentUriForPath(String path) {
+                return (path.startsWith(
+                        Environment.getStorageDirectory().getAbsolutePath() + "/")
+                        ? EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI);
             }
 
             /**
@@ -1540,8 +1454,8 @@
              * @return the URI to the audio genres table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
-                        .appendPath("genres").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/audio/genres");
             }
 
             /**
@@ -1553,8 +1467,8 @@
              * with the given the volume and audioID
              */
             public static Uri getContentUriForAudioId(String volumeName, int audioId) {
-                return ContentUris.withAppendedId(Audio.Media.getContentUri(volumeName), audioId)
-                        .buildUpon().appendPath("genres").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/audio/media/" + audioId + "/genres");
             }
 
             /**
@@ -1590,10 +1504,10 @@
              */
             public static final class Members implements AudioColumns {
 
-                public static final Uri getContentUri(String volumeName, long genreId) {
-                    return ContentUris
-                            .withAppendedId(Audio.Genres.getContentUri(volumeName), genreId)
-                            .buildUpon().appendPath("members").build();
+                public static final Uri getContentUri(String volumeName,
+                        long genreId) {
+                    return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
+                            + "/audio/genres/" + genreId + "/members");
                 }
 
                 /**
@@ -1681,8 +1595,8 @@
              * @return the URI to the audio playlists table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
-                        .appendPath("playlists").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/audio/playlists");
             }
 
             /**
@@ -1717,10 +1631,10 @@
              * Sub-directory of each playlist containing all members.
              */
             public static final class Members implements AudioColumns {
-                public static final Uri getContentUri(String volumeName, long playlistId) {
-                    return ContentUris
-                            .withAppendedId(Audio.Playlists.getContentUri(volumeName), playlistId)
-                            .buildUpon().appendPath("members").build();
+                public static final Uri getContentUri(String volumeName,
+                        long playlistId) {
+                    return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
+                            + "/audio/playlists/" + playlistId + "/members");
                 }
 
                 /**
@@ -1820,8 +1734,8 @@
              * @return the URI to the audio artists table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
-                        .appendPath("artists").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/audio/artists");
             }
 
             /**
@@ -1857,10 +1771,10 @@
              * a song by the artist appears.
              */
             public static final class Albums implements AlbumColumns {
-                public static final Uri getContentUri(String volumeName,long artistId) {
-                    return ContentUris
-                            .withAppendedId(Audio.Artists.getContentUri(volumeName), artistId)
-                            .buildUpon().appendPath("albums").build();
+                public static final Uri getContentUri(String volumeName,
+                        long artistId) {
+                    return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
+                            + "/audio/artists/" + artistId + "/albums");
                 }
             }
         }
@@ -1955,8 +1869,8 @@
              * @return the URI to the audio albums table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
-                        .appendPath("albums").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/audio/albums");
             }
 
             /**
@@ -2090,7 +2004,7 @@
              * <P>Type: INTEGER</P>
              *
              * @deprecated all thumbnails should be obtained via
-             *             {@link MediaStore.Images.Thumbnails#getThumbnail}, as this
+             *             {@link Images.Thumbnails#getThumbnail}, as this
              *             value is no longer supported.
              */
             @Deprecated
@@ -2150,8 +2064,8 @@
              * @return the URI to the video media table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("video")
-                        .appendPath("media").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/video/media");
             }
 
             /**
@@ -2274,8 +2188,8 @@
              * @return the URI to the image media table on the given volume
              */
             public static Uri getContentUri(String volumeName) {
-                return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("video")
-                        .appendPath("thumbnails").build();
+                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
+                        "/video/thumbnails");
             }
 
             /**
@@ -2343,30 +2257,6 @@
     }
 
     /**
-     * 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.
-     */
-    public static @NonNull Set<String> getAllVolumeNames(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.isMountedReadable()) {
-                if (vi.isPrimary()) {
-                    volumeNames.add(VOLUME_EXTERNAL);
-                } else {
-                    volumeNames.add(vi.getFsUuid());
-                }
-            }
-        }
-        return volumeNames;
-    }
-
-    /**
      * Return the volume name that the given {@link Uri} references.
      */
     public static @NonNull String getVolumeName(@NonNull Uri uri) {
@@ -2382,7 +2272,7 @@
      * Uri for querying the state of the media scanner.
      */
     public static Uri getMediaScannerUri() {
-        return AUTHORITY_URI.buildUpon().appendPath("none").appendPath("media_scanner").build();
+        return Uri.parse(CONTENT_AUTHORITY_SLASH + "none/media_scanner");
     }
 
     /**
@@ -2407,10 +2297,16 @@
      * @return A version string, or null if the version could not be determined.
      */
     public static String getVersion(Context context) {
-        final Uri uri = AUTHORITY_URI.buildUpon().appendPath("none").appendPath("version").build();
-        try (Cursor c = context.getContentResolver().query(uri, null, null, null, null)) {
-            if (c.moveToFirst()) {
-                return c.getString(0);
+        Cursor c = context.getContentResolver().query(
+                Uri.parse(CONTENT_AUTHORITY_SLASH + "none/version"),
+                null, null, null, null);
+        if (c != null) {
+            try {
+                if (c.moveToFirst()) {
+                    return c.getString(0);
+                }
+            } finally {
+                c.close();
             }
         }
         return null;