From 94a7b819fe7ee1dc8637dc93b79729479cf1db65 Mon Sep 17 00:00:00 2001 From: Zim Date: Tue, 19 Jan 2021 02:11:02 +0000 Subject: [PATCH] Fix convertToModernFd to support /mnt/user paths Since I72f39d3e35b975f0a386c055cbb10b4d21c21c86, the MediaProvider now always opens FUSE paths when transcoding is required. Those paths start with /mnt/user/ but apps can't access those paths directly so we make the following changes: 1. Call readlink(2) directly (without stat as ParcelFileDescriptor#getFile currently does). 2. Replace /mnt/user/ with /storage paths and use the new /storage path for scanning This also fixes some failing CTS Test: Apps don't ANR when calling MediaMetadataRetriever#setDataSource Test: atest android.appsecurity.cts.ExternalStorageHostTest#testMediaNone29 Bug: 174655855 Fixes: 177860000 Change-Id: Iec48dcb714a47b147e16eae39df783de748960f4 --- core/java/android/os/FileUtils.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 0326b72ece7ca..a46af9754f328 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -1442,11 +1442,13 @@ public final class FileUtils { public static FileDescriptor convertToModernFd(FileDescriptor fd) { try { Context context = AppGlobals.getInitialApplication(); - File realFile = ParcelFileDescriptor.getFile(fd); + // /mnt/user paths are not accessible directly so convert to a /storage path + String filePath = Os.readlink("/proc/self/fd/" + fd.getInt$()).replace( + "/mnt/user/" + UserHandle.myUserId(), "/storage"); + File realFile = new File(filePath); String fileName = realFile.getName(); boolean isCameraVideo = !fileName.startsWith(".") && fileName.endsWith(".mp4") - && contains(CAMERA_DIR_LOWER_CASE, realFile.getAbsolutePath().toLowerCase( - Locale.ROOT)); + && contains(CAMERA_DIR_LOWER_CASE, filePath.toLowerCase(Locale.ROOT)); if (!SystemProperties.getBoolean("sys.fuse.transcode_enabled", false) || UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context) @@ -1471,7 +1473,7 @@ public final class FileUtils { Log.i(TAG, "Failed to change to modern format dataSource for: " + realFile); } } catch (Exception e) { - Log.w(TAG, "Failed to change to modern format dataSource"); + Log.w(TAG, "Failed to change to modern format dataSource", e); } return null; }