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 */ getRootOneshot(String authority, String rootId)45 RootInfo getRootOneshot(String authority, String rootId); 46 getMatchingRootsBlocking(State state)47 Collection<RootInfo> getMatchingRootsBlocking(State state); 48 getRootsBlocking()49 Collection<RootInfo> getRootsBlocking(); 50 getDefaultRootBlocking(State state)51 RootInfo getDefaultRootBlocking(State state); 52 getRecentsRoot()53 RootInfo getRecentsRoot(); 54 getApplicationName(String authority)55 String getApplicationName(String authority); 56 getPackageName(String authority)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 */ getRootsForAuthorityBlocking(String authority)63 Collection<RootInfo> getRootsForAuthorityBlocking(String authority); 64 getMatchingRoots(Collection<RootInfo> roots, State state)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