summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/provider/DocumentsContract.java22
-rw-r--r--core/java/com/android/internal/content/FileSystemProvider.java54
3 files changed, 71 insertions, 7 deletions
diff --git a/api/current.txt b/api/current.txt
index 33ae6433bd05..a34ccccd07cd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37448,6 +37448,8 @@ package android.provider {
field public static final java.lang.String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION";
field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT";
field public static final java.lang.String METADATA_EXIF = "android:documentExif";
+ field public static final java.lang.String METADATA_TREE_COUNT = "android:metadataTreeCount";
+ field public static final java.lang.String METADATA_TREE_SIZE = "android:metadataTreeSize";
field public static final java.lang.String METADATA_TYPES = "android:documentMetadataTypes";
field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
field public static final java.lang.String QUERY_ARG_DISPLAY_NAME = "android:query-arg-display-name";
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index ff772287de25..d9c16a700cb9 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -244,18 +244,34 @@ public final class DocumentsContract {
* Get string array identifies the type or types of metadata returned
* using DocumentsContract#getDocumentMetadata.
*
- * @see #getDocumentMetadata(ContentResolver, Uri)
+ * @see #getDocumentMetadata(ContentInterface, Uri)
*/
public static final String METADATA_TYPES = "android:documentMetadataTypes";
/**
* Get Exif information using DocumentsContract#getDocumentMetadata.
*
- * @see #getDocumentMetadata(ContentResolver, Uri)
+ * @see #getDocumentMetadata(ContentInterface, Uri)
*/
public static final String METADATA_EXIF = "android:documentExif";
/**
+ * Get total count of all documents currently stored under the given
+ * directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
+ *
+ * @see #getDocumentMetadata(ContentInterface, Uri)
+ */
+ public static final String METADATA_TREE_COUNT = "android:metadataTreeCount";
+
+ /**
+ * Get total size of all documents currently stored under the given
+ * directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
+ *
+ * @see #getDocumentMetadata(ContentInterface, Uri)
+ */
+ public static final String METADATA_TREE_SIZE = "android:metadataTreeSize";
+
+ /**
* Constants related to a document, including {@link Cursor} column names
* and flags.
* <p>
@@ -519,7 +535,7 @@ public final class DocumentsContract {
* using DocumentsContract#getDocumentMetadata
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
+ * @see DocumentsContract#getDocumentMetadata(ContentInterface, Uri)
*/
public static final int FLAG_SUPPORTS_METADATA = 1 << 14;
}
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 8bc90a891352..a27dbeae2f3a 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -39,6 +39,7 @@ import android.provider.DocumentsContract.Document;
import android.provider.DocumentsProvider;
import android.provider.MediaStore;
import android.provider.MetadataReader;
+import android.system.Int64Ref;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -53,6 +54,12 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -122,18 +129,56 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new FileNotFoundException("Can't find the file for documentId: " + documentId);
}
+ final String mimeType = getDocumentType(documentId);
+ if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+ final Int64Ref treeCount = new Int64Ref(0);
+ final Int64Ref treeSize = new Int64Ref(0);
+ try {
+ final Path path = FileSystems.getDefault().getPath(file.getAbsolutePath());
+ Files.walkFileTree(path, new FileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ treeCount.value += 1;
+ treeSize.value += attrs.size();
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path file, IOException exc) {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException e) {
+ Log.e(TAG, "An error occurred retrieving the metadata", e);
+ return null;
+ }
+
+ final Bundle res = new Bundle();
+ res.putLong(DocumentsContract.METADATA_TREE_COUNT, treeCount.value);
+ res.putLong(DocumentsContract.METADATA_TREE_SIZE, treeSize.value);
+ return res;
+ }
+
if (!file.isFile()) {
Log.w(TAG, "Can't stream non-regular file. Returning empty metadata.");
return null;
}
-
if (!file.canRead()) {
Log.w(TAG, "Can't stream non-readable file. Returning empty metadata.");
return null;
}
-
- String mimeType = getDocumentType(documentId);
if (!MetadataReader.isSupportedMimeType(mimeType)) {
+ Log.w(TAG, "Unsupported type " + mimeType + ". Returning empty metadata.");
return null;
}
@@ -562,7 +607,8 @@ public abstract class FileSystemProvider extends DocumentsProvider {
}
protected boolean typeSupportsMetadata(String mimeType) {
- return MetadataReader.isSupportedMimeType(mimeType);
+ return MetadataReader.isSupportedMimeType(mimeType)
+ || Document.MIME_TYPE_DIR.equals(mimeType);
}
protected final File getFileForDocId(String docId) throws FileNotFoundException {