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.EXTRA_SIZE; 20 import static com.android.documentsui.StubProvider.ROOT_0_ID; 21 import static com.android.documentsui.StubProvider.ROOT_1_ID; 22 23 import static android.provider.DocumentsContract.buildDocumentUri; 24 import android.provider.DocumentsContract; 25 import com.android.documentsui.archives.ResourcesProvider; 26 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.ContentResolver; 30 import android.content.Intent; 31 import android.content.IntentFilter; 32 import android.content.BroadcastReceiver; 33 import android.net.Uri; 34 import android.os.Bundle; 35 import android.os.RemoteException; 36 import android.provider.Settings; 37 import android.support.test.filters.LargeTest; 38 import android.support.test.filters.Suppress; 39 import android.text.TextUtils; 40 import android.view.KeyEvent; 41 import android.util.Log; 42 43 import com.android.documentsui.files.FilesActivity; 44 import com.android.documentsui.services.TestNotificationService; 45 import com.android.documentsui.R; 46 47 import java.util.concurrent.CountDownLatch; 48 import java.util.concurrent.TimeUnit; 49 50 /** 51 * This class tests the below points. 52 * - Cancel copying or moving file before starting it. 53 * - Cancel during copying or moving file. 54 */ 55 @LargeTest 56 public class CancelFromNotificationUiTest extends ActivityTest<FilesActivity> { 57 private static final String PACKAGE_NAME = "com.android.documentsui.tests"; 58 59 private static final String TARGET_FILE = "dummy.data"; 60 61 private static final int BUFFER_SIZE = 10 * 1024 * 1024; 62 63 private static final String ACCESS_APP_NAME = "DocumentsUI Tests"; 64 65 private static final String ALLOW = "ALLOW"; 66 67 private static final String TURN_OFF = "TURN OFF"; 68 69 private static final String COPY = "Copy to…"; 70 71 private static final String MOVE = "Move to…"; 72 73 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 74 @Override 75 public void onReceive(Context context, Intent intent) { 76 String action = intent.getAction(); 77 if (TestNotificationService.ACTION_OPERATION_RESULT.equals(action)) { 78 mOperationExecuted = intent.getBooleanExtra( 79 TestNotificationService.EXTRA_RESULT, false); 80 if (!mOperationExecuted) { 81 mErrorReason = intent.getStringExtra( 82 TestNotificationService.EXTRA_ERROR_REASON); 83 } 84 mCountDownLatch.countDown(); 85 } 86 } 87 }; 88 89 private CountDownLatch mCountDownLatch; 90 91 private boolean mOperationExecuted; 92 93 private String mErrorReason; 94 CancelFromNotificationUiTest()95 public CancelFromNotificationUiTest() { 96 super(FilesActivity.class); 97 } 98 99 @Override setUp()100 public void setUp() throws Exception { 101 super.setUp(); 102 103 // super.setUp() method will change the storage size to 100MB. 104 // So, reset the storage size again to 500MB. 105 Bundle bundle = new Bundle(); 106 bundle.putLong(EXTRA_SIZE, 500L); 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_CANCEL_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 createDummyFile(); 145 } catch (Exception e) { 146 fail("Initialization failed. " + e.toString()); 147 } 148 } 149 createDummyFile()150 private void createDummyFile() throws Exception { 151 Uri uri = mDocsHelper.createDocument(rootDir0, "*/*", TARGET_FILE); 152 byte[] dummyByte = new byte[BUFFER_SIZE]; 153 mDocsHelper.writeDocument(uri, dummyByte); 154 for (int i = 0; i < 49; i++) { 155 dummyByte = null; 156 dummyByte = new byte[BUFFER_SIZE]; 157 mDocsHelper.writeAppendDocument(uri, dummyByte); 158 } 159 } 160 allowNotificationAccess()161 private void allowNotificationAccess() throws Exception { 162 Intent intent = new Intent(); 163 intent.setAction(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); 164 getActivity().startActivity(intent); 165 device.waitForIdle(); 166 167 bots.main.findMenuLabelWithName(ACCESS_APP_NAME).click(); 168 device.waitForIdle(); 169 170 bots.main.findMenuLabelWithName(ALLOW).click(); 171 bots.keyboard.pressKey(KeyEvent.KEYCODE_BACK); 172 } 173 disallowNotificationAccess()174 private void disallowNotificationAccess() throws Exception { 175 Intent intent = new Intent(); 176 intent.setAction(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); 177 getActivity().startActivity(intent); 178 device.waitForIdle(); 179 180 bots.main.findMenuLabelWithName(ACCESS_APP_NAME).click(); 181 device.waitForIdle(); 182 183 bots.main.findMenuLabelWithName(TURN_OFF).click(); 184 bots.keyboard.pressKey(KeyEvent.KEYCODE_BACK); 185 } 186 isEnableAccessNotification()187 private boolean isEnableAccessNotification() { 188 ContentResolver resolver = getActivity().getContentResolver(); 189 String listeners = Settings.Secure.getString(resolver,"enabled_notification_listeners"); 190 191 if (!TextUtils.isEmpty(listeners)) { 192 String[] list = listeners.split(":"); 193 for(String item : list) { 194 if(item.startsWith(PACKAGE_NAME)) { 195 return true; 196 } 197 } 198 } 199 return false; 200 } 201 testCopyDocument_Cancel()202 public void testCopyDocument_Cancel() throws Exception { 203 bots.roots.openRoot(ROOT_0_ID); 204 205 bots.directory.findDocument(TARGET_FILE); 206 device.waitForIdle(); 207 208 bots.directory.selectDocument(TARGET_FILE); 209 device.waitForIdle(); 210 211 bots.main.clickToolbarOverflowItem(COPY); 212 device.waitForIdle(); 213 214 bots.main.clickDialogCancelButton(); 215 device.waitForIdle(); 216 217 bots.directory.waitForDocument(TARGET_FILE); 218 } 219 testCopyDocument_CancelFromNotification()220 public void testCopyDocument_CancelFromNotification() throws Exception { 221 bots.roots.openRoot(ROOT_0_ID); 222 bots.directory.findDocument(TARGET_FILE); 223 device.waitForIdle(); 224 225 bots.directory.selectDocument(TARGET_FILE); 226 device.waitForIdle(); 227 228 bots.main.clickToolbarOverflowItem(COPY); 229 device.waitForIdle(); 230 231 bots.roots.openRoot(ROOT_1_ID); 232 bots.main.clickDialogOkButton(); 233 device.waitForIdle(); 234 235 try { 236 mCountDownLatch.await(60, TimeUnit.SECONDS); 237 } catch (Exception e) { 238 fail("Cannot wait because of error." + e.toString()); 239 } 240 241 assertTrue(mErrorReason, mOperationExecuted); 242 243 bots.roots.openRoot(ROOT_1_ID); 244 device.waitForIdle(); 245 assertFalse(bots.directory.hasDocuments(TARGET_FILE)); 246 247 bots.roots.openRoot(ROOT_0_ID); 248 device.waitForIdle(); 249 assertTrue(bots.directory.hasDocuments(TARGET_FILE)); 250 } 251 testMoveDocument_Cancel()252 public void testMoveDocument_Cancel() throws Exception { 253 bots.roots.openRoot(ROOT_0_ID); 254 255 bots.directory.findDocument(TARGET_FILE); 256 device.waitForIdle(); 257 258 bots.directory.selectDocument(TARGET_FILE); 259 device.waitForIdle(); 260 261 bots.main.clickToolbarOverflowItem(MOVE); 262 device.waitForIdle(); 263 264 bots.main.clickDialogCancelButton(); 265 device.waitForIdle(); 266 267 bots.directory.waitForDocument(TARGET_FILE); 268 } 269 testMoveDocument_CancelFromNotification()270 public void testMoveDocument_CancelFromNotification() throws Exception { 271 bots.roots.openRoot(ROOT_0_ID); 272 bots.directory.findDocument(TARGET_FILE); 273 device.waitForIdle(); 274 275 bots.directory.selectDocument(TARGET_FILE); 276 device.waitForIdle(); 277 278 bots.main.clickToolbarOverflowItem(MOVE); 279 device.waitForIdle(); 280 281 bots.roots.openRoot(ROOT_1_ID); 282 bots.main.clickDialogOkButton(); 283 device.waitForIdle(); 284 285 try { 286 mCountDownLatch.await(60, TimeUnit.SECONDS); 287 } catch (Exception e) { 288 fail("Cannot wait because of error." + e.toString()); 289 } 290 291 assertTrue(mErrorReason, mOperationExecuted); 292 293 bots.roots.openRoot(ROOT_1_ID); 294 device.waitForIdle(); 295 assertFalse(bots.directory.hasDocuments(TARGET_FILE)); 296 297 bots.roots.openRoot(ROOT_0_ID); 298 device.waitForIdle(); 299 assertTrue(bots.directory.hasDocuments(TARGET_FILE)); 300 } 301 } 302