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

Commit 5d7acbd8 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Filter roots based on supported MIME types." into klp-dev

parents e0e4197c 923396b7
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -20786,17 +20786,15 @@ package android.provider {
    field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id";
    field public static final java.lang.String COLUMN_FLAGS = "flags";
    field public static final java.lang.String COLUMN_ICON = "icon";
    field public static final java.lang.String COLUMN_MIME_TYPES = "mime_types";
    field public static final java.lang.String COLUMN_ROOT_ID = "root_id";
    field public static final java.lang.String COLUMN_ROOT_TYPE = "root_type";
    field public static final java.lang.String COLUMN_SUMMARY = "summary";
    field public static final java.lang.String COLUMN_TITLE = "title";
    field public static final int FLAG_ADVANCED = 4; // 0x4
    field public static final int FLAG_LOCAL_ONLY = 2; // 0x2
    field public static final int FLAG_PROVIDES_AUDIO = 8; // 0x8
    field public static final int FLAG_PROVIDES_IMAGES = 32; // 0x20
    field public static final int FLAG_PROVIDES_VIDEO = 16; // 0x10
    field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
    field public static final int FLAG_SUPPORTS_RECENTS = 64; // 0x40
    field public static final int FLAG_SUPPORTS_RECENTS = 8; // 0x8
    field public static final int ROOT_TYPE_DEVICE = 3; // 0x3
    field public static final int ROOT_TYPE_SERVICE = 1; // 0x1
    field public static final int ROOT_TYPE_SHORTCUT = 2; // 0x2
+11 −28
Original line number Diff line number Diff line
@@ -336,6 +336,16 @@ public final class DocumentsContract {
         */
        public static final String COLUMN_AVAILABLE_BYTES = "available_bytes";

        /**
         * MIME types supported by this root, or {@code null} if the root
         * supports all MIME types. Multiple MIME types can be separated by a
         * newline. For example, a root supporting audio might use
         * "audio/*\napplication/x-flac".
         * <p>
         * Type: String
         */
        public static final String COLUMN_MIME_TYPES = "mime_types";

        /**
         * Type of root that represents a storage service, such as a cloud-based
         * service.
@@ -385,33 +395,6 @@ public final class DocumentsContract {
         */
        public static final int FLAG_ADVANCED = 1 << 2;

        /**
         * Flag indicating that a root offers audio documents. When a user is
         * selecting audio, roots not providing audio may be excluded.
         *
         * @see #COLUMN_FLAGS
         * @see Intent#EXTRA_MIME_TYPES
         */
        public static final int FLAG_PROVIDES_AUDIO = 1 << 3;

        /**
         * Flag indicating that a root offers video documents. When a user is
         * selecting video, roots not providing video may be excluded.
         *
         * @see #COLUMN_FLAGS
         * @see Intent#EXTRA_MIME_TYPES
         */
        public static final int FLAG_PROVIDES_VIDEO = 1 << 4;

        /**
         * Flag indicating that a root offers image documents. When a user is
         * selecting images, roots not providing images may be excluded.
         *
         * @see #COLUMN_FLAGS
         * @see Intent#EXTRA_MIME_TYPES
         */
        public static final int FLAG_PROVIDES_IMAGES = 1 << 5;

        /**
         * Flag indicating that this root can report recently modified
         * documents.
@@ -419,7 +402,7 @@ public final class DocumentsContract {
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#buildRecentDocumentsUri(String, String)
         */
        public static final int FLAG_SUPPORTS_RECENTS = 1 << 6;
        public static final int FLAG_SUPPORTS_RECENTS = 1 << 3;
    }

    /**
+24 −7
Original line number Diff line number Diff line
@@ -16,9 +16,13 @@

package com.android.documentsui;

import android.util.Log;

import com.android.documentsui.model.DocumentInfo;
import com.android.internal.util.Predicate;

import java.util.Arrays;

public class MimePredicate implements Predicate<DocumentInfo> {
    private final String[] mFilters;

@@ -31,16 +35,29 @@ public class MimePredicate implements Predicate<DocumentInfo> {
        if (doc.isDirectory()) {
            return true;
        }
        for (String filter : mFilters) {
            if (mimeMatches(filter, doc.mimeType)) {
        if (mimeMatches(mFilters, doc.mimeType)) {
            return true;
        }
        }
        return false;
    }

    public static boolean mimeMatches(String filter, String[] tests) {
    public static boolean mimeMatches(String[] filters, String[] tests) {
        if (tests == null) {
            return false;
        }
        for (String test : tests) {
            if (mimeMatches(filters, test)) {
                return true;
            }
        }
        return false;
    }

    public static boolean mimeMatches(String[] filters, String test) {
        if (filters == null) {
            return true;
        }
        for (String filter : filters) {
            if (mimeMatches(filter, test)) {
                return true;
            }
@@ -49,12 +66,12 @@ public class MimePredicate implements Predicate<DocumentInfo> {
    }

    public static boolean mimeMatches(String filter, String test) {
        if (test == null) {
        if (filter == null || "*/*".equals(filter)) {
            return true;
        } else if (test == null) {
            return false;
        } else if (filter.equals(test)) {
            return true;
        } else if ("*/*".equals(filter)) {
            return true;
        } else if (filter.endsWith("/*")) {
            return filter.regionMatches(0, test, 0, filter.indexOf('/'));
        } else {
+3 −36
Original line number Diff line number Diff line
@@ -21,15 +21,11 @@ import static com.android.documentsui.DocumentsActivity.TAG;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.util.Log;

@@ -153,33 +149,8 @@ public class RootsCache {
        return mRoots;
    }

    /**
     * Flags that declare explicit content types.
     */
    private static final int FLAGS_CONTENT_MASK = Root.FLAG_PROVIDES_IMAGES
            | Root.FLAG_PROVIDES_AUDIO | Root.FLAG_PROVIDES_VIDEO;

    @GuardedBy("ActivityThread")
    public List<RootInfo> getMatchingRoots(State state) {

        // Determine acceptable content flags
        int includeFlags = 0;
        for (String acceptMime : state.acceptMimes) {
            final String[] type = acceptMime.split("/");
            if (type.length != 2) continue;

            if ("image".equals(type[0])) {
                includeFlags |= Root.FLAG_PROVIDES_IMAGES;
            } else if ("audio".equals(type[0])) {
                includeFlags |= Root.FLAG_PROVIDES_AUDIO;
            } else if ("video".equals(type[0])) {
                includeFlags |= Root.FLAG_PROVIDES_VIDEO;
            } else if ("*".equals(type[0])) {
                includeFlags |= Root.FLAG_PROVIDES_IMAGES | Root.FLAG_PROVIDES_AUDIO
                        | Root.FLAG_PROVIDES_VIDEO;
            }
        }

        ArrayList<RootInfo> matching = Lists.newArrayList();
        for (RootInfo root : mRoots) {
            final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0;
@@ -193,14 +164,10 @@ public class RootsCache {
            // Exclude non-local devices when local only
            if (state.localOnly && !localOnly) continue;

            if ((root.flags & FLAGS_CONTENT_MASK) != 0) {
                // This root offers specific content, so only include if the
                // caller asked for that content type.
                if ((root.flags & includeFlags) == 0) {
                    // Sorry, no overlap.
            // Only include roots that serve requested content
            if (!MimePredicate.mimeMatches(root.mimeTypes, state.acceptMimes)) {
                continue;
            }
            }

            matching.add(root);
        }
+3 −5
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ public class RootInfo {
    public String summary;
    public String documentId;
    public long availableBytes;
    public String[] mimeTypes;

    public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
        final RootInfo root = new RootInfo();
@@ -55,11 +56,8 @@ public class RootInfo {
        root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
        root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);

        // TODO: remove this hack
        if ("com.google.android.apps.docs.storage".equals(root.authority)) {
            root.flags &= ~(Root.FLAG_PROVIDES_AUDIO | Root.FLAG_PROVIDES_IMAGES
                    | Root.FLAG_PROVIDES_VIDEO);
        }
        final String raw = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
        root.mimeTypes = (raw != null) ? raw.split("\n") : null;

        return root;
    }