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