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