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

Commit 62434fcb authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Filter roots based on supported MIME types.

Using flags to indicate supported types isn't very extensible, so
use newline-separated MIME types instead.

Bug: 10514613
Change-Id: I45641fc20b423b2a0bb2df7457c274f42aa6861a
parent 5629ec59
Loading
Loading
Loading
Loading
+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;
    }