• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.content.Context;
23 import android.content.ContentResolver;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.content.BroadcastReceiver;
27 import android.net.Uri;
28 import android.os.Bundle;
29 import android.os.RemoteException;
30 import android.provider.Settings;
31 import android.support.test.filters.LargeTest;
32 import android.support.test.filters.Suppress;
33 import android.support.test.uiautomator.Configurator;
34 import android.text.TextUtils;
35 import android.view.KeyEvent;
36 import android.view.MotionEvent;
37 
38 import com.android.documentsui.base.DocumentInfo;
39 import com.android.documentsui.files.FilesActivity;
40 import com.android.documentsui.services.TestNotificationService;
41 
42 import java.util.concurrent.ArrayBlockingQueue;
43 import java.util.concurrent.CountDownLatch;
44 import java.util.concurrent.RejectedExecutionException;
45 import java.util.concurrent.ThreadPoolExecutor;
46 import java.util.concurrent.TimeUnit;
47 import java.util.List;
48 import java.util.ArrayList;
49 
50 /**
51 * This class test the below points
52 * - Copy large number of files
53 */
54 @LargeTest
55 public class FileCopyUiTest extends ActivityTest<FilesActivity> {
56     private static final String PACKAGE_NAME = "com.android.documentsui.tests";
57 
58     private static final String ACCESS_APP_NAME = "DocumentsUI Tests";
59 
60     private static final String ALLOW = "ALLOW";
61 
62     private static final String TURN_OFF = "TURN OFF";
63 
64     private static final String COPY = "Copy to…";
65 
66     private static final String MOVE = "Move to…";
67 
68     private static final String SELECT_ALL = "Select all";
69 
70     private static final int DUMMY_FILE_COUNT = 1000;
71 
72     private final List<String> mCopyFileList = new ArrayList<String>();
73 
74     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
75         @Override
76         public void onReceive(Context context, Intent intent) {
77             String action = intent.getAction();
78             if (TestNotificationService.ACTION_OPERATION_RESULT.equals(action)) {
79                 mOperationExecuted = intent.getBooleanExtra(
80                         TestNotificationService.EXTRA_RESULT, false);
81                 if (!mOperationExecuted) {
82                     mErrorReason = intent.getStringExtra(
83                             TestNotificationService.EXTRA_ERROR_REASON);
84                 }
85                 mCountDownLatch.countDown();
86             }
87         }
88     };
89 
90     private CountDownLatch mCountDownLatch;
91 
92     private boolean mOperationExecuted;
93 
94     private String mErrorReason;
95 
FileCopyUiTest()96     public FileCopyUiTest() {
97         super(FilesActivity.class);
98     }
99 
100     @Override
setUp()101     public void setUp() throws Exception {
102         super.setUp();
103 
104         // Set a flag to prevent many refreshes.
105         Bundle bundle = new Bundle();
106         bundle.putBoolean(StubProvider.EXTRA_ENABLE_ROOT_NOTIFICATION, false);
107         mDocsHelper.configure(null, bundle);
108 
109         initTestFiles();
110 
111         IntentFilter filter = new IntentFilter();
112         filter.addAction(TestNotificationService.ACTION_OPERATION_RESULT);
113         context.registerReceiver(mReceiver, filter);
114         context.sendBroadcast(new Intent(
115                 TestNotificationService.ACTION_CHANGE_EXECUTION_MODE));
116 
117         mOperationExecuted = false;
118         mErrorReason = "No response from Notification";
119         mCountDownLatch = new CountDownLatch(1);
120     }
121 
122     @Override
tearDown()123     public void tearDown() throws Exception {
124         mCountDownLatch.countDown();
125         mCountDownLatch = null;
126 
127         context.unregisterReceiver(mReceiver);
128         try {
129             if (isEnableAccessNotification()) {
130                 disallowNotificationAccess();
131             }
132         } catch (Exception e) {
133             // ignore
134         }
135         super.tearDown();
136     }
137 
138     @Override
initTestFiles()139     public void initTestFiles() throws RemoteException {
140         try {
141             if (!isEnableAccessNotification()) {
142                 allowNotificationAccess();
143             }
144             createDummyFiles();
145         } catch (Exception e) {
146             fail("Initialization failed");
147         }
148     }
149 
createDummyFiles()150     private void createDummyFiles() throws Exception {
151         final ThreadPoolExecutor exec = new ThreadPoolExecutor(
152                 5, 5, 1000L, TimeUnit.MILLISECONDS,
153                         new ArrayBlockingQueue<Runnable>(100, true));
154         for (int i = 0; i < DUMMY_FILE_COUNT; i++) {
155             final String fileName = "file" + String.format("%04d", i) + ".log";
156             if (exec.getQueue().size() >= 80) {
157                 Thread.sleep(50);
158             }
159             exec.submit(new Runnable() {
160                 @Override
161                 public void run() {
162                     Uri uri = mDocsHelper.createDocument(rootDir0, "text/plain", fileName);
163                     try {
164                         mDocsHelper.writeDocument(uri, new byte[1]);
165                     } catch (Exception e) {
166                         // ignore
167                     }
168                 }
169             });
170             mCopyFileList.add(fileName);
171         }
172         exec.shutdown();
173     }
174 
allowNotificationAccess()175     private void allowNotificationAccess() throws Exception {
176         Intent intent = new Intent();
177         intent.setAction(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
178         getActivity().startActivity(intent);
179         device.waitForIdle();
180 
181         bots.main.findMenuLabelWithName(ACCESS_APP_NAME).click();
182         device.waitForIdle();
183 
184         bots.main.findMenuLabelWithName(ALLOW).click();
185         bots.keyboard.pressKey(KeyEvent.KEYCODE_BACK);
186     }
187 
disallowNotificationAccess()188     private void disallowNotificationAccess() throws Exception {
189         Intent intent = new Intent();
190         intent.setAction(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
191         getActivity().startActivity(intent);
192         device.waitForIdle();
193 
194         bots.main.findMenuLabelWithName(ACCESS_APP_NAME).click();
195         device.waitForIdle();
196 
197         bots.main.findMenuLabelWithName(TURN_OFF).click();
198         bots.keyboard.pressKey(KeyEvent.KEYCODE_BACK);
199     }
200 
isEnableAccessNotification()201     private boolean isEnableAccessNotification() {
202         ContentResolver resolver = getActivity().getContentResolver();
203         String listeners = Settings.Secure.getString(
204                 resolver,"enabled_notification_listeners");
205         if (!TextUtils.isEmpty(listeners)) {
206             String[] list = listeners.split(":");
207             for(String item : list) {
208                 if(item.startsWith(PACKAGE_NAME)) {
209                     return true;
210                 }
211             }
212         }
213         return false;
214     }
215 
testCopyAllDocument()216     public void testCopyAllDocument() throws Exception {
217         bots.roots.openRoot(ROOT_0_ID);
218         bots.main.clickToolbarOverflowItem(SELECT_ALL);
219         device.waitForIdle();
220 
221         bots.main.clickToolbarOverflowItem(COPY);
222         device.waitForIdle();
223 
224         bots.roots.openRoot(ROOT_1_ID);
225         bots.main.clickDialogOkButton();
226         device.waitForIdle();
227 
228         try {
229             mCountDownLatch.await(60, TimeUnit.SECONDS);
230         } catch (Exception e) {
231             fail("Cannot wait because of error." + e.toString());
232         }
233 
234         assertTrue(mErrorReason, mOperationExecuted);
235 
236         bots.roots.openRoot(ROOT_1_ID);
237         device.waitForIdle();
238 
239         List<DocumentInfo> root1 = mDocsHelper.listChildren(rootDir1.documentId, 1000);
240         List<String> copiedFileList = new ArrayList<String>();
241         for (DocumentInfo info : root1) {
242             copiedFileList.add(info.displayName);
243         }
244 
245         for (String name : mCopyFileList) {
246             assertTrue("Not found " + name, copiedFileList.contains(name));
247         }
248     }
249 }
250