1 /* 2 * Copyright (C) 2013 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.google.common.collect.Lists.newArrayList; 20 import static com.google.common.truth.Truth.assertThat; 21 22 import android.provider.DocumentsContract; 23 import android.test.AndroidTestCase; 24 import android.test.suitebuilder.annotation.SmallTest; 25 26 import androidx.annotation.Nullable; 27 28 import com.android.documentsui.base.Providers; 29 import com.android.documentsui.base.RootInfo; 30 import com.android.documentsui.base.State; 31 import com.android.documentsui.base.UserId; 32 33 import com.google.common.collect.Lists; 34 import com.google.common.truth.Correspondence; 35 36 import java.util.List; 37 import java.util.Objects; 38 39 @SmallTest 40 public class ProvidersAccessTest extends AndroidTestCase { 41 42 private static final UserId OTHER_USER = UserId.of(UserId.DEFAULT_USER.getIdentifier() + 1); 43 private static final Correspondence<RootInfo, RootInfo> USER_ID_MIME_TYPES_CORRESPONDENCE = 44 new Correspondence<RootInfo, RootInfo>() { 45 @Override 46 public boolean compare(@Nullable RootInfo actual, @Nullable RootInfo expected) { 47 return actual != null && expected != null 48 && Objects.equals(actual.userId, expected.userId) 49 && Objects.equals(actual.derivedMimeTypes, expected.derivedMimeTypes); 50 } 51 52 @Override 53 public String toString() { 54 return "has same userId and mimeTypes as in"; 55 } 56 }; 57 58 private static RootInfo mNull = buildForMimeTypes((String[]) null); 59 private static RootInfo mEmpty = buildForMimeTypes(); 60 private static RootInfo mWild = buildForMimeTypes("*/*"); 61 private static RootInfo mImages = buildForMimeTypes("image/*"); 62 private static RootInfo mAudio = buildForMimeTypes( 63 "audio/*", "application/ogg", "application/x-flac"); 64 private static RootInfo mDocs = buildForMimeTypes( 65 "application/msword", "application/vnd.ms-excel"); 66 private static RootInfo mMalformed1 = buildForMimeTypes("meow"); 67 private static RootInfo mMalformed2 = buildForMimeTypes("*/meow"); 68 private static RootInfo mImagesOtherUser = buildForMimeTypes(OTHER_USER, "image/*"); 69 70 private List<RootInfo> mRoots; 71 72 private State mState; 73 74 @Override setUp()75 protected void setUp() throws Exception { 76 super.setUp(); 77 78 mRoots = Lists.newArrayList( 79 mNull, mWild, mEmpty, mImages, mAudio, mDocs, mMalformed1, mMalformed2, 80 mImagesOtherUser); 81 82 mState = new State(); 83 mState.action = State.ACTION_OPEN; 84 mState.localOnly = false; 85 } 86 testMatchingRoots_Everything()87 public void testMatchingRoots_Everything() throws Exception { 88 mState.acceptMimes = new String[]{"*/*"}; 89 assertContainsExactly( 90 newArrayList(mNull, mWild, mImages, mAudio, mDocs, mMalformed1, mMalformed2), 91 ProvidersAccess.getMatchingRoots(mRoots, mState)); 92 } 93 testMatchingRoots_PngOrWild()94 public void testMatchingRoots_PngOrWild() throws Exception { 95 mState.acceptMimes = new String[] { "image/png", "*/*" }; 96 assertContainsExactly( 97 newArrayList(mNull, mWild, mImages, mAudio, mDocs, mMalformed1, mMalformed2), 98 ProvidersAccess.getMatchingRoots(mRoots, mState)); 99 } 100 testMatchingRoots_AudioWild()101 public void testMatchingRoots_AudioWild() throws Exception { 102 mState.acceptMimes = new String[] { "audio/*" }; 103 assertContainsExactly( 104 newArrayList(mNull, mWild, mAudio), 105 ProvidersAccess.getMatchingRoots(mRoots, mState)); 106 } 107 testMatchingRoots_AudioWildOrImageWild()108 public void testMatchingRoots_AudioWildOrImageWild() throws Exception { 109 mState.acceptMimes = new String[] { "audio/*", "image/*" }; 110 assertContainsExactly( 111 newArrayList(mNull, mWild, mAudio, mImages), 112 ProvidersAccess.getMatchingRoots(mRoots, mState)); 113 } 114 testMatchingRoots_AudioSpecific()115 public void testMatchingRoots_AudioSpecific() throws Exception { 116 mState.acceptMimes = new String[] { "audio/mpeg" }; 117 assertContainsExactly( 118 newArrayList(mNull, mWild, mAudio), 119 ProvidersAccess.getMatchingRoots(mRoots, mState)); 120 } 121 testMatchingRoots_Document()122 public void testMatchingRoots_Document() throws Exception { 123 mState.acceptMimes = new String[] { "application/msword" }; 124 assertContainsExactly( 125 newArrayList(mNull, mWild, mDocs), 126 ProvidersAccess.getMatchingRoots(mRoots, mState)); 127 } 128 testMatchingRoots_Application()129 public void testMatchingRoots_Application() throws Exception { 130 mState.acceptMimes = new String[] { "application/*" }; 131 assertContainsExactly( 132 newArrayList(mNull, mWild, mAudio, mDocs), 133 ProvidersAccess.getMatchingRoots(mRoots, mState)); 134 } 135 testMatchingRoots_FlacOrPng()136 public void testMatchingRoots_FlacOrPng() throws Exception { 137 mState.acceptMimes = new String[] { "application/x-flac", "image/png" }; 138 assertContainsExactly( 139 newArrayList(mNull, mWild, mAudio, mImages), 140 ProvidersAccess.getMatchingRoots(mRoots, mState)); 141 } 142 testMatchingRoots_FlacOrPng_crossProfile()143 public void testMatchingRoots_FlacOrPng_crossProfile() throws Exception { 144 mState.supportsCrossProfile = true; 145 mState.acceptMimes = new String[]{"application/x-flac", "image/png"}; 146 assertContainsExactly( 147 newArrayList(mNull, mWild, mAudio, mImages, mImagesOtherUser), 148 ProvidersAccess.getMatchingRoots(mRoots, mState)); 149 } 150 testDefaultRoot()151 public void testDefaultRoot() { 152 mState.acceptMimes = new String[] { "*/*" }; 153 assertNull(ProvidersAccess.getDefaultRoot(mRoots, mState)); 154 155 RootInfo downloads = buildForMimeTypes("*/*"); 156 downloads.authority = Providers.AUTHORITY_DOWNLOADS; 157 mRoots.add(downloads); 158 159 assertEquals(downloads, ProvidersAccess.getDefaultRoot(mRoots, mState)); 160 } 161 testDefaultRoot_openDocumentTree()162 public void testDefaultRoot_openDocumentTree() { 163 RootInfo storage = buildForMimeTypes("*/*"); 164 storage.authority = Providers.AUTHORITY_STORAGE; 165 storage.flags = DocumentsContract.Root.FLAG_SUPPORTS_IS_CHILD; 166 mRoots.add(storage); 167 168 mState.action = State.ACTION_OPEN_TREE; 169 mState.acceptMimes = new String[] { "*/*" }; 170 assertEquals(storage, ProvidersAccess.getDefaultRoot(mRoots, mState)); 171 } 172 testExcludedAuthorities()173 public void testExcludedAuthorities() throws Exception { 174 final List<RootInfo> roots = newArrayList(); 175 176 // Set up some roots 177 for (int i = 0; i < 5; ++i) { 178 RootInfo root = new RootInfo(); 179 root.userId = UserId.DEFAULT_USER; 180 root.authority = "authority" + i; 181 roots.add(root); 182 } 183 // Make some allowed authorities 184 List<RootInfo> allowedRoots = newArrayList( 185 roots.get(0), roots.get(2), roots.get(4)); 186 // Set up the excluded authority list 187 for (RootInfo root: roots) { 188 if (!allowedRoots.contains(root)) { 189 mState.excludedAuthorities.add(root.authority); 190 } 191 } 192 mState.acceptMimes = new String[] { "*/*" }; 193 194 assertContainsExactly( 195 allowedRoots, 196 ProvidersAccess.getMatchingRoots(roots, mState)); 197 } 198 assertContainsExactly(List<RootInfo> expected, List<RootInfo> actual)199 private static void assertContainsExactly(List<RootInfo> expected, List<RootInfo> actual) { 200 assertThat(actual) 201 .comparingElementsUsing(USER_ID_MIME_TYPES_CORRESPONDENCE) 202 .containsExactlyElementsIn(expected); 203 } 204 buildForMimeTypes(String... mimeTypes)205 private static RootInfo buildForMimeTypes(String... mimeTypes) { 206 return buildForMimeTypes(UserId.DEFAULT_USER, mimeTypes); 207 } 208 buildForMimeTypes(UserId userId, String... mimeTypes)209 private static RootInfo buildForMimeTypes(UserId userId, String... mimeTypes) { 210 final RootInfo root = new RootInfo(); 211 root.userId = userId; 212 root.derivedMimeTypes = mimeTypes; 213 return root; 214 } 215 } 216