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