Open file directly when external storage emulated.

For the special case where (1) a file lives on external storage,
(2) it's being opened for reading, and (3) external storage is
emulated, this change rewrites the path at the last moment to open
the file directly from internal storage.

This avoids the overhead of forcing I/O through the emulated storage
layer when we've already asserted the caller has permission. This is
only possible because MediaProvider is running with the media_rw GID.

Bug: 6539384
Change-Id: Ieda6b30e819340d46466f8db2e34b47bbf06ee08
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 266233a..22b4158 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -19,7 +19,7 @@
 import static android.Manifest.permission.ACCESS_CACHE_FILESYSTEM;
 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
-import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
 import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
 
 import android.app.SearchManager;
@@ -4281,7 +4281,7 @@
         final int modeBits = ContentResolver.modeToMode(uri, mode);
         final boolean isWrite = (modeBits & MODE_WRITE_ONLY) != 0;
 
-        final File file = queryForDataFile(uri);
+        File file = queryForDataFile(uri);
         final String path;
         try {
             path = file.getCanonicalPath();
@@ -4297,6 +4297,13 @@
                 getContext().enforceCallingOrSelfPermission(
                         WRITE_EXTERNAL_STORAGE, "External path: " + path);
             }
+
+            // bypass emulation layer when file is opened for reading
+            if (modeBits == MODE_READ_ONLY && Environment.isExternalStorageEmulated()) {
+                file = new File(Environment.getMediaStorageDirectory(), path.substring(
+                        sExternalPath.length()));
+            }
+
         } else if (path.startsWith(sCachePath)) {
             getContext().enforceCallingOrSelfPermission(
                     ACCESS_CACHE_FILESYSTEM, "Cache path: " + path);