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