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