1 /* 2 * Copyright (C) 2016 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.files; 18 19 import static com.android.documentsui.testing.IntentAsserts.assertHasAction; 20 import static com.android.documentsui.testing.IntentAsserts.assertHasData; 21 import static com.android.documentsui.testing.IntentAsserts.assertHasExtra; 22 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraIntent; 23 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraList; 24 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraUri; 25 import static com.android.documentsui.testing.IntentAsserts.assertTargetsComponent; 26 27 import static org.junit.Assert.assertEquals; 28 import static org.junit.Assert.assertFalse; 29 import static org.junit.Assert.assertNotNull; 30 import static org.junit.Assert.assertNull; 31 import static org.junit.Assert.assertSame; 32 import static org.junit.Assert.assertTrue; 33 import static org.junit.Assume.assumeTrue; 34 35 import android.app.Activity; 36 import android.app.DownloadManager; 37 import android.app.PendingIntent; 38 import android.content.ClipData; 39 import android.content.Intent; 40 import android.net.Uri; 41 import android.os.Parcelable; 42 import android.provider.DocumentsContract; 43 import android.provider.DocumentsContract.Path; 44 import android.util.Pair; 45 import android.view.DragEvent; 46 47 import androidx.core.util.Preconditions; 48 import androidx.test.InstrumentationRegistry; 49 import androidx.test.filters.MediumTest; 50 51 import com.android.documentsui.AbstractActionHandler; 52 import com.android.documentsui.ModelId; 53 import com.android.documentsui.R; 54 import com.android.documentsui.TestActionModeAddons; 55 import com.android.documentsui.TestConfigStore; 56 import com.android.documentsui.archives.ArchivesProvider; 57 import com.android.documentsui.base.DebugFlags; 58 import com.android.documentsui.base.DocumentInfo; 59 import com.android.documentsui.base.DocumentStack; 60 import com.android.documentsui.base.RootInfo; 61 import com.android.documentsui.base.Shared; 62 import com.android.documentsui.inspector.InspectorActivity; 63 import com.android.documentsui.testing.ClipDatas; 64 import com.android.documentsui.testing.DocumentStackAsserts; 65 import com.android.documentsui.testing.Roots; 66 import com.android.documentsui.testing.TestActivityConfig; 67 import com.android.documentsui.testing.TestDocumentClipper; 68 import com.android.documentsui.testing.TestDragAndDropManager; 69 import com.android.documentsui.testing.TestEnv; 70 import com.android.documentsui.testing.TestFeatures; 71 import com.android.documentsui.testing.TestProvidersAccess; 72 import com.android.documentsui.testing.UserManagers; 73 import com.android.documentsui.ui.TestDialogController; 74 import com.android.documentsui.util.VersionUtils; 75 import com.android.modules.utils.build.SdkLevel; 76 77 import com.google.common.collect.Lists; 78 79 import org.junit.Before; 80 import org.junit.Ignore; 81 import org.junit.Test; 82 import org.junit.runner.RunWith; 83 import org.junit.runners.Parameterized; 84 import org.junit.runners.Parameterized.Parameter; 85 import org.junit.runners.Parameterized.Parameters; 86 87 import java.util.ArrayList; 88 import java.util.Arrays; 89 import java.util.List; 90 91 @RunWith(Parameterized.class) 92 @MediumTest 93 public class ActionHandlerTest { 94 95 private TestEnv mEnv; 96 private TestActivity mActivity; 97 private TestActionModeAddons mActionModeAddons; 98 private TestDialogController mDialogs; 99 private ActionHandler<TestActivity> mHandler; 100 private TestDocumentClipper mClipper; 101 private TestDragAndDropManager mDragAndDropManager; 102 private TestFeatures mFeatures; 103 private TestConfigStore mTestConfigStore; 104 private boolean refreshAnswer = false; 105 106 @Parameter(0) 107 public boolean isPrivateSpaceEnabled; 108 109 /** 110 * Parametrize values for {@code isPrivateSpaceEnabled} to run all the tests twice once with 111 * private space flag enabled and once with it disabled. 112 */ 113 @Parameters(name = "privateSpaceEnabled={0}") data()114 public static Iterable<?> data() { 115 return Lists.newArrayList(true, false); 116 } 117 118 @Before setUp()119 public void setUp() { 120 mFeatures = new TestFeatures(); 121 mEnv = TestEnv.create(mFeatures); 122 mActivity = TestActivity.create(mEnv); 123 mActivity.userManager = UserManagers.create(); 124 mActionModeAddons = new TestActionModeAddons(); 125 mDialogs = new TestDialogController(); 126 mClipper = new TestDocumentClipper(); 127 mDragAndDropManager = new TestDragAndDropManager(); 128 mTestConfigStore = new TestConfigStore(); 129 mEnv.state.configStore = mTestConfigStore; 130 131 isPrivateSpaceEnabled &= SdkLevel.isAtLeastS(); 132 if (isPrivateSpaceEnabled) { 133 mTestConfigStore.enablePrivateSpaceInPhotoPicker(); 134 mEnv.state.canForwardToProfileIdMap.put(TestProvidersAccess.USER_ID, true); 135 } 136 137 mEnv.providers.configurePm(mActivity.packageMgr); 138 ((TestActivityConfig) mEnv.injector.config).nextDocumentEnabled = true; 139 mEnv.injector.dialogs = mDialogs; 140 141 mHandler = createHandler(); 142 143 mEnv.selectDocument(TestEnv.FILE_GIF); 144 } 145 146 @Test testOpenSelectedInNewWindow()147 public void testOpenSelectedInNewWindow() { 148 mHandler.openSelectedInNewWindow(); 149 150 DocumentStack path = new DocumentStack(Roots.create("123"), mEnv.model.getDocument("1")); 151 152 Intent expected = LauncherActivity.createLaunchIntent(mActivity); 153 expected.putExtra(Shared.EXTRA_STACK, (Parcelable) path); 154 155 Intent actual = mActivity.startActivity.getLastValue(); 156 assertEquals(expected.toString(), actual.toString()); 157 } 158 159 @Test testSpringOpenDirectory()160 public void testSpringOpenDirectory() { 161 mHandler.springOpenDirectory(TestEnv.FOLDER_0); 162 assertTrue(mActionModeAddons.finishActionModeCalled); 163 assertEquals(TestEnv.FOLDER_0, mEnv.state.stack.peek()); 164 } 165 166 @Test testCutSelectedDocuments_NoGivenSelection()167 public void testCutSelectedDocuments_NoGivenSelection() { 168 mEnv.populateStack(); 169 170 mEnv.selectionMgr.clearSelection(); 171 mHandler.cutToClipboard(); 172 mDialogs.assertDocumentsClippedNotShown(); 173 } 174 175 @Test testCutSelectedDocuments_ContainsNonMovableItem()176 public void testCutSelectedDocuments_ContainsNonMovableItem() { 177 mEnv.populateStack(); 178 mEnv.selectDocument(TestEnv.FILE_READ_ONLY); 179 180 mHandler.cutToClipboard(); 181 mDialogs.assertDocumentsClippedNotShown(); 182 mDialogs.assertShowOperationUnsupported(); 183 mClipper.clipForCut.assertNotCalled(); 184 } 185 186 @Test testCopySelectedDocuments_NoGivenSelection()187 public void testCopySelectedDocuments_NoGivenSelection() { 188 mEnv.populateStack(); 189 190 mEnv.selectionMgr.clearSelection(); 191 mHandler.copyToClipboard(); 192 mDialogs.assertDocumentsClippedNotShown(); 193 } 194 195 @Test testShowDeleteDialog_NoSelection()196 public void testShowDeleteDialog_NoSelection() { 197 mEnv.populateStack(); 198 199 mEnv.selectionMgr.clearSelection(); 200 mHandler.showDeleteDialog(); 201 mActivity.startService.assertNotCalled(); 202 assertFalse(mActionModeAddons.finishActionModeCalled); 203 } 204 205 @Test testDeleteSelectedDocuments()206 public void testDeleteSelectedDocuments() { 207 mEnv.populateStack(); 208 209 mEnv.selectionMgr.clearSelection(); 210 mEnv.selectDocument(TestEnv.FILE_PNG); 211 212 List<DocumentInfo> docs = new ArrayList<>(); 213 docs.add(TestEnv.FILE_PNG); 214 mHandler.deleteSelectedDocuments(docs, mEnv.state.stack.peek()); 215 216 mActivity.startService.assertCalled(); 217 assertTrue(mActionModeAddons.finishActionModeCalled); 218 } 219 220 @Test testShareSelectedDocuments_ShowsChooser()221 public void testShareSelectedDocuments_ShowsChooser() { 222 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 223 mHandler.shareSelectedDocuments(); 224 225 mActivity.assertActivityStarted(Intent.ACTION_CHOOSER); 226 } 227 228 @Test testShareSelectedDocuments_Single()229 public void testShareSelectedDocuments_Single() { 230 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 231 mHandler.shareSelectedDocuments(); 232 233 Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue()); 234 assertHasAction(intent, Intent.ACTION_SEND); 235 assertFalse(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE)); 236 assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE)); 237 assertHasExtraUri(intent, Intent.EXTRA_STREAM); 238 } 239 240 @Test testShareSelectedDocuments_ArchivedFile()241 public void testShareSelectedDocuments_ArchivedFile() { 242 mEnv = TestEnv.create(ArchivesProvider.AUTHORITY); 243 mHandler = createHandler(); 244 245 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 246 mEnv.selectionMgr.clearSelection(); 247 mEnv.selectDocument(TestEnv.FILE_PDF); 248 mHandler.shareSelectedDocuments(); 249 250 Intent intent = mActivity.startActivity.getLastValue(); 251 assertNull(intent); 252 } 253 254 @Test testShareSelectedDocuments_Multiple()255 public void testShareSelectedDocuments_Multiple() { 256 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 257 mEnv.selectDocument(TestEnv.FILE_PDF); 258 mHandler.shareSelectedDocuments(); 259 260 Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue()); 261 assertHasAction(intent, Intent.ACTION_SEND_MULTIPLE); 262 assertFalse(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE)); 263 assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE)); 264 assertHasExtraList(intent, Intent.EXTRA_STREAM, 2); 265 } 266 267 @Test testShareSelectedDocuments_overShareLimit()268 public void testShareSelectedDocuments_overShareLimit() { 269 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 270 mEnv.selectMultipleFiles(500); 271 mHandler.shareSelectedDocuments(); 272 273 Intent intent = mActivity.startActivity.getLastValue(); 274 assertNull(intent); 275 mDialogs.assertShareOverLimitShown(); 276 } 277 278 @Test testShareSelectedDocuments_VirtualFiles()279 public void testShareSelectedDocuments_VirtualFiles() { 280 if (!mEnv.features.isVirtualFilesSharingEnabled()) { 281 return; 282 } 283 284 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 285 mEnv.selectionMgr.clearSelection(); 286 mEnv.selectDocument(TestEnv.FILE_VIRTUAL); 287 mHandler.shareSelectedDocuments(); 288 289 Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue()); 290 assertHasAction(intent, Intent.ACTION_SEND); 291 assertTrue(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE)); 292 assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE)); 293 assertHasExtraUri(intent, Intent.EXTRA_STREAM); 294 } 295 296 @Test testShareSelectedDocuments_RegularAndVirtualFiles()297 public void testShareSelectedDocuments_RegularAndVirtualFiles() { 298 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 299 mEnv.selectDocument(TestEnv.FILE_PNG); 300 mEnv.selectDocument(TestEnv.FILE_VIRTUAL); 301 mHandler.shareSelectedDocuments(); 302 303 Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue()); 304 assertHasAction(intent, Intent.ACTION_SEND_MULTIPLE); 305 306 assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE)); 307 if (mEnv.features.isVirtualFilesSharingEnabled()) { 308 assertTrue(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE)); 309 assertHasExtraList(intent, Intent.EXTRA_STREAM, 3); 310 }else { 311 assertHasExtraList(intent, Intent.EXTRA_STREAM, 2); 312 } 313 } 314 315 @Test testShareSelectedDocuments_OmitsPartialFiles()316 public void testShareSelectedDocuments_OmitsPartialFiles() { 317 mActivity.resources.strings.put(R.string.share_via, "Sharezilla!"); 318 mEnv.selectDocument(TestEnv.FILE_PARTIAL); 319 mEnv.selectDocument(TestEnv.FILE_PNG); 320 mHandler.shareSelectedDocuments(); 321 322 Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue()); 323 assertHasAction(intent, Intent.ACTION_SEND_MULTIPLE); 324 assertFalse(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE)); 325 assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE)); 326 assertHasExtraList(intent, Intent.EXTRA_STREAM, 2); 327 } 328 329 @Test testDocumentPicked_DefaultsToView()330 public void testDocumentPicked_DefaultsToView() throws Exception { 331 mActivity.currentRoot = TestProvidersAccess.HOME; 332 333 mHandler.openDocument(TestEnv.FILE_GIF, ActionHandler.VIEW_TYPE_PREVIEW, 334 ActionHandler.VIEW_TYPE_REGULAR); 335 mActivity.assertActivityStarted(Intent.ACTION_VIEW); 336 } 337 338 @Test testDocumentPicked_InArchive_QuickViewable()339 public void testDocumentPicked_InArchive_QuickViewable() throws Exception { 340 mActivity.resources.setQuickViewerPackage("corptropolis.viewer"); 341 mActivity.currentRoot = TestProvidersAccess.HOME; 342 343 mHandler.openDocument(TestEnv.FILE_IN_ARCHIVE, ActionHandler.VIEW_TYPE_PREVIEW, 344 ActionHandler.VIEW_TYPE_REGULAR); 345 mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW); 346 } 347 348 @Test testDocumentPicked_InArchive_Unopenable()349 public void testDocumentPicked_InArchive_Unopenable() throws Exception { 350 mActivity.currentRoot = TestProvidersAccess.HOME; 351 352 mHandler.openDocument(TestEnv.FILE_IN_ARCHIVE, ActionHandler.VIEW_TYPE_PREVIEW, 353 ActionHandler.VIEW_TYPE_REGULAR); 354 mDialogs.assertViewInArchivesShownUnsupported(); 355 } 356 357 @Test testDocumentPicked_PreviewsWhenResourceSet()358 public void testDocumentPicked_PreviewsWhenResourceSet() throws Exception { 359 mActivity.resources.setQuickViewerPackage("corptropolis.viewer"); 360 mActivity.currentRoot = TestProvidersAccess.HOME; 361 362 mHandler.openDocument(TestEnv.FILE_GIF, ActionHandler.VIEW_TYPE_PREVIEW, 363 ActionHandler.VIEW_TYPE_REGULAR); 364 mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW); 365 } 366 367 @Test testDocumentPicked_Downloads_ManagesApks()368 public void testDocumentPicked_Downloads_ManagesApks() throws Exception { 369 mActivity.currentRoot = TestProvidersAccess.DOWNLOADS; 370 TestEnv.FILE_APK.authority = TestProvidersAccess.DOWNLOADS.authority; 371 372 mHandler.openDocument(TestEnv.FILE_APK, ActionHandler.VIEW_TYPE_PREVIEW, 373 ActionHandler.VIEW_TYPE_REGULAR); 374 mActivity.assertActivityStarted(DocumentsContract.ACTION_MANAGE_DOCUMENT); 375 } 376 377 @Test testDocumentPicked_Downloads_ManagesPartialFiles()378 public void testDocumentPicked_Downloads_ManagesPartialFiles() throws Exception { 379 mActivity.currentRoot = TestProvidersAccess.DOWNLOADS; 380 TestEnv.FILE_PARTIAL.authority = TestProvidersAccess.DOWNLOADS.authority; 381 382 mHandler.openDocument(TestEnv.FILE_PARTIAL, ActionHandler.VIEW_TYPE_PREVIEW, 383 ActionHandler.VIEW_TYPE_REGULAR); 384 mActivity.assertActivityStarted(DocumentsContract.ACTION_MANAGE_DOCUMENT); 385 } 386 387 @Test testDocumentPicked_Recent_ManagesApks()388 public void testDocumentPicked_Recent_ManagesApks() throws Exception { 389 mActivity.currentRoot = TestProvidersAccess.RECENTS; 390 TestEnv.FILE_APK.authority = TestProvidersAccess.DOWNLOADS.authority; 391 392 mHandler.openDocument(TestEnv.FILE_APK, ActionHandler.VIEW_TYPE_PREVIEW, 393 ActionHandler.VIEW_TYPE_REGULAR); 394 mActivity.assertActivityStarted(DocumentsContract.ACTION_MANAGE_DOCUMENT); 395 } 396 397 @Test testDocumentPicked_Home_SendsActionViewForApks()398 public void testDocumentPicked_Home_SendsActionViewForApks() throws Exception { 399 mActivity.currentRoot = TestProvidersAccess.HOME; 400 401 mHandler.openDocument(TestEnv.FILE_APK, ActionHandler.VIEW_TYPE_PREVIEW, 402 ActionHandler.VIEW_TYPE_REGULAR); 403 mActivity.assertActivityStarted(Intent.ACTION_VIEW); 404 } 405 406 @Test testDocumentPicked_OpensArchives()407 public void testDocumentPicked_OpensArchives() throws Exception { 408 mActivity.currentRoot = TestProvidersAccess.HOME; 409 mEnv.docs.nextDocument = TestEnv.FILE_ARCHIVE; 410 411 final boolean result = mHandler.openDocument(TestEnv.FILE_ARCHIVE, 412 ActionHandler.VIEW_TYPE_PREVIEW, ActionHandler.VIEW_TYPE_REGULAR); 413 assertEquals(TestEnv.FILE_ARCHIVE, mEnv.state.stack.peek()); 414 assertEquals(false, result); 415 } 416 417 @Test testDocumentPicked_OpensDirectories()418 public void testDocumentPicked_OpensDirectories() throws Exception { 419 mActivity.currentRoot = TestProvidersAccess.HOME; 420 421 final boolean result = mHandler.openDocument(TestEnv.FOLDER_1, 422 ActionHandler.VIEW_TYPE_PREVIEW, ActionHandler.VIEW_TYPE_REGULAR); 423 assertEquals(TestEnv.FOLDER_1, mEnv.state.stack.peek()); 424 assertEquals(false, result); 425 } 426 427 @Test testShowChooser()428 public void testShowChooser() throws Exception { 429 mActivity.currentRoot = TestProvidersAccess.DOWNLOADS; 430 431 mHandler.showChooserForDoc(TestEnv.FILE_PDF); 432 mActivity.assertActivityStarted(Intent.ACTION_CHOOSER); 433 } 434 435 @Test testInitLocation_LaunchToStackLocation()436 public void testInitLocation_LaunchToStackLocation() { 437 DocumentStack path = new DocumentStack(Roots.create("123"), mEnv.model.getDocument("1")); 438 439 Intent intent = LauncherActivity.createLaunchIntent(mActivity); 440 intent.putExtra(Shared.EXTRA_STACK, (Parcelable) path); 441 442 mHandler.initLocation(intent); 443 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 444 } 445 446 @Test testInitLocation_RestoresIfStackIsLoaded()447 public void testInitLocation_RestoresIfStackIsLoaded() throws Exception { 448 mEnv.state.stack.changeRoot(TestProvidersAccess.DOWNLOADS); 449 mEnv.state.stack.push(TestEnv.FOLDER_0); 450 451 mHandler.initLocation(mActivity.getIntent()); 452 mActivity.restoreRootAndDirectory.assertCalled(); 453 } 454 455 @Test testInitLocation_LoadsRootDocIfStackOnlyHasRoot()456 public void testInitLocation_LoadsRootDocIfStackOnlyHasRoot() throws Exception { 457 mEnv.state.stack.changeRoot(TestProvidersAccess.HAMMY); 458 459 mHandler.initLocation(mActivity.getIntent()); 460 assertRootPicked(TestProvidersAccess.HAMMY.getUri()); 461 } 462 463 @Test testInitLocation_forceDefaultsToRoot()464 public void testInitLocation_forceDefaultsToRoot() throws Exception { 465 mActivity.resources.strings.put(R.string.default_root_uri, 466 TestProvidersAccess.DOWNLOADS.getUri().toString()); 467 468 mHandler.initLocation(mActivity.getIntent()); 469 assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri()); 470 } 471 472 @Test testInitLocation_BrowseRootWithoutRootId()473 public void testInitLocation_BrowseRootWithoutRootId() throws Exception { 474 Intent intent = mActivity.getIntent(); 475 intent.setAction(Intent.ACTION_VIEW); 476 intent.setData(DocumentsContract.buildRootsUri(TestProvidersAccess.HAMMY.authority)); 477 478 mHandler.initLocation(intent); 479 assertRootPicked(TestProvidersAccess.HAMMY.getUri()); 480 } 481 482 @Test testInitLocation_BrowseRootWrongAuthority_ShowDefault()483 public void testInitLocation_BrowseRootWrongAuthority_ShowDefault() throws Exception { 484 Intent intent = mActivity.getIntent(); 485 intent.setAction(Intent.ACTION_VIEW); 486 intent.setData(DocumentsContract.buildRootsUri("com.test.wrongauthority")); 487 mActivity.resources.strings.put(R.string.default_root_uri, 488 TestProvidersAccess.HOME.getUri().toString()); 489 490 mHandler.initLocation(intent); 491 assertRootPicked(TestProvidersAccess.HOME.getUri()); 492 } 493 494 @Test testInitLocation_BrowseRoot()495 public void testInitLocation_BrowseRoot() throws Exception { 496 Intent intent = mActivity.getIntent(); 497 intent.setAction(Intent.ACTION_VIEW); 498 intent.setData(TestProvidersAccess.PICKLES.getUri()); 499 500 mHandler.initLocation(intent); 501 assertRootPicked(TestProvidersAccess.PICKLES.getUri()); 502 } 503 504 @Test testInitLocation_LaunchToDocuments()505 public void testInitLocation_LaunchToDocuments() throws Exception { 506 if (!mEnv.features.isLaunchToDocumentEnabled()) { 507 return; 508 } 509 510 mEnv.docs.nextIsDocumentsUri = true; 511 mEnv.docs.nextPath = new Path( 512 TestProvidersAccess.HOME.rootId, 513 Arrays.asList( 514 TestEnv.FOLDER_0.documentId, 515 TestEnv.FOLDER_1.documentId)); 516 mEnv.docs.nextDocuments = 517 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1); 518 519 mActivity.refreshCurrentRootAndDirectory.assertNotCalled(); 520 Intent intent = mActivity.getIntent(); 521 intent.setAction(Intent.ACTION_VIEW); 522 intent.setData(TestEnv.FOLDER_1.derivedUri); 523 mHandler.initLocation(intent); 524 525 mEnv.beforeAsserts(); 526 527 DocumentStackAsserts.assertEqualsTo(mEnv.state.stack, TestProvidersAccess.HOME, 528 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1)); 529 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 530 } 531 532 @Test testInitLocation_LaunchToDownloads()533 public void testInitLocation_LaunchToDownloads() throws Exception { 534 Intent intent = mActivity.getIntent(); 535 intent.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS); 536 537 mHandler.initLocation(intent); 538 assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri()); 539 } 540 541 // Ignoring the test because it uses hidden api DragEvent#obtain() and changes to the api is 542 // causing failure on older base builds 543 // TODO: b/343206763 remove dependence on hidden api 544 @Ignore 545 @Test testDragAndDrop_OnReadOnlyRoot()546 public void testDragAndDrop_OnReadOnlyRoot() throws Exception { 547 assumeTrue(VersionUtils.isAtLeastS()); 548 RootInfo root = new RootInfo(); // root by default has no SUPPORT_CREATE flag 549 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, 0, 0, 0, null, null, null, 550 null, null, true); 551 assertFalse(mHandler.dropOn(event, root)); 552 } 553 554 // Ignoring the test because it uses hidden api DragEvent#obtain() and changes to the api is 555 // causing failure on older base builds 556 // TODO: b/343206763 remove dependence on hidden api 557 @Ignore 558 @Test testDragAndDrop_OnLibraryRoot()559 public void testDragAndDrop_OnLibraryRoot() throws Exception { 560 assumeTrue(VersionUtils.isAtLeastS()); 561 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, 0, 0, 0, null, null, null, 562 null, null, true); 563 assertFalse(mHandler.dropOn(event, TestProvidersAccess.RECENTS)); 564 } 565 566 // Ignoring the test because it uses hidden api DragEvent#obtain() and changes to the api is 567 // causing failure on older base builds 568 // TODO: b/343206763 remove dependence on hidden api 569 @Ignore 570 @Test testDragAndDrop_DropsOnWritableRoot()571 public void testDragAndDrop_DropsOnWritableRoot() throws Exception { 572 assumeTrue(VersionUtils.isAtLeastS()); 573 // DragEvent gets recycled in Android, so it is possible that by the time the callback is 574 // called, event.getLocalState() and event.getClipData() returns null. This tests to ensure 575 // our Clipper is getting the original CipData passed in. 576 Object localState = new Object(); 577 ClipData clipData = ClipDatas.createTestClipData(); 578 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, 0, 0, 0, localState, null, 579 clipData, null, null, true); 580 581 mHandler.dropOn(event, TestProvidersAccess.DOWNLOADS); 582 event.recycle(); 583 584 Pair<ClipData, RootInfo> actual = mDragAndDropManager.dropOnRootHandler.getLastValue(); 585 assertSame(clipData, actual.first); 586 assertSame(TestProvidersAccess.DOWNLOADS, actual.second); 587 } 588 589 @Test testRefresh_nullUri()590 public void testRefresh_nullUri() throws Exception { 591 refreshAnswer = true; 592 mHandler.refreshDocument(null, (boolean answer) -> { 593 refreshAnswer = answer; 594 }); 595 596 mEnv.beforeAsserts(); 597 assertFalse(refreshAnswer); 598 } 599 600 @Test testRefresh_emptyStack()601 public void testRefresh_emptyStack() throws Exception { 602 refreshAnswer = true; 603 assertTrue(mEnv.state.stack.isEmpty()); 604 mHandler.refreshDocument(new DocumentInfo(), (boolean answer) -> { 605 refreshAnswer = answer; 606 }); 607 608 mEnv.beforeAsserts(); 609 assertFalse(refreshAnswer); 610 } 611 612 @Test testRefresh()613 public void testRefresh() throws Exception { 614 refreshAnswer = false; 615 mEnv.populateStack(); 616 mHandler.refreshDocument(mEnv.model.getDocument( 617 ModelId.build(mEnv.model.mUserId, TestProvidersAccess.HOME.authority, "1")), 618 (boolean answer) -> { 619 refreshAnswer = answer; 620 }); 621 622 mEnv.beforeAsserts(); 623 if (mEnv.features.isContentRefreshEnabled()) { 624 assertTrue(refreshAnswer); 625 } else { 626 assertFalse(refreshAnswer); 627 } 628 } 629 630 @Test testAuthentication()631 public void testAuthentication() throws Exception { 632 PendingIntent intent = PendingIntent.getActivity( 633 InstrumentationRegistry.getInstrumentation().getTargetContext(), 0, new Intent(), 634 PendingIntent.FLAG_IMMUTABLE); 635 636 mHandler.startAuthentication(intent); 637 assertEquals(intent.getIntentSender(), mActivity.startIntentSender.getLastValue().first); 638 assertEquals(AbstractActionHandler.CODE_AUTHENTICATION, 639 mActivity.startIntentSender.getLastValue().second.intValue()); 640 } 641 642 @Test testOnActivityResult_onOK()643 public void testOnActivityResult_onOK() throws Exception { 644 mHandler.onActivityResult(AbstractActionHandler.CODE_AUTHENTICATION, Activity.RESULT_OK, 645 null); 646 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 647 } 648 649 @Test testOnActivityResult_onNotOK()650 public void testOnActivityResult_onNotOK() throws Exception { 651 mHandler.onActivityResult(0, Activity.RESULT_OK, null); 652 mActivity.refreshCurrentRootAndDirectory.assertNotCalled(); 653 654 mHandler.onActivityResult(AbstractActionHandler.CODE_AUTHENTICATION, 655 Activity.RESULT_CANCELED, null); 656 mActivity.refreshCurrentRootAndDirectory.assertNotCalled(); 657 } 658 659 @Test testShowInspector()660 public void testShowInspector() throws Exception { 661 mHandler.showInspector(TestEnv.FILE_GIF); 662 663 mActivity.startActivity.assertCalled(); 664 Intent intent = mActivity.startActivity.getLastValue(); 665 assertTargetsComponent(intent, InspectorActivity.class); 666 assertHasData(intent, TestEnv.FILE_GIF.derivedUri); 667 668 // should only send this under especial circumstances. See test below. 669 assertFalse(intent.getExtras().containsKey(Intent.EXTRA_TITLE)); 670 } 671 672 @Test testShowInspector_DebugDisabled()673 public void testShowInspector_DebugDisabled() throws Exception { 674 mFeatures.debugSupport = false; 675 676 mHandler.showInspector(TestEnv.FILE_GIF); 677 Intent intent = mActivity.startActivity.getLastValue(); 678 679 assertHasExtra(intent, Shared.EXTRA_SHOW_DEBUG); 680 assertFalse(intent.getExtras().getBoolean(Shared.EXTRA_SHOW_DEBUG)); 681 } 682 683 @Test testShowInspector_DebugEnabled()684 public void testShowInspector_DebugEnabled() throws Exception { 685 mFeatures.debugSupport = true; 686 DebugFlags.setDocumentDetailsEnabled(true); 687 688 mHandler.showInspector(TestEnv.FILE_GIF); 689 Intent intent = mActivity.startActivity.getLastValue(); 690 691 assertHasExtra(intent, Shared.EXTRA_SHOW_DEBUG); 692 assertTrue(intent.getExtras().getBoolean(Shared.EXTRA_SHOW_DEBUG)); 693 DebugFlags.setDocumentDetailsEnabled(false); 694 } 695 696 @Test testShowInspector_OverridesRootDocumentName()697 public void testShowInspector_OverridesRootDocumentName() throws Exception { 698 mActivity.currentRoot = TestProvidersAccess.PICKLES; 699 mEnv.populateStack(); 700 701 // Verify test setup is correct, but not an assert related to the logic of our test. 702 Preconditions.checkState(mEnv.state.stack.size() == 1); 703 Preconditions.checkNotNull(mEnv.state.stack.peek()); 704 705 DocumentInfo rootDoc = mEnv.state.stack.peek(); 706 rootDoc.displayName = "poodles"; 707 708 mHandler.showInspector(rootDoc); 709 Intent intent = mActivity.startActivity.getLastValue(); 710 assertEquals( 711 TestProvidersAccess.PICKLES.title, 712 intent.getExtras().getString(Intent.EXTRA_TITLE)); 713 } 714 715 @Test testShowInspector_OverridesRootDocumentNameX()716 public void testShowInspector_OverridesRootDocumentNameX() throws Exception { 717 mActivity.currentRoot = TestProvidersAccess.PICKLES; 718 mEnv.populateStack(); 719 mEnv.state.stack.push(TestEnv.FOLDER_2); 720 721 // Verify test setup is correct, but not an assert related to the logic of our test. 722 Preconditions.checkState(mEnv.state.stack.size() == 2); 723 Preconditions.checkNotNull(mEnv.state.stack.peek()); 724 725 DocumentInfo rootDoc = mEnv.state.stack.peek(); 726 rootDoc.displayName = "poodles"; 727 728 mHandler.showInspector(rootDoc); 729 Intent intent = mActivity.startActivity.getLastValue(); 730 assertFalse(intent.getExtras().containsKey(Intent.EXTRA_TITLE)); 731 } 732 assertRootPicked(Uri expectedUri)733 private void assertRootPicked(Uri expectedUri) throws Exception { 734 mEnv.beforeAsserts(); 735 736 mActivity.rootPicked.assertCalled(); 737 RootInfo root = mActivity.rootPicked.getLastValue(); 738 assertNotNull(root); 739 assertEquals(expectedUri, root.getUri()); 740 } 741 createHandler()742 private ActionHandler<TestActivity> createHandler() { 743 return new ActionHandler<>( 744 mActivity, 745 mEnv.state, 746 mEnv.providers, 747 mEnv.docs, 748 mEnv.searchViewManager, 749 mEnv::lookupExecutor, 750 mActionModeAddons, 751 mClipper, 752 null, // clip storage, not utilized unless we venture into *jumbo* clip territory. 753 mDragAndDropManager, 754 mEnv.injector 755 ); 756 } 757 } 758