diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-08-11 21:09:55 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-08-11 21:09:55 +0000 |
commit | a4979cde29a16b6e513f1838320f47a40851a524 (patch) | |
tree | cf42355f715644f517a5c829f710a879ef0d1078 | |
parent | 2ba7ca9cc7f6c3256d6068592145b44f109ec95f (diff) | |
parent | 2ddae5b1a1167f44e9bc98b5a12f466c8119cf02 (diff) | |
download | MediaProvider-android12-platform-release.tar.gz |
Merge cherrypicks of ['googleplex-android-review.googlesource.com/23029977'] into sc-platform-release.android-platform-12.0.0_r31android-platform-12.0.0_r30android-platform-12.0.0_r29android-platform-12.0.0_r28android-platform-12.0.0_r27android-platform-12.0.0_r26android-platform-12.0.0_r25android-platform-12.0.0_r24android12-platform-release
Change-Id: I1f57582bae4625e54d7061d7653a2abba91ebe45
-rw-r--r-- | src/com/android/providers/media/MediaProvider.java | 54 | ||||
-rw-r--r-- | src/com/android/providers/media/scan/ModernMediaScanner.java | 33 | ||||
-rw-r--r-- | src/com/android/providers/media/util/FileUtils.java | 47 |
3 files changed, 96 insertions, 38 deletions
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java index 705d7ecc1..31bdf893f 100644 --- a/src/com/android/providers/media/MediaProvider.java +++ b/src/com/android/providers/media/MediaProvider.java @@ -5549,38 +5549,48 @@ public class MediaProvider extends ContentProvider { BackgroundThread.waitForIdle(); return null; } - case MediaStore.SCAN_FILE_CALL: - case MediaStore.SCAN_VOLUME_CALL: { - final int userId = Binder.getCallingUid() / PER_USER_RANGE; + case MediaStore.SCAN_FILE_CALL: { final LocalCallingIdentity token = clearLocalCallingIdentity(); final CallingIdentity providerToken = clearCallingIdentity(); + + final String filePath = arg; + final Uri uri; try { - final Bundle res = new Bundle(); - switch (method) { - case MediaStore.SCAN_FILE_CALL: { - final File file = new File(arg); - res.putParcelable(Intent.EXTRA_STREAM, scanFile(file, REASON_DEMAND)); - break; - } - case MediaStore.SCAN_VOLUME_CALL: { - final String volumeName = arg; - try { - MediaVolume volume = mVolumeCache.findVolume(volumeName, - UserHandle.of(userId)); - MediaService.onScanVolume(getContext(), volume, REASON_DEMAND); - } catch (FileNotFoundException e) { - Log.w(TAG, "Failed to find volume " + volumeName, e); - } - break; - } + File file; + try { + file = FileUtils.getCanonicalFile(filePath); + } catch (IOException e) { + file = null; } - return res; + + uri = file != null ? scanFile(file, REASON_DEMAND) : null; + } finally { + restoreCallingIdentity(providerToken); + restoreLocalCallingIdentity(token); + } + + final Bundle res = new Bundle(); + res.putParcelable(Intent.EXTRA_STREAM, uri); + return res; + } + case MediaStore.SCAN_VOLUME_CALL: { + final UserHandle user = UserHandle.of(Binder.getCallingUid() / PER_USER_RANGE); + final LocalCallingIdentity token = clearLocalCallingIdentity(); + final CallingIdentity providerToken = clearCallingIdentity(); + + final String volumeName = arg; + try { + final MediaVolume volume = mVolumeCache.findVolume(volumeName, user); + MediaService.onScanVolume(getContext(), volume, REASON_DEMAND); + } catch (FileNotFoundException e) { + Log.w(TAG, "Failed to find volume " + volumeName, e); } catch (IOException e) { throw new RuntimeException(e); } finally { restoreCallingIdentity(providerToken); restoreLocalCallingIdentity(token); } + return Bundle.EMPTY; } case MediaStore.GET_VERSION_CALL: { final String volumeName = extras.getString(Intent.EXTRA_TEXT); diff --git a/src/com/android/providers/media/scan/ModernMediaScanner.java b/src/com/android/providers/media/scan/ModernMediaScanner.java index 8927bfa56..5087c19ad 100644 --- a/src/com/android/providers/media/scan/ModernMediaScanner.java +++ b/src/com/android/providers/media/scan/ModernMediaScanner.java @@ -50,6 +50,8 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static com.android.providers.media.util.Metrics.translateReason; +import static java.util.Objects.requireNonNull; + import android.content.ContentProviderClient; import android.content.ContentProviderOperation; import android.content.ContentProviderResult; @@ -243,7 +245,15 @@ public class ModernMediaScanner implements MediaScanner { } @Override - public void scanDirectory(File file, int reason) { + public void scanDirectory(@NonNull File file, int reason) { + requireNonNull(file); + try { + file = file.getCanonicalFile(); + } catch (IOException e) { + Log.e(TAG, "Couldn't canonicalize directory to scan" + file, e); + return; + } + try (Scan scan = new Scan(file, reason, /*ownerPackage*/ null)) { scan.run(); } catch (OperationCanceledException ignored) { @@ -253,12 +263,21 @@ public class ModernMediaScanner implements MediaScanner { } @Override - public Uri scanFile(File file, int reason) { + @Nullable + public Uri scanFile(@NonNull File file, int reason) { return scanFile(file, reason, /*ownerPackage*/ null); } @Override public Uri scanFile(File file, int reason, @Nullable String ownerPackage) { + requireNonNull(file); + try { + file = file.getCanonicalFile(); + } catch (IOException e) { + Log.e(TAG, "Couldn't canonicalize file to scan" + file, e); + return null; + } + try (Scan scan = new Scan(file, reason, ownerPackage)) { scan.run(); return scan.getFirstResult(); @@ -294,9 +313,17 @@ public class ModernMediaScanner implements MediaScanner { @Override public void onDirectoryDirty(File dir) { + requireNonNull(dir); + try { + dir = dir.getCanonicalFile(); + } catch (IOException e) { + Log.e(TAG, "Couldn't canonicalize directory" + dir, e); + return; + } + synchronized (mPendingCleanDirectories) { mPendingCleanDirectories.remove(dir.getPath()); - FileUtils.setDirectoryDirty(dir, /*isDirty*/ true); + FileUtils.setDirectoryDirty(dir, /* isDirty */ true); } } diff --git a/src/com/android/providers/media/util/FileUtils.java b/src/com/android/providers/media/util/FileUtils.java index a0f666fbd..e5c62d160 100644 --- a/src/com/android/providers/media/util/FileUtils.java +++ b/src/com/android/providers/media/util/FileUtils.java @@ -1101,18 +1101,25 @@ public class FileUtils { } public static @Nullable String extractRelativePath(@Nullable String data) { - data = getCanonicalPath(data); if (data == null) return null; - final Matcher matcher = PATTERN_RELATIVE_PATH.matcher(data); + final String path; + try { + path = getCanonicalPath(data); + } catch (IOException e) { + Log.d(TAG, "Unable to get canonical path from invalid data path: " + data, e); + return null; + } + + final Matcher matcher = PATTERN_RELATIVE_PATH.matcher(path); if (matcher.find()) { - final int lastSlash = data.lastIndexOf('/'); + final int lastSlash = path.lastIndexOf('/'); if (lastSlash == -1 || lastSlash < matcher.end()) { // This is a file in the top-level directory, so relative path is "/" // which is different than null, which means unknown path return "/"; } else { - return data.substring(matcher.end(), lastSlash + 1); + return path.substring(matcher.end(), lastSlash + 1); } } else { return null; @@ -1667,15 +1674,29 @@ public class FileUtils { return null; } - @Nullable - private static String getCanonicalPath(@Nullable String path) { - if (path == null) return null; + /** + * Returns the canonical {@link File} for the provided abstract pathname. + * + * @return The canonical pathname string denoting the same file or directory as this abstract + * pathname + * @see File#getCanonicalFile() + */ + @NonNull + public static File getCanonicalFile(@NonNull String path) throws IOException { + Objects.requireNonNull(path); + return new File(path).getCanonicalFile(); + } - try { - return new File(path).getCanonicalPath(); - } catch (IOException e) { - Log.d(TAG, "Unable to get canonical path from invalid data path: " + path, e); - return null; - } + /** + * Returns the canonical pathname string of the provided abstract pathname. + * + * @return The canonical pathname string denoting the same file or directory as this abstract + * pathname. + * @see File#getCanonicalPath() + */ + @NonNull + public static String getCanonicalPath(@NonNull String path) throws IOException { + Objects.requireNonNull(path); + return new File(path).getCanonicalPath(); } } |