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.app.DownloadManager;
23import android.app.DownloadManager.Request;
24import android.content.Context;
25import android.content.Intent;
26import android.net.Uri;
27import android.os.RemoteException;
28import android.provider.DocumentsContract;
29import android.support.test.uiautomator.Configurator;
30import android.support.test.uiautomator.UiObject;
31import android.test.suitebuilder.annotation.LargeTest;
32import android.test.suitebuilder.annotation.Suppress;
33import android.view.KeyEvent;
34import android.view.MotionEvent;
35
36import com.android.documentsui.model.RootInfo;
37
38@LargeTest
39public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
40
41    public FilesActivityUiTest() {
42        super(FilesActivity.class);
43    }
44
45    @Override
46    protected RootInfo getInitialRoot() {
47        return null;
48    }
49
50    @Override
51    public void initTestFiles() throws RemoteException {
52        mDocsHelper.createDocument(rootDir0, "text/plain", "file0.log");
53        mDocsHelper.createDocument(rootDir0, "image/png", "file1.png");
54        mDocsHelper.createDocument(rootDir0, "text/csv", "file2.csv");
55
56        mDocsHelper.createDocument(rootDir1, "text/plain", "anotherFile0.log");
57        mDocsHelper.createDocument(rootDir1, "text/plain", "poodles.text");
58    }
59
60    public void testRootsListed() throws Exception {
61        initTestFiles();
62
63        // Should also have Drive, but that requires pre-configuration of devices
64        // We omit for now.
65        bots.roots.assertRootsPresent(
66                "Images",
67                "Videos",
68                "Audio",
69                "Downloads",
70                ROOT_0_ID,
71                ROOT_1_ID);
72
73        // Separate logic for "Documents" root, which presence depends on the config setting
74        if (Shared.shouldShowDocumentsRoot(context, new Intent(DocumentsContract.ACTION_BROWSE))) {
75            bots.roots.assertRootsPresent("Documents");
76        } else {
77            bots.roots.assertRootsAbsent("Documents");
78        }
79    }
80
81    public void testFilesListed() throws Exception {
82        initTestFiles();
83
84        bots.roots.openRoot(ROOT_0_ID);
85        bots.directory.assertDocumentsPresent("file0.log", "file1.png", "file2.csv");
86    }
87
88    public void testLoadsDownloadsDirectoryByDefault() throws Exception {
89        initTestFiles();
90
91        device.waitForIdle();
92        bots.main.assertWindowTitle("Downloads");
93    }
94
95    public void testRootClickSetsWindowTitle() throws Exception {
96        initTestFiles();
97
98        bots.roots.openRoot("Downloads");
99        bots.main.assertWindowTitle("Downloads");
100    }
101
102    public void testFilesList_LiveUpdate() throws Exception {
103        initTestFiles();
104
105        bots.roots.openRoot(ROOT_0_ID);
106        mDocsHelper.createDocument(rootDir0, "yummers/sandwich", "Ham & Cheese.sandwich");
107
108        bots.directory.waitForDocument("Ham & Cheese.sandwich");
109        bots.directory.assertDocumentsPresent(
110                "file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
111    }
112
113    public void testCreateDirectory() throws Exception {
114        initTestFiles();
115
116        bots.roots.openRoot(ROOT_0_ID);
117
118        bots.main.openOverflowMenu();
119        bots.main.menuNewFolder().click();
120        bots.main.setDialogText("Kung Fu Panda");
121
122        bots.keyboard.pressEnter();
123
124        bots.directory.assertDocumentsPresent("Kung Fu Panda");
125    }
126
127    public void testDeleteDocument() throws Exception {
128        initTestFiles();
129
130        bots.roots.openRoot(ROOT_0_ID);
131
132        bots.directory.clickDocument("file1.png");
133        device.waitForIdle();
134        bots.main.menuDelete().click();
135
136        bots.main.findDialogOkButton().click();
137
138        bots.directory.assertDocumentsAbsent("file1.png");
139    }
140
141    public void testDeleteDocument_Cancel() throws Exception {
142        initTestFiles();
143
144        bots.roots.openRoot(ROOT_0_ID);
145
146        bots.directory.clickDocument("file1.png");
147        device.waitForIdle();
148        bots.main.menuDelete().click();
149
150        bots.main.findDialogCancelButton().click();
151
152        bots.directory.assertDocumentsPresent("file1.png");
153    }
154
155    // Tests that pressing tab switches focus between the roots and directory listings.
156    @Suppress
157    public void testKeyboard_tab() throws Exception {
158        bots.main.pressKey(KeyEvent.KEYCODE_TAB);
159        bots.roots.assertHasFocus();
160        bots.main.pressKey(KeyEvent.KEYCODE_TAB);
161        bots.directory.assertHasFocus();
162    }
163
164    // Tests that arrow keys do not switch focus away from the dir list.
165    @Suppress
166    public void testKeyboard_arrowsDirList() throws Exception {
167        for (int i = 0; i < 10; i++) {
168            bots.main.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
169            bots.directory.assertHasFocus();
170        }
171        for (int i = 0; i < 10; i++) {
172            bots.main.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
173            bots.directory.assertHasFocus();
174        }
175    }
176
177    // Tests that arrow keys do not switch focus away from the roots list.
178    public void testKeyboard_arrowsRootsList() throws Exception {
179        bots.main.pressKey(KeyEvent.KEYCODE_TAB);
180        for (int i = 0; i < 10; i++) {
181            bots.main.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
182            bots.roots.assertHasFocus();
183        }
184        for (int i = 0; i < 10; i++) {
185            bots.main.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
186            bots.roots.assertHasFocus();
187        }
188    }
189
190    // We don't really need to test the entirety of download support
191    // since downloads is (almost) just another provider.
192    @Suppress
193    public void testDownload_Queued() throws Exception {
194        DownloadManager dm = (DownloadManager) context.getSystemService(
195                Context.DOWNLOAD_SERVICE);
196        // This downloads ends up being queued (because DNS can't be resolved).
197        // We'll still see an entry in the downloads UI with a "Queued" label.
198        dm.enqueue(new Request(Uri.parse("http://hammychamp.toodles")));
199
200        bots.roots.openRoot("Downloads");
201        bots.directory.assertDocumentsPresent("Queued");
202    }
203
204    @Suppress
205    public void testDownload_RetryUnsuccessful() throws Exception {
206        DownloadManager dm = (DownloadManager) context.getSystemService(
207                Context.DOWNLOAD_SERVICE);
208        // This downloads fails! But it'll still show up.
209        dm.enqueue(new Request(Uri.parse("http://www.google.com/hamfancy")));
210
211        bots.roots.openRoot("Downloads");
212        UiObject doc = bots.directory.findDocument("Unsuccessful");
213        doc.waitForExists(TIMEOUT);
214
215        int toolType = Configurator.getInstance().getToolType();
216        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
217        doc.click();
218        Configurator.getInstance().setToolType(toolType);
219
220        assertTrue(bots.main.findDownloadRetryDialog().exists());
221
222        device.pressBack(); // to clear the dialog.
223    }
224}
225