diff options
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | core/java/android/provider/DocumentsContract.java | 22 | ||||
-rw-r--r-- | core/java/com/android/internal/content/FileSystemProvider.java | 54 |
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 { |