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 android.content.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.os.RemoteException; 30 import android.util.Log; 31 32 import androidx.test.filters.LargeTest; 33 34 import com.android.documentsui.files.FilesActivity; 35 import com.android.documentsui.filters.HugeLongTest; 36 import com.android.documentsui.services.TestNotificationService; 37 38 import java.util.concurrent.CountDownLatch; 39 import java.util.concurrent.TimeUnit; 40 41 /** 42 * This class tests the below points. 43 * - Cancel copying or moving file before starting it. 44 * - Cancel during copying or moving file. 45 */ 46 @LargeTest 47 public class CancelFromNotificationUiTest extends ActivityTest<FilesActivity> { 48 private static final String TAG = "CancelFromNotificationUiTest"; 49 50 private static final String TARGET_FILE = "dummy.data"; 51 52 private static final int BUFFER_SIZE = 10 * 1024 * 1024; 53 54 private static final int WAIT_TIME_SECONDS = 120; 55 56 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 57 @Override 58 public void onReceive(Context context, Intent intent) { 59 String action = intent.getAction(); 60 if (TestNotificationService.ACTION_OPERATION_RESULT.equals(action)) { 61 mOperationExecuted = intent.getBooleanExtra( 62 TestNotificationService.EXTRA_RESULT, false); 63 if (!mOperationExecuted) { 64 mErrorReason = intent.getStringExtra( 65 TestNotificationService.EXTRA_ERROR_REASON); 66 } 67 mCountDownLatch.countDown(); 68 } 69 } 70 }; 71 72 private CountDownLatch mCountDownLatch; 73 74 private boolean mOperationExecuted; 75 76 private String mErrorReason; 77 CancelFromNotificationUiTest()78 public CancelFromNotificationUiTest() { 79 super(FilesActivity.class); 80 } 81 82 @Override setUp()83 public void setUp() throws Exception { 84 super.setUp(); 85 86 // super.setUp() method will change the storage size to 100MB. 87 // So, reset the storage size again to 500MB. 88 Bundle bundle = new Bundle(); 89 bundle.putLong(EXTRA_SIZE, 500L); 90 // Set a flag to prevent many refreshes. 91 bundle.putBoolean(StubProvider.EXTRA_ENABLE_ROOT_NOTIFICATION, false); 92 mDocsHelper.configure(null, bundle); 93 94 try { 95 bots.notifications.setNotificationAccess(getActivity(), true); 96 } catch (Exception e) { 97 Log.d(TAG, "Cannot set notification access. ", e); 98 } 99 100 initTestFiles(); 101 102 IntentFilter filter = new IntentFilter(); 103 filter.addAction(TestNotificationService.ACTION_OPERATION_RESULT); 104 context.registerReceiver(mReceiver, filter); 105 context.sendBroadcast(new Intent( 106 TestNotificationService.ACTION_CHANGE_CANCEL_MODE)); 107 108 mOperationExecuted = false; 109 mErrorReason = "No response from Notification"; 110 mCountDownLatch = new CountDownLatch(1); 111 } 112 113 @Override tearDown()114 public void tearDown() throws Exception { 115 mCountDownLatch.countDown(); 116 mCountDownLatch = null; 117 118 context.unregisterReceiver(mReceiver); 119 try { 120 bots.notifications.setNotificationAccess(getActivity(), false); 121 } catch (Exception e) { 122 Log.d(TAG, "Cannot set notification access. ", e); 123 } 124 super.tearDown(); 125 } 126 127 @Override initTestFiles()128 public void initTestFiles() throws RemoteException { 129 try { 130 createDummyFile(); 131 } catch (Exception e) { 132 fail("Initialization failed. " + e.toString()); 133 } 134 } 135 createDummyFile()136 private void createDummyFile() throws Exception { 137 Uri uri = mDocsHelper.createDocument(rootDir0, "*/*", TARGET_FILE); 138 byte[] dummyByte = new byte[BUFFER_SIZE]; 139 mDocsHelper.writeDocument(uri, dummyByte); 140 for (int i = 0; i < 49; i++) { 141 dummyByte = null; 142 dummyByte = new byte[BUFFER_SIZE]; 143 mDocsHelper.writeAppendDocument(uri, dummyByte, dummyByte.length); 144 } 145 } 146 147 @HugeLongTest testCopyDocument_Cancel()148 public void testCopyDocument_Cancel() throws Exception { 149 bots.roots.openRoot(ROOT_0_ID); 150 151 bots.directory.findDocument(TARGET_FILE); 152 device.waitForIdle(); 153 154 bots.directory.selectDocument(TARGET_FILE, 1); 155 device.waitForIdle(); 156 157 bots.main.clickToolbarOverflowItem(context.getResources().getString(R.string.menu_copy)); 158 device.waitForIdle(); 159 160 bots.main.clickDialogCancelButton(); 161 device.waitForIdle(); 162 163 bots.directory.waitForDocument(TARGET_FILE); 164 } 165 166 @HugeLongTest testCopyDocument_CancelFromNotification()167 public void testCopyDocument_CancelFromNotification() throws Exception { 168 bots.roots.openRoot(ROOT_0_ID); 169 bots.directory.findDocument(TARGET_FILE); 170 device.waitForIdle(); 171 172 bots.directory.selectDocument(TARGET_FILE, 1); 173 device.waitForIdle(); 174 175 bots.main.clickToolbarOverflowItem(context.getResources().getString(R.string.menu_copy)); 176 device.waitForIdle(); 177 178 bots.roots.openRoot(ROOT_1_ID); 179 bots.main.clickDialogOkButton(); 180 device.waitForIdle(); 181 182 try { 183 mCountDownLatch.await(WAIT_TIME_SECONDS, TimeUnit.SECONDS); 184 } catch (Exception e) { 185 fail("Cannot wait because of error." + e.toString()); 186 } 187 188 assertTrue(mErrorReason, mOperationExecuted); 189 190 bots.roots.openRoot(ROOT_1_ID); 191 device.waitForIdle(); 192 assertFalse(bots.directory.hasDocuments(TARGET_FILE)); 193 194 bots.roots.openRoot(ROOT_0_ID); 195 device.waitForIdle(); 196 assertTrue(bots.directory.hasDocuments(TARGET_FILE)); 197 } 198 199 @HugeLongTest testMoveDocument_Cancel()200 public void testMoveDocument_Cancel() throws Exception { 201 bots.roots.openRoot(ROOT_0_ID); 202 203 bots.directory.findDocument(TARGET_FILE); 204 device.waitForIdle(); 205 206 bots.directory.selectDocument(TARGET_FILE, 1); 207 device.waitForIdle(); 208 209 bots.main.clickToolbarOverflowItem(context.getResources().getString(R.string.menu_move)); 210 device.waitForIdle(); 211 212 bots.main.clickDialogCancelButton(); 213 device.waitForIdle(); 214 215 bots.directory.waitForDocument(TARGET_FILE); 216 } 217 218 @HugeLongTest 219 // (TODO: b/156756197) : Deflake tests 220 // Notice because this class inherits JUnit3 TestCase, the right way to suppress a test 221 // is by removing "test" from prefix, instead of adding @Ignore. ignored_testMoveDocument_CancelFromNotification()222 public void ignored_testMoveDocument_CancelFromNotification() throws Exception { 223 bots.roots.openRoot(ROOT_0_ID); 224 bots.directory.findDocument(TARGET_FILE); 225 device.waitForIdle(); 226 227 bots.directory.selectDocument(TARGET_FILE, 1); 228 device.waitForIdle(); 229 230 bots.main.clickToolbarOverflowItem(context.getResources().getString(R.string.menu_move)); 231 device.waitForIdle(); 232 233 bots.roots.openRoot(ROOT_1_ID); 234 bots.main.clickDialogOkButton(); 235 device.waitForIdle(); 236 237 try { 238 mCountDownLatch.await(WAIT_TIME_SECONDS, TimeUnit.SECONDS); 239 } catch (Exception e) { 240 fail("Cannot wait because of error." + e.toString()); 241 } 242 243 assertTrue(mErrorReason, mOperationExecuted); 244 245 bots.roots.openRoot(ROOT_1_ID); 246 device.waitForIdle(); 247 assertFalse(bots.directory.hasDocuments(TARGET_FILE)); 248 249 bots.roots.openRoot(ROOT_0_ID); 250 device.waitForIdle(); 251 assertTrue(bots.directory.hasDocuments(TARGET_FILE)); 252 } 253 } 254