Merge "Import translations. DO NOT MERGE ANYWHERE" into sc-dev
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 7a1c5d0..aaeb8a7 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -67,6 +67,7 @@
 import static com.android.providers.media.util.FileUtils.DEFAULT_FOLDER_NAMES;
 import static com.android.providers.media.util.FileUtils.PATTERN_PENDING_FILEPATH_FOR_SQL;
 import static com.android.providers.media.util.FileUtils.extractDisplayName;
+import static com.android.providers.media.util.FileUtils.extractFileExtension;
 import static com.android.providers.media.util.FileUtils.extractFileName;
 import static com.android.providers.media.util.FileUtils.extractPathOwnerPackageName;
 import static com.android.providers.media.util.FileUtils.extractRelativePath;
@@ -1523,7 +1524,7 @@
 
         final String transformsSyntheticDir = getStorageRootPathForUid(uid) + "/"
                 + REDACTED_URI_DIR;
-        final String fileName = extractDisplayName(path);
+        final String fileName = extractFileName(path);
         return fileName != null && path.toLowerCase(Locale.ROOT).startsWith(
                 transformsSyntheticDir.toLowerCase(Locale.ROOT)) && fileName.startsWith(
                 REDACTED_URI_ID_PREFIX) && fileName.length() == REDACTED_URI_ID_SIZE;
@@ -1538,7 +1539,7 @@
 
     private FileLookupResult getFileLookupResultsForRedactedUriPath(int uid, @NonNull String path) {
         final LocalCallingIdentity token = clearLocalCallingIdentity();
-        final String fileName = extractDisplayName(path);
+        final String fileName = extractFileName(path);
 
         final DatabaseHelper helper;
         try {
@@ -2877,11 +2878,17 @@
             }
         }
 
+        String ext = getFileExtensionFromCursor(c, columnNames);
+        ext = ext == null ? "" : "." + ext;
+        final String displayName = redactedUriId + ext;
+        final String data = getPathForRedactedUriId(displayName);
+
+
         updateRow(columnNames, MediaColumns._ID, row, redactedUriId);
-        updateRow(columnNames, MediaColumns.DISPLAY_NAME, row, redactedUriId);
+        updateRow(columnNames, MediaColumns.DISPLAY_NAME, row, displayName);
         updateRow(columnNames, MediaColumns.RELATIVE_PATH, row, REDACTED_URI_DIR);
         updateRow(columnNames, MediaColumns.BUCKET_DISPLAY_NAME, row, REDACTED_URI_DIR);
-        updateRow(columnNames, MediaColumns.DATA, row, getPathForRedactedUriId(redactedUriId));
+        updateRow(columnNames, MediaColumns.DATA, row, data);
         updateRow(columnNames, MediaColumns.DOCUMENT_ID, row, null);
         updateRow(columnNames, MediaColumns.INSTANCE_ID, row, null);
         updateRow(columnNames, MediaColumns.BUCKET_ID, row, null);
@@ -2889,9 +2896,21 @@
         return redactedUriCursor;
     }
 
-    static private String getPathForRedactedUriId(String redactedUriId) {
+    @Nullable
+    private static String getFileExtensionFromCursor(@NonNull Cursor c,
+            @NonNull HashSet<String> columnNames) {
+        if (columnNames.contains(MediaColumns.DATA)) {
+            return extractFileExtension(c.getString(c.getColumnIndex(MediaColumns.DATA)));
+        }
+        if (columnNames.contains(MediaColumns.DISPLAY_NAME)) {
+            return extractFileExtension(c.getString(c.getColumnIndex(MediaColumns.DISPLAY_NAME)));
+        }
+        return null;
+    }
+
+    static private String getPathForRedactedUriId(@NonNull String displayName) {
         return getStorageRootPathForUid(Binder.getCallingUid()) + "/" + REDACTED_URI_DIR + "/"
-                + redactedUriId;
+                + displayName;
     }
 
     static private String getStorageRootPathForUid(int uid) {
@@ -8067,7 +8086,7 @@
                             mediaCapabilitiesUid, new long[0]);
                 }
 
-                redactedUriId = extractDisplayName(path);
+                redactedUriId = extractFileName(path);
 
                 // If path is redacted Uris' path, ioPath must be the real path, ioPath must
                 // haven been updated to the real path during onFileLookupForFuse.
diff --git a/tests/src/com/android/providers/media/MediaProviderTest.java b/tests/src/com/android/providers/media/MediaProviderTest.java
index ef2c44b..e18fc4e 100644
--- a/tests/src/com/android/providers/media/MediaProviderTest.java
+++ b/tests/src/com/android/providers/media/MediaProviderTest.java
@@ -1435,4 +1435,41 @@
             }
         }
     }
+
+    @Test
+    public void testRedactionForFileExtension() throws Exception {
+        testRedactionForFileExtension(R.raw.test_audio, ".mp3");
+        testRedactionForFileExtension(R.raw.test_video_xmp, ".mp4");
+        testRedactionForFileExtension(R.raw.lg_g4_iso_800_jpg, ".jpg");
+    }
+
+    private void testRedactionForFileExtension(int resId, String extension) throws Exception {
+        final File dir = Environment
+                .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
+        final File file = new File(dir, "test" + System.nanoTime() + extension);
+
+        stage(resId, file);
+
+        final List<Uri> uris = new ArrayList<>();
+        uris.add(MediaStore.scanFile(sIsolatedResolver, file));
+
+
+        try (ContentProviderClient cpc = sIsolatedResolver
+                .acquireContentProviderClient(MediaStore.AUTHORITY)) {
+            final MediaProvider mp = (MediaProvider) cpc.getLocalContentProvider();
+
+            final String[] projection = new String[]{MediaColumns.DISPLAY_NAME, MediaColumns.DATA};
+            for (Uri uri : mp.getRedactedUri(uris)) {
+                try (Cursor c = sIsolatedResolver.query(uri, projection, null, null)) {
+                    assertNotNull(c);
+                    assertEquals(1, c.getCount());
+                    assertTrue(c.moveToFirst());
+                    assertTrue(c.getString(0).endsWith(extension));
+                    assertTrue(c.getString(1).endsWith(extension));
+                }
+            }
+        } finally {
+            file.delete();
+        }
+    }
 }