summaryrefslogtreecommitdiffstats
path: root/packages/ExternalStorageProvider
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2014-04-05 19:05:24 -0700
committerJeff Sharkey <jsharkey@android.com>2014-04-22 22:18:21 -0700
commit21de56a94668e0fda1b8bb4ee4f99a09b40d28fd (patch)
tree3cadec8c73dd2ea2ed4cbe5744a52128e5d24a8a /packages/ExternalStorageProvider
parent846318a3250fa95f47a9decfbffb05a31dbd0006 (diff)
downloadframeworks_base-21de56a94668e0fda1b8bb4ee4f99a09b40d28fd.zip
frameworks_base-21de56a94668e0fda1b8bb4ee4f99a09b40d28fd.tar.gz
frameworks_base-21de56a94668e0fda1b8bb4ee4f99a09b40d28fd.tar.bz2
Add directory selection to DocumentsProvider.
Introduce new ACTION_PICK_DIRECTORY that allows users to grant access to an entire document subtree. Instead of requiring grants for each individual document, this leverages new prefix URI permission grants by defining new "via"-style URIs: content://com.example/via/12/document/24/ This references document 24 by using a prefix grant given for document 12. Internally, we use isChildDocument() to enforce that 24 is actually a descendant (child, grandchild, etc) of 12. Since this is an optional API, providers indicate support with Root.FLAG_SUPPORTS_DIR_SELECTION. Extend DocumentsUI to support picking directories. Expose createDocument() API to work with returned directories. Offer to canonicalize via-style URIs into direct URIs, generating exact permission grants along the way. Override openAssetFile() to pass through CancellationSignal. Move testing code into ApiDemos. Bug: 10607375 Change-Id: Ifffc1cff878870f8152eb6ca0199c5d014b9cb07
Diffstat (limited to 'packages/ExternalStorageProvider')
-rw-r--r--packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java23
1 files changed, 20 insertions, 3 deletions
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 559e052..16fc3e5 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -27,6 +27,7 @@ import android.net.Uri;
import android.os.CancellationSignal;
import android.os.Environment;
import android.os.FileObserver;
+import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
@@ -143,7 +144,7 @@ public class ExternalStorageProvider extends DocumentsProvider {
final RootInfo root = new RootInfo();
root.rootId = rootId;
root.flags = Root.FLAG_SUPPORTS_CREATE | Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED
- | Root.FLAG_SUPPORTS_SEARCH;
+ | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_DIR_SELECTION;
if (ROOT_ID_PRIMARY_EMULATED.equals(rootId)) {
root.title = getContext().getString(R.string.root_internal_storage);
} else {
@@ -240,8 +241,8 @@ public class ExternalStorageProvider extends DocumentsProvider {
flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
} else {
flags |= Document.FLAG_SUPPORTS_WRITE;
+ flags |= Document.FLAG_SUPPORTS_DELETE;
}
- flags |= Document.FLAG_SUPPORTS_DELETE;
}
final String displayName = file.getName();
@@ -284,11 +285,26 @@ public class ExternalStorageProvider extends DocumentsProvider {
}
@Override
+ public boolean isChildDocument(String parentDocId, String docId) {
+ try {
+ final File parent = getFileForDocId(parentDocId).getCanonicalFile();
+ final File doc = getFileForDocId(docId).getCanonicalFile();
+ return FileUtils.contains(parent, doc);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(
+ "Failed to determine if " + docId + " is child of " + parentDocId + ": " + e);
+ }
+ }
+
+ @Override
public String createDocument(String docId, String mimeType, String displayName)
throws FileNotFoundException {
final File parent = getFileForDocId(docId);
- File file;
+ if (!parent.isDirectory()) {
+ throw new IllegalArgumentException("Parent document isn't a directory");
+ }
+ File file;
if (Document.MIME_TYPE_DIR.equals(mimeType)) {
file = new File(parent, displayName);
if (!file.mkdir()) {
@@ -317,6 +333,7 @@ public class ExternalStorageProvider extends DocumentsProvider {
@Override
public void deleteDocument(String docId) throws FileNotFoundException {
+ // TODO: extend to delete directories
final File file = getFileForDocId(docId);
if (!file.delete()) {
throw new IllegalStateException("Failed to delete " + file);