1 /* 2 * Copyright (C) 2015 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; 18 19 import static com.android.documentsui.StubProvider.ROOT_0_ID; 20 import static com.android.documentsui.StubProvider.ROOT_1_ID; 21 22 import android.net.Uri; 23 import android.os.Bundle; 24 import android.os.RemoteException; 25 import android.view.KeyEvent; 26 27 import androidx.test.filters.LargeTest; 28 import androidx.test.filters.Suppress; 29 30 import com.android.documentsui.base.DocumentInfo; 31 import com.android.documentsui.base.Shared; 32 import com.android.documentsui.files.FilesActivity; 33 import com.android.documentsui.filters.HugeLongTest; 34 import com.android.documentsui.sorting.SortDimension; 35 import com.android.documentsui.sorting.SortModel; 36 37 import java.util.List; 38 39 @LargeTest 40 public class FileManagementUiTest extends ActivityTest<FilesActivity> { 41 FileManagementUiTest()42 public FileManagementUiTest() { 43 super(FilesActivity.class); 44 } 45 46 @Override setUp()47 public void setUp() throws Exception { 48 super.setUp(); 49 initTestFiles(); 50 } 51 52 @Override initTestFiles()53 public void initTestFiles() throws RemoteException { 54 Uri uri = mDocsHelper.createFolder(rootDir0, dirName1); 55 mDocsHelper.createFolder(uri, childDir1); 56 57 mDocsHelper.createDocument(rootDir0, "text/plain", "file0.log"); 58 mDocsHelper.createDocument(rootDir0, "image/png", "file1.png"); 59 mDocsHelper.createDocument(rootDir0, "text/csv", "file2.csv"); 60 61 mDocsHelper.createDocument(rootDir1, "text/plain", "anotherFile0.log"); 62 mDocsHelper.createDocument(rootDir1, "text/plain", "poodles.text"); 63 } 64 65 @Suppress testCreateDirectory()66 public void testCreateDirectory() throws Exception { 67 bots.main.openOverflowMenu(); 68 device.waitForIdle(); 69 70 bots.main.clickToolbarOverflowItem("New folder"); 71 device.waitForIdle(); 72 73 bots.main.setDialogText("Kung Fu Panda"); 74 device.waitForIdle(); 75 76 bots.keyboard.pressEnter(); 77 78 bots.directory.waitForDocument("Kung Fu Panda"); 79 } 80 testDeleteDocument()81 public void testDeleteDocument() throws Exception { 82 bots.directory.selectDocument("file1.png", 1); 83 device.waitForIdle(); 84 bots.main.clickToolbarItem(R.id.action_menu_delete); 85 86 bots.main.clickDialogOkButton(); 87 device.waitForIdle(); 88 89 bots.directory.assertDocumentsAbsent("file1.png"); 90 } 91 92 @HugeLongTest testKeyboard_CutDocument()93 public void testKeyboard_CutDocument() throws Exception { 94 bots.directory.selectDocument("file1.png", 1); 95 device.waitForIdle(); 96 bots.keyboard.pressKey(KeyEvent.KEYCODE_X, KeyEvent.META_CTRL_ON); 97 98 device.waitForIdle(); 99 100 bots.roots.openRoot(ROOT_1_ID); 101 bots.keyboard.pressKey(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON); 102 103 bots.directory.waitForDocument("file1.png"); 104 bots.directory.assertDocumentsPresent("file1.png"); 105 106 bots.roots.openRoot(ROOT_0_ID); 107 bots.directory.assertDocumentsAbsent("file1.png"); 108 } 109 110 @HugeLongTest testKeyboard_CopyDocument()111 public void testKeyboard_CopyDocument() throws Exception { 112 bots.directory.selectDocument("file1.png", 1); 113 device.waitForIdle(); 114 bots.keyboard.pressKey(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON); 115 116 device.waitForIdle(); 117 118 bots.roots.openRoot(ROOT_1_ID); 119 bots.keyboard.pressKey(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON); 120 121 bots.directory.waitForDocument("file1.png"); 122 123 bots.roots.openRoot(ROOT_0_ID); 124 bots.directory.waitForDocument("file1.png"); 125 } 126 127 @HugeLongTest testKeyboard_PasteDocumentWhileSelectionActive()128 public void testKeyboard_PasteDocumentWhileSelectionActive() throws Exception { 129 bots.directory.selectDocument("file1.png", 1); 130 bots.keyboard.pressKey(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON); 131 132 device.waitForIdle(); 133 bots.directory.openDocument("Dir1"); 134 bots.directory.selectDocument("ChildDir1", 1); 135 136 bots.keyboard.pressKey(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON); 137 device.waitForIdle(); 138 139 bots.directory.assertDocumentsPresent("file1.png"); 140 } 141 testDeleteDocument_Cancel()142 public void testDeleteDocument_Cancel() throws Exception { 143 bots.directory.selectDocument("file1.png", 1); 144 device.waitForIdle(); 145 bots.main.clickToolbarItem(R.id.action_menu_delete); 146 147 bots.main.clickDialogCancelButton(); 148 149 bots.directory.waitForDocument("file1.png"); 150 } 151 152 @HugeLongTest testCopyLargeAmountOfFiles()153 public void testCopyLargeAmountOfFiles() throws Exception { 154 // Suppress root notification. We're gonna create tons of files and it will soon crash 155 // DocsUI because too many root refreshes are queued in an executor. 156 Bundle conf = new Bundle(); 157 conf.putBoolean(StubProvider.EXTRA_ENABLE_ROOT_NOTIFICATION, false); 158 mDocsHelper.configure(null, conf); 159 160 final Uri test = mDocsHelper.createFolder(rootDir0, "test"); 161 final Uri target = mDocsHelper.createFolder(rootDir0, "target"); 162 String nameOfLastFile = ""; 163 for (int i = 0; i <= Shared.MAX_DOCS_IN_INTENT; ++i) { 164 final String name = i + ".txt"; 165 final Uri doc = 166 mDocsHelper.createDocument(test, "text/plain", name); 167 mDocsHelper.writeDocument(doc, Integer.toString(i).getBytes()); 168 nameOfLastFile = nameOfLastFile.compareTo(name) < 0 ? name : nameOfLastFile; 169 } 170 171 bots.roots.openRoot(ROOT_0_ID); 172 bots.directory.openDocument("test"); 173 bots.sort.sortBy( 174 SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); 175 bots.directory.waitForDocument("0.txt"); 176 bots.keyboard.pressKey( 177 KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON); 178 bots.keyboard.pressKey( 179 KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON); 180 181 bots.roots.openRoot(ROOT_0_ID); 182 bots.directory.openDocument("target"); 183 bots.directory.pasteFilesFromClipboard(); 184 185 // Use these 2 events as a signal that many files have already been copied. Only considering 186 // Android devices a more reliable way is to wait until notification goes away, but ARC++ 187 // uses Chrome OS notifications so it isn't even an option. 188 bots.directory.waitForDocument("0.txt"); 189 bots.directory.waitForDocument(nameOfLastFile); 190 191 final int expectedCount = Shared.MAX_DOCS_IN_INTENT + 1; 192 List<DocumentInfo> children = mDocsHelper.listChildren(target, -1); 193 if (children.size() == expectedCount) { 194 return; 195 } 196 197 // Files weren't copied fast enough, so gonna do some polling until they all arrive or copy 198 // seems stalled. 199 int maxRetries = 10; 200 int retries = 0; 201 while (retries++ <= maxRetries) { 202 Thread.sleep(200); 203 List<DocumentInfo> newChildren = mDocsHelper.listChildren(target, -1); 204 if (newChildren.size() == expectedCount) { 205 return; 206 } 207 208 if (newChildren.size() > expectedCount && retries >= maxRetries) { 209 // Should never happen 210 fail("Something wrong with this test case. Copied file count " 211 + newChildren.size() + " exceeds expected number " + expectedCount); 212 } 213 214 if (newChildren.size() <= children.size() && retries >= maxRetries) { 215 fail("Only copied " + children.size() 216 + " files, expected to copy " + expectedCount + " files."); 217 } 218 219 children = newChildren; 220 } 221 } 222 } 223