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

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

Merge "Filter roots based on incoming request." into klp-dev

parents 7c925042 348ad686
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -191,7 +191,9 @@ public class DirectoryFragment extends Fragment {
                                authority, docId, query);
                        return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder);
                    case TYPE_RECENT_OPEN:
                        return new RecentLoader(context);
                        final RootsCache roots = DocumentsApplication.getRootsCache(context);
                        final List<RootInfo> matchingRoots = roots.getMatchingRoots(state);
                        return new RecentLoader(context, matchingRoots);
                    default:
                        throw new IllegalStateException("Unknown type " + mType);

+4 −0
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ public class DocumentsActivity extends Activity {
        }

        mState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
        mState.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(this);

        if (mState.action == ACTION_MANAGE) {
            mState.sortOrder = SORT_ORDER_LAST_MODIFIED;
@@ -701,6 +702,7 @@ public class DocumentsActivity extends Activity {
        public boolean allowMultiple = false;
        public boolean showSize = false;
        public boolean localOnly = false;
        public boolean showAdvanced = false;

        /** Current user navigation stack; empty implies recents. */
        public DocumentStack stack = new DocumentStack();
@@ -733,6 +735,7 @@ public class DocumentsActivity extends Activity {
            out.writeInt(allowMultiple ? 1 : 0);
            out.writeInt(showSize ? 1 : 0);
            out.writeInt(localOnly ? 1 : 0);
            out.writeInt(showAdvanced ? 1 : 0);
            DurableUtils.writeToParcel(out, stack);
            out.writeString(currentSearch);
        }
@@ -748,6 +751,7 @@ public class DocumentsActivity extends Activity {
                state.allowMultiple = in.readInt() != 0;
                state.showSize = in.readInt() != 0;
                state.localOnly = in.readInt() != 0;
                state.showAdvanced = in.readInt() != 0;
                DurableUtils.readFromParcel(in, state.stack);
                state.currentSearch = in.readString();
                return state;
+5 −3
Original line number Diff line number Diff line
@@ -78,6 +78,8 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
        return executor;
    }

    private final List<RootInfo> mRoots;

    private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap();

    private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED;
@@ -133,8 +135,9 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
        }
    }

    public RecentLoader(Context context) {
    public RecentLoader(Context context, List<RootInfo> roots) {
        super(context);
        mRoots = roots;
    }

    @Override
@@ -143,8 +146,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
            // First time through we kick off all the recent tasks, and wait
            // around to see if everyone finishes quickly.

            final RootsCache roots = DocumentsApplication.getRootsCache(getContext());
            for (RootInfo root : roots.getRoots()) {
            for (RootInfo root : mRoots) {
                if ((root.flags & Root.FLAG_SUPPORTS_RECENTS) != 0) {
                    final RecentTask task = new RecentTask(root.authority, root.rootId);
                    mTasks.put(root, task);
+57 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.util.Log;

import com.android.documentsui.DocumentsActivity.State;
import com.android.documentsui.model.RootInfo;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Objects;
@@ -40,6 +41,7 @@ import com.google.android.collect.Lists;

import libcore.io.IoUtils;

import java.util.ArrayList;
import java.util.List;

/**
@@ -75,6 +77,7 @@ public class RootsCache {
            final RootInfo root = new RootInfo();
            root.rootType = Root.ROOT_TYPE_SHORTCUT;
            root.icon = R.drawable.ic_dir;
            root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE;
            root.title = mContext.getString(R.string.root_recent);
            root.availableBytes = -1;

@@ -150,6 +153,60 @@ 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;
            final boolean advanced = (root.flags & Root.FLAG_ADVANCED) != 0;
            final boolean localOnly = (root.flags & Root.FLAG_LOCAL_ONLY) != 0;

            // Exclude read-only devices when creating
            if (state.action == State.ACTION_CREATE && !supportsCreate) continue;
            // Exclude advanced devices when not requested
            if (!state.showAdvanced && advanced) continue;
            // 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.
                    continue;
                }
            }

            matching.add(root);
        }
        return matching;
    }

    @GuardedBy("ActivityThread")
    public static Drawable resolveDocumentIcon(Context context, String mimeType) {
        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+22 −24
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.documentsui;

import static com.android.documentsui.DocumentsActivity.TAG;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
@@ -28,7 +26,6 @@ import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.provider.DocumentsContract.Root;
import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -39,6 +36,7 @@ import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.android.documentsui.DocumentsActivity.State;
import com.android.documentsui.SectionedListAdapter.SectionAdapter;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
@@ -76,24 +74,31 @@ public class RootsFragment extends Fragment {
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final Context context = inflater.getContext();
        final RootsCache roots = DocumentsApplication.getRootsCache(context);

        final View view = inflater.inflate(R.layout.fragment_roots, container, false);
        mList = (ListView) view.findViewById(android.R.id.list);
        mList.setOnItemClickListener(mItemListener);

        final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS);
        mAdapter = new SectionedRootsAdapter(context, roots.getRoots(), includeApps);

        return view;
    }

    @Override
    public void onStart() {
        super.onStart();
        updateRootsAdapter();
    }

    private void updateRootsAdapter() {
        final Context context = getActivity();
        mAdapter.updateVisible(SettingsActivity.getDisplayAdvancedDevices(context));

        final State state = ((DocumentsActivity) context).getDisplayState();
        state.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(context);

        final RootsCache roots = DocumentsApplication.getRootsCache(context);
        final List<RootInfo> matchingRoots = roots.getMatchingRoots(state);
        final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS);

        mAdapter = new SectionedRootsAdapter(context, matchingRoots, includeApps);
        mList.setAdapter(mAdapter);
    }

@@ -211,18 +216,15 @@ public class RootsFragment extends Fragment {
        private final RootsAdapter mServices;
        private final RootsAdapter mShortcuts;
        private final RootsAdapter mDevices;
        private final RootsAdapter mDevicesAdvanced;
        private final AppsAdapter mApps;

        public SectionedRootsAdapter(Context context, List<RootInfo> roots, Intent includeApps) {
            mServices = new RootsAdapter(context, R.string.root_type_service);
            mShortcuts = new RootsAdapter(context, R.string.root_type_shortcut);
            mDevices = new RootsAdapter(context, R.string.root_type_device);
            mDevicesAdvanced = new RootsAdapter(context, R.string.root_type_device);
            mApps = new AppsAdapter(context);

            for (RootInfo root : roots) {
                Log.d(TAG, "Found rootType=" + root.rootType);
                switch (root.rootType) {
                    case Root.ROOT_TYPE_SERVICE:
                        mServices.add(root);
@@ -231,10 +233,7 @@ public class RootsFragment extends Fragment {
                        mShortcuts.add(root);
                        break;
                    case Root.ROOT_TYPE_DEVICE:
                        mDevicesAdvanced.add(root);
                        if ((root.flags & Root.FLAG_ADVANCED) == 0) {
                        mDevices.add(root);
                        }
                        break;
                }
            }
@@ -256,23 +255,16 @@ public class RootsFragment extends Fragment {
            mServices.sort(comp);
            mShortcuts.sort(comp);
            mDevices.sort(comp);
            mDevicesAdvanced.sort(comp);
        }

        public void updateVisible(boolean showAdvanced) {
            clearSections();
            if (mServices.getCount() > 0) {
                addSection(mServices);
            }
            if (mShortcuts.getCount() > 0) {
                addSection(mShortcuts);
            }

            final RootsAdapter devices = showAdvanced ? mDevicesAdvanced : mDevices;
            if (devices.getCount() > 0) {
                addSection(devices);
            if (mDevices.getCount() > 0) {
                addSection(mDevices);
            }

            if (mApps.getCount() > 0) {
                addSection(mApps);
            }
@@ -282,6 +274,12 @@ public class RootsFragment extends Fragment {
    public static class RootComparator implements Comparator<RootInfo> {
        @Override
        public int compare(RootInfo lhs, RootInfo rhs) {
            if (lhs.authority == null) {
                return -1;
            } else if (rhs.authority == null) {
                return 1;
            }

            final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title);
            if (score != 0) {
                return score;
Loading