Home | History | Annotate | Download | only in roots
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.documentsui.roots;
     18 
     19 import static com.android.documentsui.base.Shared.DEBUG;
     20 import static com.android.documentsui.base.Shared.VERBOSE;
     21 
     22 import android.util.Log;
     23 
     24 import com.android.documentsui.base.MimeTypes;
     25 import com.android.documentsui.base.RootInfo;
     26 import com.android.documentsui.base.State;
     27 
     28 import java.util.ArrayList;
     29 import java.util.Arrays;
     30 import java.util.Collection;
     31 import java.util.List;
     32 
     33 /**
     34  * Provides testable access to key {@link ProvidersCache} methods.
     35  */
     36 public interface ProvidersAccess {
     37 
     38     String BROADCAST_ACTION = "com.android.documentsui.action.ROOT_CHANGED";
     39 
     40     /**
     41      * Return the requested {@link RootInfo}, but only loading the roots for the
     42      * requested authority. This is useful when we want to load fast without
     43      * waiting for all the other roots to come back.
     44      */
     45     RootInfo getRootOneshot(String authority, String rootId);
     46 
     47     Collection<RootInfo> getMatchingRootsBlocking(State state);
     48 
     49     Collection<RootInfo> getRootsBlocking();
     50 
     51     RootInfo getDefaultRootBlocking(State state);
     52 
     53     RootInfo getRecentsRoot();
     54 
     55     String getApplicationName(String authority);
     56 
     57     String getPackageName(String authority);
     58 
     59     /**
     60      * Returns a list of roots for the specified authority. If not found, then
     61      * an empty list is returned.
     62      */
     63     Collection<RootInfo> getRootsForAuthorityBlocking(String authority);
     64 
     65     public static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) {
     66 
     67         final String tag = "ProvidersAccess";
     68 
     69         final List<RootInfo> matching = new ArrayList<>();
     70         for (RootInfo root : roots) {
     71 
     72             if (VERBOSE) Log.v(tag, "Evaluationg root: " + root);
     73 
     74             if (state.action == State.ACTION_CREATE && !root.supportsCreate()) {
     75                 if (VERBOSE) Log.v(tag, "Excluding read-only root because: ACTION_CREATE.");
     76                 continue;
     77             }
     78 
     79             if (state.action == State.ACTION_PICK_COPY_DESTINATION
     80                     && !root.supportsCreate()) {
     81                 if (VERBOSE) Log.v(
     82                         tag, "Excluding read-only root because: ACTION_PICK_COPY_DESTINATION.");
     83                 continue;
     84             }
     85 
     86             if (state.action == State.ACTION_OPEN_TREE && !root.supportsChildren()) {
     87                 if (VERBOSE) Log.v(
     88                         tag, "Excluding root !supportsChildren because: ACTION_OPEN_TREE.");
     89                 continue;
     90             }
     91 
     92             if (!state.showAdvanced && root.isAdvanced()) {
     93                 if (VERBOSE) Log.v(tag, "Excluding root because: unwanted advanced device.");
     94                 continue;
     95             }
     96 
     97             if (state.localOnly && !root.isLocalOnly()) {
     98                 if (VERBOSE) Log.v(tag, "Excluding root because: unwanted non-local device.");
     99                 continue;
    100             }
    101 
    102             if (state.directoryCopy && root.isDownloads()) {
    103                 if (VERBOSE) Log.v(
    104                         tag, "Excluding downloads root because: unsupported directory copy.");
    105                 continue;
    106             }
    107 
    108             if (state.action == State.ACTION_OPEN && root.isEmpty()) {
    109                 if (VERBOSE) Log.v(tag, "Excluding empty root because: ACTION_OPEN.");
    110                 continue;
    111             }
    112 
    113             if (state.action == State.ACTION_GET_CONTENT && root.isEmpty()) {
    114                 if (VERBOSE) Log.v(tag, "Excluding empty root because: ACTION_GET_CONTENT.");
    115                 continue;
    116             }
    117 
    118             final boolean overlap =
    119                     MimeTypes.mimeMatches(root.derivedMimeTypes, state.acceptMimes) ||
    120                     MimeTypes.mimeMatches(state.acceptMimes, root.derivedMimeTypes);
    121             if (!overlap) {
    122                 if (VERBOSE) Log.v(
    123                         tag, "Excluding root because: unsupported content types > "
    124                         + Arrays.toString(state.acceptMimes));
    125                 continue;
    126             }
    127 
    128             if (state.excludedAuthorities.contains(root.authority)) {
    129                 if (VERBOSE) Log.v(tag, "Excluding root because: owned by calling package.");
    130                 continue;
    131             }
    132 
    133             matching.add(root);
    134         }
    135 
    136         if (DEBUG) Log.d(tag, "Matched roots: " + matching);
    137         return matching;
    138     }
    139 }
    140