diff options
author | Abhijeet Kaur <abkaur@google.com> | 2020-05-07 13:11:55 +0100 |
---|---|---|
committer | Abhijeet Kaur <abkaur@google.com> | 2020-05-11 11:39:40 +0100 |
commit | 553625de0ac7c78ec5353675e94f98dbe9a6ae4d (patch) | |
tree | cc5176cce8d612f6aa37bb2bf47657784706a7b7 | |
parent | c07cd07a4a210914831c5abb044a1979e0067d3f (diff) |
Add manage mode workflow for ExternalStorageProvider
In Scoped Storage world, access to "Android/data" style directories are
hidden for privacy reasons. Allow ExternalStorageProvider to show these
hidden files when in manage mode.
Bug: 150366834
Test: Android/data and Android/obb is visible from Files App, but are
hidden in Picker view from StorageTestApp and Gmail (GMAIL > Compose >
Attach > Go to Pixel > Android)
Change-Id: I58b4fc23d9b479df4fc0480ae55f1f2070d0cb7c
-rw-r--r-- | core/java/com/android/internal/content/FileSystemProvider.java | 41 | ||||
-rw-r--r-- | packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java | 7 |
2 files changed, 47 insertions, 1 deletions
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java index 2f048c95ae4e..a50a52219c74 100644 --- a/core/java/com/android/internal/content/FileSystemProvider.java +++ b/core/java/com/android/internal/content/FileSystemProvider.java @@ -68,6 +68,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Predicate; import java.util.regex.Pattern; /** @@ -381,17 +382,51 @@ public abstract class FileSystemProvider extends DocumentsProvider { return result; } + /** + * This method is similar to + * {@link DocumentsProvider#queryChildDocuments(String, String[], String)}. This method returns + * all children documents including hidden directories/files. + * + * <p> + * In a scoped storage world, access to "Android/data" style directories are hidden for privacy + * reasons. This method may show privacy sensitive data, so its usage should only be in + * restricted modes. + * + * @param parentDocumentId the directory to return children for. + * @param projection list of {@link Document} columns to put into the + * cursor. If {@code null} all supported columns should be + * included. + * @param sortOrder how to order the rows, formatted as an SQL + * {@code ORDER BY} clause (excluding the ORDER BY itself). + * Passing {@code null} will use the default sort order, which + * may be unordered. This ordering is a hint that can be used to + * prioritize how data is fetched from the network, but UI may + * always enforce a specific ordering + * @throws FileNotFoundException when parent document doesn't exist or query fails + */ + protected Cursor queryChildDocumentsShowAll( + String parentDocumentId, String[] projection, String sortOrder) + throws FileNotFoundException { + return queryChildDocuments(parentDocumentId, projection, sortOrder, File -> true); + } + @Override public Cursor queryChildDocuments( String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException { + // Access to some directories is hidden for privacy reasons. + return queryChildDocuments(parentDocumentId, projection, sortOrder, this::shouldShow); + } + private Cursor queryChildDocuments( + String parentDocumentId, String[] projection, String sortOrder, + @NonNull Predicate<File> filter) throws FileNotFoundException { final File parent = getFileForDocId(parentDocumentId); final MatrixCursor result = new DirectoryCursor( resolveProjection(projection), parentDocumentId, parent); if (parent.isDirectory()) { for (File file : FileUtils.listFilesOrEmpty(parent)) { - if (!shouldHide(file)) { + if (filter.test(file)) { includeFile(result, null, file); } } @@ -617,6 +652,10 @@ public abstract class FileSystemProvider extends DocumentsProvider { return (PATTERN_HIDDEN_PATH.matcher(file.getAbsolutePath()).matches()); } + private boolean shouldShow(@NonNull File file) { + return !shouldHide(file); + } + protected boolean shouldBlockFromTree(@NonNull String docId) { return false; } diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 0c70e104f9a6..8f919c3d86ca 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -275,6 +275,13 @@ public class ExternalStorageProvider extends FileSystemProvider { return projection != null ? projection : DEFAULT_ROOT_PROJECTION; } + @Override + public Cursor queryChildDocumentsForManage( + String parentDocId, String[] projection, String sortOrder) + throws FileNotFoundException { + return queryChildDocumentsShowAll(parentDocId, projection, sortOrder); + } + /** * Check that the directory is the root of storage or blocked file from tree. * |