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