diff options
| author | 2018-12-11 21:13:25 +0000 | |
|---|---|---|
| committer | 2018-12-11 21:13:25 +0000 | |
| commit | f9eeca1364822ff8ba5e1ec0d738f0c2c7843a15 (patch) | |
| tree | e9166e3256274316ad42b2a831b05f508dc6862b | |
| parent | 5e34c414cff56359e54ebb8848ef4654b3e90f8f (diff) | |
| parent | b95bd4429c87ba7d79a06b61ccfb783153a6b10d (diff) | |
Merge "Surface tree statistics through metadata."
| -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 ed9ac402847a..b8a37d492303 100644 --- a/api/current.txt +++ b/api/current.txt @@ -37454,6 +37454,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 { |