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 package com.android.documentsui.testing; 17 18 import android.content.Context; 19 import android.provider.DocumentsContract.Document; 20 import android.support.test.InstrumentationRegistry; 21 import android.test.mock.MockContentResolver; 22 23 import com.android.documentsui.DocsSelectionHelper; 24 import com.android.documentsui.FocusManager; 25 import com.android.documentsui.Injector; 26 import com.android.documentsui.archives.ArchivesProvider; 27 import com.android.documentsui.base.DocumentInfo; 28 import com.android.documentsui.base.Features; 29 import com.android.documentsui.base.RootInfo; 30 import com.android.documentsui.base.State; 31 import com.android.documentsui.dirlist.TestFocusHandler; 32 import com.android.documentsui.sorting.SortModel; 33 import com.android.documentsui.ui.TestDialogController; 34 35 import java.util.ArrayList; 36 import java.util.HashMap; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.concurrent.Executor; 40 41 public class TestEnv { 42 43 public static DocumentInfo FOLDER_0; 44 public static DocumentInfo FOLDER_1; 45 public static DocumentInfo FOLDER_2; 46 public static DocumentInfo FILE_TXT; 47 public static DocumentInfo FILE_PNG; 48 public static DocumentInfo FILE_JPG; 49 public static DocumentInfo FILE_GIF; 50 public static DocumentInfo FILE_PDF; 51 public static DocumentInfo FILE_MP4; 52 public static DocumentInfo FILE_APK; 53 public static DocumentInfo FILE_PARTIAL; 54 public static DocumentInfo FILE_ARCHIVE; 55 public static DocumentInfo FILE_IN_ARCHIVE; 56 public static DocumentInfo FILE_VIRTUAL; 57 public static DocumentInfo FILE_READ_ONLY; 58 59 public final TestScheduledExecutorService mExecutor; 60 public final State state = new State(); 61 public final TestProvidersAccess providers = new TestProvidersAccess(); 62 public final TestDocumentsAccess docs = new TestDocumentsAccess(); 63 public final TestFocusHandler focusHandler = new TestFocusHandler(); 64 public final TestDialogController dialogs = new TestDialogController(); 65 public final TestModel model; 66 public final TestModel archiveModel; 67 public final DocsSelectionHelper selectionMgr; 68 public final TestSearchViewManager searchViewManager; 69 public final Injector<?> injector; 70 public final Features features; 71 72 public final MockContentResolver contentResolver; 73 public final Map<String, TestDocumentsProvider> mockProviders; 74 75 private TestEnv(Context context, Features features, String authority) { 76 this.features = features; 77 state.sortModel = SortModel.createModel(); 78 mExecutor = new TestScheduledExecutorService(); 79 model = new TestModel(authority, features); 80 archiveModel = new TestModel(ArchivesProvider.AUTHORITY, features); 81 selectionMgr = SelectionHelpers.createTestInstance(); 82 searchViewManager = new TestSearchViewManager(); 83 injector = new Injector( 84 features, 85 new TestActivityConfig(), 86 null, // ScopedPreferences are not currently required for tests 87 null, // MessageBuilder is not currently required for tests 88 dialogs, 89 new TestFileTypeLookup(), 90 (roots) -> {}, // not sure why, but java gets angry when I declare roots type. 91 model); 92 93 injector.selectionMgr = selectionMgr; 94 injector.focusManager = new FocusManager(features, selectionMgr, null, null, 0); 95 injector.searchManager = searchViewManager; 96 97 contentResolver = new MockContentResolver(); 98 mockProviders = new HashMap<>(providers.getRootsBlocking().size()); 99 registerProviders(); 100 } 101 102 private void registerProviders() { 103 for (RootInfo root : providers.getRootsBlocking()) { 104 if (!mockProviders.containsKey(root.authority)) { 105 TestDocumentsProvider provider = new TestDocumentsProvider(root.authority); 106 contentResolver.addProvider(root.authority, provider); 107 mockProviders.put(root.authority, provider); 108 } 109 } 110 } 111 112 // Many terrible creational permutations == easy to user for test authors! 113 public static TestEnv create(Features features) { 114 return create(features, TestProvidersAccess.HOME.authority); 115 } 116 117 public static TestEnv create() { 118 return create(TestProvidersAccess.HOME.authority); 119 } 120 121 public static TestEnv create(Features features, String authority) { 122 Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); 123 return create(context, features, authority); 124 } 125 126 public static TestEnv create(String authority) { 127 Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); 128 Features features = new Features.RuntimeFeatures(context.getResources(), null); 129 return create(context, features, authority); 130 } 131 132 private static TestEnv create(Context context, Features features, String authority) { 133 TestEnv env = new TestEnv(context, features, authority); 134 env.reset(); 135 return env; 136 } 137 138 public void clear() { 139 model.reset(); 140 model.update(); 141 } 142 143 public void reset() { 144 model.reset(); 145 FOLDER_0 = model.createFolder("folder 0"); 146 FOLDER_1 = model.createFolder("folder 1"); 147 FOLDER_2 = model.createFolder("folder 2"); 148 FILE_TXT = model.createFile("woowoo.txt"); 149 FILE_PNG = model.createFile("peppey.png"); 150 FILE_JPG = model.createFile("jiffy.jpg"); 151 FILE_GIF = model.createFile("glibby.gif"); 152 FILE_PDF = model.createFile("busy.pdf"); 153 FILE_MP4 = model.createFile("cameravideo.mp4"); 154 FILE_APK = model.createFile("becareful.apk"); 155 FILE_PARTIAL = model.createFile( 156 "UbuntuFlappyBird.iso", 157 Document.FLAG_SUPPORTS_DELETE 158 | Document.FLAG_PARTIAL); 159 FILE_READ_ONLY = model.createFile("topsecretsystemfile.bin", 0); 160 FILE_ARCHIVE = model.createFile("whatsinthere.zip"); 161 FILE_IN_ARCHIVE = archiveModel.createFile("whatsinthere.png", 0); 162 FILE_VIRTUAL = model.createDocument( 163 "virtualdoc.vnd", 164 "application/vnd.google-apps.document", 165 Document.FLAG_VIRTUAL_DOCUMENT 166 | Document.FLAG_SUPPORTS_DELETE 167 | Document.FLAG_SUPPORTS_RENAME); 168 169 archiveModel.update(); 170 model.update(); 171 } 172 173 public void populateStack() { 174 DocumentInfo rootDoc = model.getDocument("1"); 175 176 // These are test setup sanity checks, not test assertions. 177 assert rootDoc != null; 178 assert rootDoc.isDirectory(); 179 assert FOLDER_0.equals(rootDoc); 180 181 state.stack.changeRoot(TestProvidersAccess.HOME); 182 state.stack.push(rootDoc); 183 } 184 185 public void beforeAsserts() throws Exception { 186 mExecutor.waitForTasks(30000); // 30 secs 187 } 188 189 public Executor lookupExecutor(String authority) { 190 return mExecutor; 191 } 192 193 public void selectDocument(DocumentInfo info) { 194 List<String> ids = new ArrayList<>(1); 195 ids.add(info.documentId); 196 selectionMgr.setItemsSelected(ids, true); 197 } 198 199 // Easily copy docs, so we don't pollute static data across tests. 200 public static DocumentInfo clone(DocumentInfo a) { 201 DocumentInfo b = new DocumentInfo(); 202 b.authority = a.authority; 203 b.documentId = a.documentId; 204 b.mimeType = a.mimeType; 205 b.displayName = a.displayName; 206 b.lastModified = a.lastModified; 207 b.flags = a.flags; 208 b.summary = a.summary; 209 b.size = a.size; 210 b.icon = a.icon; 211 b.derivedUri = a.derivedUri; 212 213 return b; 214 } 215 } 216