| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.documentsui.testing; |
| |
| import android.content.Context; |
| import android.os.UserHandle; |
| import android.provider.DocumentsContract.Document; |
| import android.test.mock.MockContentResolver; |
| |
| import androidx.test.InstrumentationRegistry; |
| |
| import com.android.documentsui.DocsSelectionHelper; |
| import com.android.documentsui.FocusManager; |
| import com.android.documentsui.Injector; |
| import com.android.documentsui.ModelId; |
| import com.android.documentsui.SelectionHelpers; |
| import com.android.documentsui.archives.ArchivesProvider; |
| import com.android.documentsui.base.DocumentInfo; |
| import com.android.documentsui.base.Features; |
| import com.android.documentsui.base.RootInfo; |
| import com.android.documentsui.base.State; |
| import com.android.documentsui.base.UserId; |
| import com.android.documentsui.dirlist.TestFocusHandler; |
| import com.android.documentsui.sorting.SortModel; |
| import com.android.documentsui.ui.TestDialogController; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.Executor; |
| |
| public class TestEnv { |
| |
| public static DocumentInfo FOLDER_0; |
| public static DocumentInfo FOLDER_1; |
| public static DocumentInfo FOLDER_2; |
| public static DocumentInfo FILE_TXT; |
| public static DocumentInfo FILE_PNG; |
| public static DocumentInfo FILE_JPG; |
| public static DocumentInfo FILE_GIF; |
| public static DocumentInfo FILE_PDF; |
| public static DocumentInfo FILE_MP4; |
| public static DocumentInfo FILE_APK; |
| public static DocumentInfo FILE_PARTIAL; |
| public static DocumentInfo FILE_ARCHIVE; |
| public static DocumentInfo FILE_IN_ARCHIVE; |
| public static DocumentInfo FILE_VIRTUAL; |
| public static DocumentInfo FILE_READ_ONLY; |
| |
| public static class OtherUser { |
| public static DocumentInfo FOLDER_0; |
| public static DocumentInfo FILE_PNG; |
| } |
| |
| public final TestScheduledExecutorService mExecutor; |
| public final State state = new State(); |
| public final TestProvidersAccess providers = new TestProvidersAccess(); |
| public final TestDocumentsAccess docs = new TestDocumentsAccess(); |
| public final TestFocusHandler focusHandler = new TestFocusHandler(); |
| public final TestDialogController dialogs = new TestDialogController(); |
| public final TestModel model; |
| public final TestModel modelOtherUser; |
| public final TestModel archiveModel; |
| public final DocsSelectionHelper selectionMgr; |
| public final TestSearchViewManager searchViewManager; |
| public final Injector<?> injector; |
| public final Features features; |
| public final UserId userId; |
| public final UserHandle userHandle; |
| |
| public final MockContentResolver contentResolver; |
| public final Map<String, TestDocumentsProvider> mockProviders; |
| |
| private TestEnv(Context context, Features features, String authority) { |
| this.features = features; |
| this.userId = TestProvidersAccess.USER_ID; |
| userHandle = UserHandle.of(userId.getIdentifier()); |
| state.sortModel = SortModel.createModel(); |
| mExecutor = new TestScheduledExecutorService(); |
| model = new TestModel(userId, authority, features); |
| modelOtherUser = new TestModel(TestProvidersAccess.OtherUser.USER_ID, authority, features); |
| archiveModel = new TestModel(userId, ArchivesProvider.AUTHORITY, features); |
| selectionMgr = SelectionHelpers.createTestInstance(); |
| searchViewManager = new TestSearchViewManager(); |
| injector = new Injector( |
| features, |
| new TestActivityConfig(), |
| null, // MessageBuilder is not currently required for tests |
| dialogs, |
| new TestFileTypeLookup(), |
| (roots) -> {}, // not sure why, but java gets angry when I declare roots type. |
| model); |
| |
| injector.selectionMgr = selectionMgr; |
| injector.focusManager = new FocusManager(features, selectionMgr, null, null, 0); |
| injector.searchManager = searchViewManager; |
| |
| contentResolver = new MockContentResolver(); |
| mockProviders = new HashMap<>(providers.getRootsBlocking().size()); |
| registerProviders(); |
| } |
| |
| private void registerProviders() { |
| for (RootInfo root : providers.getRootsBlocking()) { |
| if (!mockProviders.containsKey(root.authority)) { |
| TestDocumentsProvider provider = new TestDocumentsProvider(root.authority); |
| contentResolver.addProvider(root.authority, provider); |
| mockProviders.put(root.authority, provider); |
| } |
| } |
| } |
| |
| // Many terrible creational permutations == easy to user for test authors! |
| public static TestEnv create(Features features) { |
| return create(features, TestProvidersAccess.HOME.authority); |
| } |
| |
| public static TestEnv create() { |
| return create(TestProvidersAccess.HOME.authority); |
| } |
| |
| public static TestEnv create(Features features, String authority) { |
| Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); |
| return create(context, features, authority); |
| } |
| |
| public static TestEnv create(String authority) { |
| Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); |
| Features features = new Features.RuntimeFeatures(context.getResources(), null); |
| return create(context, features, authority); |
| } |
| |
| private static TestEnv create(Context context, Features features, String authority) { |
| TestEnv env = new TestEnv(context, features, authority); |
| env.reset(); |
| return env; |
| } |
| |
| public void clear() { |
| model.reset(); |
| model.update(); |
| } |
| |
| public void reset() { |
| model.reset(); |
| FOLDER_0 = model.createFolder("folder 0"); |
| FOLDER_1 = model.createFolder("folder 1"); |
| FOLDER_2 = model.createFolder("folder 2"); |
| FILE_TXT = model.createFile("woowoo.txt"); |
| FILE_PNG = model.createFile("peppey.png"); |
| FILE_JPG = model.createFile("jiffy.jpg"); |
| FILE_GIF = model.createFile("glibby.gif"); |
| FILE_PDF = model.createFile("busy.pdf"); |
| FILE_MP4 = model.createFile("cameravideo.mp4"); |
| FILE_APK = model.createFile("becareful.apk"); |
| FILE_PARTIAL = model.createFile( |
| "UbuntuFlappyBird.iso", |
| Document.FLAG_SUPPORTS_DELETE |
| | Document.FLAG_PARTIAL); |
| FILE_READ_ONLY = model.createFile("topsecretsystemfile.bin", 0); |
| FILE_ARCHIVE = model.createFile("whatsinthere.zip"); |
| FILE_IN_ARCHIVE = archiveModel.createFile("whatsinthere.png", 0); |
| FILE_VIRTUAL = model.createDocument( |
| "virtualdoc.vnd", |
| "application/vnd.google-apps.document", |
| Document.FLAG_VIRTUAL_DOCUMENT |
| | Document.FLAG_SUPPORTS_DELETE |
| | Document.FLAG_SUPPORTS_RENAME); |
| |
| OtherUser.FOLDER_0 = modelOtherUser.createFolder("folder 0"); |
| OtherUser.FILE_PNG = modelOtherUser.createFile("work.png"); |
| |
| archiveModel.update(); |
| model.update(); |
| } |
| |
| public void populateStack() { |
| DocumentInfo rootDoc = model.getDocument( |
| ModelId.build(model.mUserId, TestProvidersAccess.HOME.authority, "1")); |
| |
| // These are test setup sanity checks, not test assertions. |
| assert rootDoc != null; |
| assert rootDoc.isDirectory(); |
| assert FOLDER_0.equals(rootDoc); |
| |
| state.stack.changeRoot(TestProvidersAccess.HOME); |
| state.stack.push(rootDoc); |
| } |
| |
| public void beforeAsserts() throws Exception { |
| mExecutor.waitForTasks(30000); // 30 secs |
| } |
| |
| public Executor lookupExecutor(String authority) { |
| return mExecutor; |
| } |
| |
| public void selectDocument(DocumentInfo info) { |
| List<String> ids = new ArrayList<>(1); |
| ids.add(ModelId.build(info.userId, info.authority, info.documentId)); |
| selectionMgr.setItemsSelected(ids, true); |
| } |
| |
| public void selectMultipleFiles(int count) { |
| List<String> ids = new ArrayList<>(count); |
| for (int i = 0; i < count; i++) { |
| DocumentInfo info = model.createFile(String.valueOf(i)); |
| ids.add(ModelId.build(info.userId, info.authority, info.documentId)); |
| } |
| selectionMgr.setItemsSelected(ids, true); |
| } |
| |
| // Easily copy docs, so we don't pollute static data across tests. |
| public static DocumentInfo clone(DocumentInfo a) { |
| DocumentInfo b = new DocumentInfo(); |
| b.authority = a.authority; |
| b.documentId = a.documentId; |
| b.mimeType = a.mimeType; |
| b.displayName = a.displayName; |
| b.lastModified = a.lastModified; |
| b.flags = a.flags; |
| b.summary = a.summary; |
| b.size = a.size; |
| b.icon = a.icon; |
| b.derivedUri = a.derivedUri; |
| |
| return b; |
| } |
| } |