Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 176b8d09 authored by Ivan Chiang's avatar Ivan Chiang Committed by Android (Google) Code Review
Browse files

Merge "Allow providers block folders in ACTION_OPEN_DOCUMENT_TREE"

parents 14b110db 730b3a3a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -38280,6 +38280,7 @@ package android.provider {
    field public static final String COLUMN_MIME_TYPE = "mime_type";
    field public static final String COLUMN_SIZE = "_size";
    field public static final String COLUMN_SUMMARY = "summary";
    field public static final int FLAG_DIR_BLOCKS_TREE = 32768; // 0x8000
    field public static final int FLAG_DIR_PREFERS_GRID = 16; // 0x10
    field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 32; // 0x20
    field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8
+28 −4
Original line number Diff line number Diff line
@@ -363,15 +363,22 @@ public final class DocumentsContract {
         * <p>
         * Type: INTEGER (int)
         *
         * @see #FLAG_SUPPORTS_WRITE
         * @see #FLAG_SUPPORTS_DELETE
         * @see #FLAG_SUPPORTS_THUMBNAIL
         * @see #FLAG_DIR_BLOCKS_TREE
         * @see #FLAG_DIR_PREFERS_GRID
         * @see #FLAG_DIR_PREFERS_LAST_MODIFIED
         * @see #FLAG_VIRTUAL_DOCUMENT
         * @see #FLAG_DIR_SUPPORTS_CREATE
         * @see #FLAG_PARTIAL
         * @see #FLAG_SUPPORTS_COPY
         * @see #FLAG_SUPPORTS_DELETE
         * @see #FLAG_SUPPORTS_METADATA
         * @see #FLAG_SUPPORTS_MOVE
         * @see #FLAG_SUPPORTS_REMOVE
         * @see #FLAG_SUPPORTS_RENAME
         * @see #FLAG_SUPPORTS_SETTINGS
         * @see #FLAG_SUPPORTS_THUMBNAIL
         * @see #FLAG_SUPPORTS_WRITE
         * @see #FLAG_VIRTUAL_DOCUMENT
         * @see #FLAG_WEB_LINKABLE
         */
        public static final String COLUMN_FLAGS = "flags";

@@ -542,6 +549,23 @@ public final class DocumentsContract {
         * @see DocumentsContract#getDocumentMetadata(ContentInterface, Uri)
         */
        public static final int FLAG_SUPPORTS_METADATA = 1 << 14;

        /**
         * Flag indicating that a document is a directory that wants to block itself
         * from being selected when the user launches an {@link Intent#ACTION_OPEN_DOCUMENT_TREE}
         * intent. Only valid when {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}.
         * <p>
         * Note that this flag <em>only</em> applies to the single directory to which it is
         * applied. It does <em>not</em> block the user from selecting either a parent or
         * child directory during an {@link Intent#ACTION_OPEN_DOCUMENT_TREE} request.
         * In particular, the only way to guarantee that a specific directory can never
         * be granted via an {@link Intent#ACTION_OPEN_DOCUMENT_TREE} request is to ensure
         * that both it and <em>all of its parent directories</em> have set this flag.
         *
         * @see Intent#ACTION_OPEN_DOCUMENT_TREE
         * @see #COLUMN_FLAGS
         */
        public static final int FLAG_DIR_BLOCKS_TREE = 1 << 15;
    }

    /**
+10 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.content;

import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Intent;
@@ -552,6 +553,11 @@ public abstract class FileSystemProvider extends DocumentsProvider {
                    flags |= Document.FLAG_SUPPORTS_DELETE;
                    flags |= Document.FLAG_SUPPORTS_RENAME;
                    flags |= Document.FLAG_SUPPORTS_MOVE;

                    if (shouldBlockFromTree(docId)) {
                        flags |= Document.FLAG_DIR_BLOCKS_TREE;
                    }

                } else {
                    flags |= Document.FLAG_SUPPORTS_WRITE;
                    flags |= Document.FLAG_SUPPORTS_DELETE;
@@ -592,6 +598,10 @@ public abstract class FileSystemProvider extends DocumentsProvider {
        return row;
    }

    protected boolean shouldBlockFromTree(@NonNull String docId) {
        return false;
    }

    protected boolean typeSupportsMetadata(String mimeType) {
        return MetadataReader.isSupportedMimeType(mimeType)
                || Document.MIME_TYPE_DIR.equals(mimeType);
+48 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.externalstorage;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.usage.StorageStatsManager;
import android.content.ContentResolver;
@@ -298,6 +299,53 @@ public class ExternalStorageProvider extends FileSystemProvider {
        return projection != null ? projection : DEFAULT_ROOT_PROJECTION;
    }

    /**
     * Check that the directory is the root of storage or blocked file from tree.
     *
     * @param docId the docId of the directory to be checked
     * @return true, should be blocked from tree. Otherwise, false.
     */
    @Override
    protected boolean shouldBlockFromTree(@NonNull String docId) {
        try {
            final File dir = getFileForDocId(docId, true /* visible */).getCanonicalFile();
            if (!dir.isDirectory()) {
                return false;
            }

            final String path = dir.getAbsolutePath();

            // Block Download folder from tree
            if (MediaStore.Downloads.isDownloadDir(path)) {
                return true;
            }

            final ArrayMap<String, RootInfo> roots = new ArrayMap<>();

            synchronized (mRootsLock) {
                roots.putAll(mRoots);
            }

            // block root of storage
            for (int i = 0; i < roots.size(); i++) {
                RootInfo rootInfo = roots.valueAt(i);
                // skip home root
                if (TextUtils.equals(rootInfo.rootId, ROOT_ID_HOME)) {
                    continue;
                }

                // block the root of storage
                if (TextUtils.equals(path, rootInfo.visiblePath.getAbsolutePath())) {
                    return true;
                }
            }
            return false;
        } catch (IOException e) {
            throw new IllegalArgumentException(
                    "Failed to determine if " + docId + " should block from tree " + ": " + e);
        }
    }

    @Override
    protected String getDocIdForFile(File file) throws FileNotFoundException {
        return getDocIdForFileMaybeCreate(file, false);