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.picker; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertNotNull; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.verify; 25 26 import android.app.Activity; 27 import android.content.ClipData; 28 import android.content.ComponentName; 29 import android.content.Intent; 30 import android.content.pm.ResolveInfo; 31 import android.net.Uri; 32 import android.os.AsyncTask; 33 import android.provider.DocumentsContract; 34 import android.provider.DocumentsContract.Path; 35 36 import androidx.fragment.app.FragmentActivity; 37 import androidx.test.filters.MediumTest; 38 import androidx.test.filters.SdkSuppress; 39 40 import com.android.documentsui.DocumentsAccess; 41 import com.android.documentsui.Injector; 42 import com.android.documentsui.R; 43 import com.android.documentsui.TestConfigStore; 44 import com.android.documentsui.base.DocumentInfo; 45 import com.android.documentsui.base.DocumentStack; 46 import com.android.documentsui.base.Lookup; 47 import com.android.documentsui.base.RootInfo; 48 import com.android.documentsui.base.Shared; 49 import com.android.documentsui.base.State; 50 import com.android.documentsui.base.State.ActionType; 51 import com.android.documentsui.picker.ActionHandler.Addons; 52 import com.android.documentsui.queries.SearchViewManager; 53 import com.android.documentsui.roots.ProvidersAccess; 54 import com.android.documentsui.testing.DocumentStackAsserts; 55 import com.android.documentsui.testing.TestEnv; 56 import com.android.documentsui.testing.TestLastAccessedStorage; 57 import com.android.documentsui.testing.TestProvidersAccess; 58 import com.android.documentsui.testing.TestResolveInfo; 59 import com.android.documentsui.util.VersionUtils; 60 import com.android.modules.utils.build.SdkLevel; 61 62 import com.google.common.collect.Lists; 63 64 import org.junit.AfterClass; 65 import org.junit.Before; 66 import org.junit.Test; 67 import org.junit.runner.RunWith; 68 import org.junit.runners.Parameterized; 69 import org.junit.runners.Parameterized.Parameter; 70 import org.junit.runners.Parameterized.Parameters; 71 72 import java.util.Arrays; 73 import java.util.concurrent.Executor; 74 75 @RunWith(Parameterized.class) 76 @MediumTest 77 public class ActionHandlerTest { 78 79 private static final String EXTRA_INTENT = "EXTRA_INTENT"; 80 private static final String EXTRA_USER = "EXTRA_USER"; 81 82 private final TestConfigStore mTestConfigStore = new TestConfigStore(); 83 84 private TestEnv mEnv; 85 private TestActivity mActivity; 86 private TestableActionHandler<TestActivity> mHandler; 87 private TestLastAccessedStorage mLastAccessed; 88 private PickCountRecordStorage mPickCountRecord; 89 90 @Parameter(0) 91 public boolean isPrivateSpaceEnabled; 92 93 /** 94 * Parametrize values for {@code isPrivateSpaceEnabled} to run all the tests twice once with 95 * private space flag enabled and once with it disabled. 96 */ 97 @Parameters(name = "privateSpaceEnabled={0}") data()98 public static Iterable<?> data() { 99 return Lists.newArrayList(true, false); 100 } 101 102 @Before setUp()103 public void setUp() { 104 mEnv = TestEnv.create(); 105 mActivity = TestActivity.create(mEnv); 106 mEnv.providers.configurePm(mActivity.packageMgr); 107 mEnv.injector.pickResult = new PickResult(); 108 mLastAccessed = new TestLastAccessedStorage(); 109 mPickCountRecord = mock(PickCountRecordStorage.class); 110 mEnv.state.configStore = mTestConfigStore; 111 112 isPrivateSpaceEnabled = SdkLevel.isAtLeastS() && isPrivateSpaceEnabled; 113 if (isPrivateSpaceEnabled) { 114 mTestConfigStore.enablePrivateSpaceInPhotoPicker(); 115 mEnv.state.canForwardToProfileIdMap.put(TestProvidersAccess.USER_ID, true); 116 } 117 118 mHandler = new TestableActionHandler<>( 119 mActivity, 120 mEnv.state, 121 mEnv.providers, 122 mEnv.docs, 123 mEnv.searchViewManager, 124 mEnv::lookupExecutor, 125 mEnv.injector, 126 mLastAccessed, 127 mPickCountRecord 128 ); 129 130 131 mEnv.selectionMgr.select("1"); 132 133 AsyncTask.setDefaultExecutor(mEnv.mExecutor); 134 } 135 136 private static class TestableActionHandler<T extends FragmentActivity & Addons> 137 extends ActionHandler { 138 139 private UpdatePickResultTask mTask; 140 TestableActionHandler( T activity, State state, ProvidersAccess providers, DocumentsAccess docs, SearchViewManager searchMgr, Lookup<String, Executor> executors, Injector injector, LastAccessedStorage lastAccessed, PickCountRecordStorage pickCountRecordStorage)141 TestableActionHandler( 142 T activity, 143 State state, 144 ProvidersAccess providers, 145 DocumentsAccess docs, 146 SearchViewManager searchMgr, 147 Lookup<String, Executor> executors, 148 Injector injector, 149 LastAccessedStorage lastAccessed, 150 PickCountRecordStorage pickCountRecordStorage) { 151 super(activity, state, providers, docs, searchMgr, executors, injector, lastAccessed); 152 mTask = new UpdatePickResultTask( 153 mActivity, mInjector.pickResult, pickCountRecordStorage); 154 } 155 156 @Override getUpdatePickResultTask()157 public UpdatePickResultTask getUpdatePickResultTask() { 158 return mTask; 159 } 160 } 161 162 @AfterClass tearDownOnce()163 public static void tearDownOnce() { 164 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 165 } 166 167 @Test testInitLocation_RestoresIfStackIsLoaded()168 public void testInitLocation_RestoresIfStackIsLoaded() throws Exception { 169 mEnv.state.stack.changeRoot(TestProvidersAccess.DOWNLOADS); 170 mEnv.state.stack.push(TestEnv.FOLDER_0); 171 172 mHandler.initLocation(mActivity.getIntent()); 173 mActivity.restoreRootAndDirectory.assertCalled(); 174 } 175 176 @Test testInitLocation_LoadsRootDocIfStackOnlyHasRoot()177 public void testInitLocation_LoadsRootDocIfStackOnlyHasRoot() throws Exception { 178 mEnv.state.stack.changeRoot(TestProvidersAccess.HAMMY); 179 180 mHandler.initLocation(mActivity.getIntent()); 181 assertRootPicked(TestProvidersAccess.HAMMY.getUri()); 182 } 183 184 @Test testInitLocation_CopyDestination_DefaultsToDownloads()185 public void testInitLocation_CopyDestination_DefaultsToDownloads() throws Exception { 186 Intent intent = mActivity.getIntent(); 187 intent.setAction(Shared.ACTION_PICK_COPY_DESTINATION); 188 mHandler.initLocation(mActivity.getIntent()); 189 assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri()); 190 } 191 192 @Test 193 // TODO(b/236963677) Test is broken pre-S by ag/16425947. The change introduces usage 194 // of PackageManager, which is mocked by the test and results in NPE. 195 @SdkSuppress(minSdkVersion = 31, codeName = "S") testInitLocation_LaunchToDocuments()196 public void testInitLocation_LaunchToDocuments() throws Exception { 197 if (!mEnv.features.isLaunchToDocumentEnabled()) { 198 return; 199 } 200 201 mEnv.docs.nextIsDocumentsUri = true; 202 mEnv.docs.nextPath = new Path( 203 TestProvidersAccess.HOME.rootId, 204 Arrays.asList( 205 TestEnv.FOLDER_0.documentId, 206 TestEnv.FOLDER_1.documentId, 207 TestEnv.FILE_GIF.documentId)); 208 mEnv.docs.nextDocuments = 209 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1, TestEnv.FILE_GIF); 210 211 mActivity.refreshCurrentRootAndDirectory.assertNotCalled(); 212 Intent intent = mActivity.getIntent(); 213 intent.setAction(Intent.ACTION_GET_CONTENT); 214 intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, TestEnv.FILE_GIF.derivedUri); 215 mHandler.initLocation(intent); 216 217 mEnv.beforeAsserts(); 218 219 DocumentStackAsserts.assertEqualsTo(mEnv.state.stack, TestProvidersAccess.HOME, 220 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1)); 221 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 222 } 223 224 @Test testInitLocation_RestoresLastAccessedStack()225 public void testInitLocation_RestoresLastAccessedStack() throws Exception { 226 final DocumentStack stack = 227 new DocumentStack(TestProvidersAccess.HAMMY, TestEnv.FOLDER_0, TestEnv.FOLDER_1); 228 mLastAccessed.setLastAccessed(mActivity, stack); 229 230 mHandler.initLocation(mActivity.getIntent()); 231 232 mEnv.beforeAsserts(); 233 assertEquals(stack, mEnv.state.stack); 234 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 235 } 236 237 @Test testInitLocation_DefaultToRecents_ActionGetContent()238 public void testInitLocation_DefaultToRecents_ActionGetContent() throws Exception { 239 testInitLocationDefaultToRecentsOnAction(State.ACTION_GET_CONTENT); 240 } 241 242 @Test testInitLocation_DefaultToRecents_ActionOpen()243 public void testInitLocation_DefaultToRecents_ActionOpen() throws Exception { 244 testInitLocationDefaultToRecentsOnAction(State.ACTION_OPEN); 245 } 246 247 @Test testInitLocation_DefaultsToDownloads_ActionCreate()248 public void testInitLocation_DefaultsToDownloads_ActionCreate() throws Exception { 249 testInitLocationDefaultToDownloadsOnAction(State.ACTION_CREATE); 250 } 251 252 @Test testInitLocation_DefaultToDeviceRoot_ActionOpenTree()253 public void testInitLocation_DefaultToDeviceRoot_ActionOpenTree() throws Exception { 254 mEnv.state.action = State.ACTION_OPEN_TREE; 255 256 mHandler.initLocation(mActivity.getIntent()); 257 258 assertRootPicked(TestProvidersAccess.EXTERNALSTORAGE.getUri()); 259 } 260 261 @Test 262 // TODO(b/236963677) Test is broken pre-S by ag/16425947. The change introduces usage 263 // of PackageManager, which is mocked by the test and results in NPE. 264 @SdkSuppress(minSdkVersion = 31, codeName = "S") testInitLocation_DefaultToDeviceRoot_ActionOpenTree_RootDoesNotSupportChildren()265 public void testInitLocation_DefaultToDeviceRoot_ActionOpenTree_RootDoesNotSupportChildren() 266 throws Exception { 267 mEnv.state.action = State.ACTION_OPEN_TREE; 268 269 String authority = TestProvidersAccess.NO_TREE_ROOT.authority; 270 String rootId = TestProvidersAccess.NO_TREE_ROOT.rootId; 271 Uri hintUri = DocumentsContract.buildRootUri(authority, rootId); 272 273 mActivity.getIntent().putExtra(DocumentsContract.EXTRA_INITIAL_URI, hintUri); 274 mHandler.initLocation(mActivity.getIntent()); 275 276 assertRootPicked(TestProvidersAccess.EXTERNALSTORAGE.getUri()); 277 } 278 279 @Test testOpenContainerDocument()280 public void testOpenContainerDocument() { 281 mHandler.openContainerDocument(TestEnv.FOLDER_0); 282 283 assertEquals(TestEnv.FOLDER_0, mEnv.state.stack.peek()); 284 285 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 286 } 287 288 @Test testOpenContainerDocument_sameDocumentInfo()289 public void testOpenContainerDocument_sameDocumentInfo() { 290 mHandler.openContainerDocument(TestEnv.FOLDER_0); 291 mHandler.openContainerDocument(TestEnv.FOLDER_0); 292 293 assertEquals(1, mEnv.state.stack.size()); 294 } 295 296 @Test testIncreasePickCountRecordCalled()297 public void testIncreasePickCountRecordCalled() throws Exception { 298 mEnv.state.action = State.ACTION_GET_CONTENT; 299 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 300 mEnv.state.stack.push(TestEnv.FOLDER_1); 301 302 mActivity.finishedHandler.assertNotCalled(); 303 mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri); 304 305 mEnv.beforeAsserts(); 306 307 verify(mPickCountRecord).increasePickCountRecord( 308 mActivity.getApplicationContext(), TestEnv.FILE_JPG.derivedUri); 309 310 mActivity.finishedHandler.assertCalled(); 311 } 312 313 @Test testPickDocument_SetsCorrectResultAndFinishes_ActionPickCopyDestination()314 public void testPickDocument_SetsCorrectResultAndFinishes_ActionPickCopyDestination() 315 throws Exception { 316 317 mEnv.state.action = State.ACTION_PICK_COPY_DESTINATION; 318 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 319 mEnv.state.stack.push(TestEnv.FOLDER_1); 320 mEnv.state.stack.push(TestEnv.FOLDER_2); 321 322 mActivity.finishedHandler.assertNotCalled(); 323 324 mHandler.pickDocument(null, TestEnv.FOLDER_2); 325 326 mEnv.beforeAsserts(); 327 328 assertLastAccessedStackUpdated(); 329 330 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 331 final Intent result = mActivity.setResult.getLastValue().second; 332 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, false); 333 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false); 334 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 335 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 336 assertContent(result, TestEnv.FOLDER_2.derivedUri); 337 338 mActivity.finishedHandler.assertCalled(); 339 } 340 341 @Test testPickDocument_SetsCorrectResultAndFinishes_ActionOpenTree()342 public void testPickDocument_SetsCorrectResultAndFinishes_ActionOpenTree() throws Exception { 343 mEnv.state.action = State.ACTION_OPEN_TREE; 344 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 345 mEnv.state.stack.push(TestEnv.FOLDER_1); 346 mEnv.state.stack.push(TestEnv.FOLDER_2); 347 348 mActivity.finishedHandler.assertNotCalled(); 349 350 Uri uri = DocumentsContract.buildTreeDocumentUri( 351 TestEnv.FOLDER_2.authority, TestEnv.FOLDER_2.documentId); 352 mHandler.finishPicking(uri); 353 354 mEnv.beforeAsserts(); 355 356 assertLastAccessedStackUpdated(); 357 358 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 359 final Intent result = mActivity.setResult.getLastValue().second; 360 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 361 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true); 362 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 363 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, true); 364 assertContent(result, DocumentsContract.buildTreeDocumentUri( 365 TestProvidersAccess.HOME.authority, TestEnv.FOLDER_2.documentId)); 366 367 mActivity.finishedHandler.assertCalled(); 368 } 369 370 @Test testSaveDocument_SetsCorrectResultAndFinishes()371 public void testSaveDocument_SetsCorrectResultAndFinishes() throws Exception { 372 mEnv.state.action = State.ACTION_CREATE; 373 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 374 mEnv.state.stack.push(TestEnv.FOLDER_1); 375 376 final String mimeType = "audio/aac"; 377 final String displayName = "foobar.m4a"; 378 379 mHandler.saveDocument(mimeType, displayName, (boolean inProgress) -> { 380 }); 381 382 mEnv.beforeAsserts(); 383 384 mEnv.docs.assertCreatedDocument(TestEnv.FOLDER_1, mimeType, displayName); 385 final Uri docUri = mEnv.docs.getLastCreatedDocumentUri(); 386 387 assertLastAccessedStackUpdated(); 388 389 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 390 final Intent result = mActivity.setResult.getLastValue().second; 391 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 392 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true); 393 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 394 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 395 assertContent(result, docUri); 396 397 mActivity.finishedHandler.assertCalled(); 398 } 399 400 @Test testSaveDocument_ConfirmsOverwrite()401 public void testSaveDocument_ConfirmsOverwrite() { 402 if (!mEnv.features.isOverwriteConfirmationEnabled()) { 403 return; 404 } 405 406 mEnv.state.action = State.ACTION_CREATE; 407 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 408 mEnv.state.stack.push(TestEnv.FOLDER_1); 409 410 mHandler.saveDocument(null, TestEnv.FILE_JPG); 411 412 mEnv.dialogs.assertOverwriteConfirmed(TestEnv.FILE_JPG); 413 } 414 415 @Test testPickDocument_ConfirmsOpenTree()416 public void testPickDocument_ConfirmsOpenTree() { 417 mEnv.state.action = State.ACTION_OPEN_TREE; 418 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 419 420 mHandler.pickDocument(null, TestEnv.FOLDER_1); 421 422 mEnv.dialogs.assertDocumentTreeConfirmed(TestEnv.FOLDER_1); 423 } 424 425 @Test testFinishPicking_SetsCorrectResultAndFinishes_ActionGetContent()426 public void testFinishPicking_SetsCorrectResultAndFinishes_ActionGetContent() throws Exception { 427 mEnv.state.action = State.ACTION_GET_CONTENT; 428 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 429 mEnv.state.stack.push(TestEnv.FOLDER_1); 430 431 mActivity.finishedHandler.assertNotCalled(); 432 433 mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri); 434 435 mEnv.beforeAsserts(); 436 437 assertLastAccessedStackUpdated(); 438 439 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 440 final Intent result = mActivity.setResult.getLastValue().second; 441 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 442 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false); 443 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 444 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 445 assertContent(result, TestEnv.FILE_JPG.derivedUri); 446 447 mActivity.finishedHandler.assertCalled(); 448 } 449 450 @Test testFinishPicking_SetsCorrectResultAndFinishes_ActionGetContent_MultipleSelection()451 public void testFinishPicking_SetsCorrectResultAndFinishes_ActionGetContent_MultipleSelection() 452 throws Exception { 453 mEnv.state.action = State.ACTION_GET_CONTENT; 454 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 455 mEnv.state.stack.push(TestEnv.FOLDER_1); 456 mEnv.state.acceptMimes = new String[]{"image/*"}; 457 458 mActivity.finishedHandler.assertNotCalled(); 459 460 mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri); 461 462 mEnv.beforeAsserts(); 463 464 assertLastAccessedStackUpdated(); 465 466 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 467 final Intent result = mActivity.setResult.getLastValue().second; 468 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 469 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false); 470 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 471 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 472 assertContent(result, TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri); 473 474 mActivity.finishedHandler.assertCalled(); 475 } 476 477 @Test testFinishPicking_SetsCorrectResultAndFinishes_ActionOpen()478 public void testFinishPicking_SetsCorrectResultAndFinishes_ActionOpen() throws Exception { 479 mEnv.state.action = State.ACTION_OPEN; 480 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 481 mEnv.state.stack.push(TestEnv.FOLDER_1); 482 483 mActivity.finishedHandler.assertNotCalled(); 484 485 mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri); 486 487 mEnv.beforeAsserts(); 488 489 assertLastAccessedStackUpdated(); 490 491 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 492 final Intent result = mActivity.setResult.getLastValue().second; 493 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 494 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true); 495 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 496 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 497 assertContent(result, TestEnv.FILE_JPG.derivedUri); 498 499 mActivity.finishedHandler.assertCalled(); 500 } 501 502 @Test testFinishPicking_SetsCorrectResultAndFinishes_ActionOpen_MultipleSelection()503 public void testFinishPicking_SetsCorrectResultAndFinishes_ActionOpen_MultipleSelection() 504 throws Exception { 505 mEnv.state.action = State.ACTION_OPEN; 506 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 507 mEnv.state.stack.push(TestEnv.FOLDER_1); 508 mEnv.state.acceptMimes = new String[]{"image/*"}; 509 510 mActivity.finishedHandler.assertNotCalled(); 511 512 mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri); 513 514 mEnv.beforeAsserts(); 515 516 assertLastAccessedStackUpdated(); 517 518 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 519 final Intent result = mActivity.setResult.getLastValue().second; 520 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 521 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true); 522 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 523 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 524 assertContent(result, TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri); 525 526 mActivity.finishedHandler.assertCalled(); 527 } 528 529 @Test testFinishPicking_SetsCorrectResultAndFinishes_ActionCreate()530 public void testFinishPicking_SetsCorrectResultAndFinishes_ActionCreate() throws Exception { 531 mEnv.state.action = State.ACTION_CREATE; 532 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 533 mEnv.state.stack.push(TestEnv.FOLDER_1); 534 535 mActivity.finishedHandler.assertNotCalled(); 536 537 mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri); 538 539 mEnv.beforeAsserts(); 540 541 assertLastAccessedStackUpdated(); 542 543 assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); 544 final Intent result = mActivity.setResult.getLastValue().second; 545 assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 546 assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true); 547 assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 548 assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 549 assertContent(result, TestEnv.FILE_JPG.derivedUri); 550 551 mActivity.finishedHandler.assertCalled(); 552 } 553 554 555 @Test testOpenAppRoot()556 public void testOpenAppRoot() throws Exception { 557 mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.USER_ID); 558 assertNotNull(mActivity.startActivity.getLastValue()); 559 } 560 561 @Test testOpenAppRoot_otherUser()562 public void testOpenAppRoot_otherUser() throws Exception { 563 ResolveInfo info = TestResolveInfo.create(); 564 if (isPrivateSpaceEnabled) { 565 mEnv.state.canForwardToProfileIdMap.put(TestProvidersAccess.OtherUser.USER_ID, true); 566 } else { 567 mEnv.state.canShareAcrossProfile = true; 568 } 569 mHandler.openRoot(info, TestProvidersAccess.OtherUser.USER_ID); 570 assertThat(mActivity.startActivityAsUser.getLastValue().first.getComponent()).isEqualTo( 571 new ComponentName(info.activityInfo.applicationInfo.packageName, 572 info.activityInfo.name)); 573 assertThat(mActivity.startActivityAsUser.getLastValue().second) 574 .isEqualTo(TestProvidersAccess.OtherUser.USER_HANDLE); 575 576 int flags = mActivity.startActivityAsUser.getLastValue().first.getFlags(); 577 assertEquals(0, flags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 578 assertEquals(0, flags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 579 assertEquals(0, flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 580 assertEquals(0, flags & Intent.FLAG_GRANT_READ_URI_PERMISSION); 581 assertEquals(Intent.FLAG_ACTIVITY_FORWARD_RESULT, 582 flags & Intent.FLAG_ACTIVITY_FORWARD_RESULT); 583 assertEquals(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP, 584 flags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); 585 } 586 587 @Test testOpenAppRoot_removeFlagsAddForwardResult()588 public void testOpenAppRoot_removeFlagsAddForwardResult() throws Exception { 589 ResolveInfo info = TestResolveInfo.create(); 590 mActivity.intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT 591 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 592 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION 593 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 594 | Intent.FLAG_GRANT_READ_URI_PERMISSION); 595 mHandler.openRoot(info, TestProvidersAccess.USER_ID); 596 assertThat(mActivity.startActivity.getLastValue().getComponent()).isEqualTo( 597 new ComponentName(info.activityInfo.applicationInfo.packageName, 598 info.activityInfo.name)); 599 600 int flags = mActivity.startActivity.getLastValue().getFlags(); 601 assertEquals(0, flags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 602 assertEquals(0, flags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 603 assertEquals(0, flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 604 assertEquals(0, flags & Intent.FLAG_GRANT_READ_URI_PERMISSION); 605 assertEquals(Intent.FLAG_ACTIVITY_FORWARD_RESULT, 606 flags & Intent.FLAG_ACTIVITY_FORWARD_RESULT); 607 assertEquals(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP, 608 flags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); 609 } 610 611 @Test testOpenAppRootWithQueryContent_matchedContent()612 public void testOpenAppRootWithQueryContent_matchedContent() throws Exception { 613 final String queryContent = "query"; 614 mActivity.intent.putExtra(Intent.EXTRA_CONTENT_QUERY, queryContent); 615 mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.USER_ID); 616 assertEquals(queryContent, 617 mActivity.startActivity.getLastValue().getStringExtra( 618 Intent.EXTRA_CONTENT_QUERY)); 619 } 620 621 @Test testOpenAppRoot_doesNotHappen_differentUser()622 public void testOpenAppRoot_doesNotHappen_differentUser() throws Exception { 623 final String queryContent = "query"; 624 mActivity.intent.putExtra(Intent.EXTRA_CONTENT_QUERY, queryContent); 625 mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.OtherUser.USER_ID); 626 assertThat(mActivity.startActivityForResult.getLastValue()).isNull(); 627 mEnv.dialogs.assertActionNotAllowedShown(); 628 } 629 630 @Test testPreviewItem()631 public void testPreviewItem() throws Exception { 632 mActivity.resources.setQuickViewerPackage("corptropolis.viewer"); 633 mActivity.currentRoot = TestProvidersAccess.HOME; 634 635 mHandler.onDocumentOpened(TestEnv.FILE_GIF, ActionHandler.VIEW_TYPE_PREVIEW, 636 ActionHandler.VIEW_TYPE_REGULAR, true); 637 mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW); 638 } 639 640 @Test testPreviewItem_onOtherUser()641 public void testPreviewItem_onOtherUser() throws Exception { 642 if (VersionUtils.isAtLeastR()) { 643 mActivity.resources.setQuickViewerPackage("corptropolis.viewer"); 644 mActivity.currentRoot = TestProvidersAccess.OtherUser.DOWNLOADS; 645 mEnv.model.reset(); 646 DocumentInfo otherUserDoc = mEnv.model.createDocumentForUser("a.png", 647 "image/png", /* flags= */ 0, TestProvidersAccess.OtherUser.USER_ID); 648 mEnv.model.update(); 649 650 mHandler.onDocumentOpened(otherUserDoc, ActionHandler.VIEW_TYPE_PREVIEW, 651 ActionHandler.VIEW_TYPE_REGULAR, true); 652 mActivity.assertActivityAsUserStarted(Intent.ACTION_QUICK_VIEW, 653 TestProvidersAccess.OtherUser.USER_HANDLE); 654 } 655 } 656 657 @Test testPreviewItem_archives()658 public void testPreviewItem_archives() throws Exception { 659 mActivity.resources.setQuickViewerPackage("corptropolis.viewer"); 660 mActivity.currentRoot = TestProvidersAccess.HOME; 661 662 mHandler.onDocumentOpened(TestEnv.FILE_ARCHIVE, ActionHandler.VIEW_TYPE_PREVIEW, 663 ActionHandler.VIEW_TYPE_REGULAR, true); 664 mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW); 665 } 666 667 @Test testPreviewItem_noQuickViewer()668 public void testPreviewItem_noQuickViewer() throws Exception { 669 mActivity.currentRoot = TestProvidersAccess.HOME; 670 671 mHandler.onDocumentOpened(TestEnv.FILE_GIF, ActionHandler.VIEW_TYPE_PREVIEW, 672 ActionHandler.VIEW_TYPE_REGULAR, true); 673 mActivity.assertActivityStarted(Intent.ACTION_VIEW); 674 } 675 testInitLocationDefaultToRecentsOnAction(@ctionType int action)676 private void testInitLocationDefaultToRecentsOnAction(@ActionType int action) 677 throws Exception { 678 mEnv.state.action = action; 679 680 mActivity.refreshCurrentRootAndDirectory.assertNotCalled(); 681 682 mHandler.initLocation(mActivity.getIntent()); 683 684 mEnv.beforeAsserts(); 685 assertEquals(TestProvidersAccess.RECENTS, mEnv.state.stack.getRoot()); 686 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 687 } 688 testInitLocationDefaultToDownloadsOnAction(@ctionType int action)689 private void testInitLocationDefaultToDownloadsOnAction(@ActionType int action) 690 throws Exception { 691 mEnv.state.action = action; 692 mActivity.resources.strings.put(R.string.default_root_uri, 693 TestProvidersAccess.DOWNLOADS.getUri().toString()); 694 695 mActivity.refreshCurrentRootAndDirectory.assertNotCalled(); 696 697 mHandler.initLocation(mActivity.getIntent()); 698 699 assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri()); 700 } 701 assertRootPicked(Uri expectedUri)702 private void assertRootPicked(Uri expectedUri) throws Exception { 703 mEnv.beforeAsserts(); 704 705 mActivity.rootPicked.assertCalled(); 706 RootInfo root = mActivity.rootPicked.getLastValue(); 707 assertNotNull(root); 708 assertEquals(expectedUri, root.getUri()); 709 } 710 assertLastAccessedStackUpdated()711 private void assertLastAccessedStackUpdated() { 712 assertEquals(mEnv.state.stack, mLastAccessed.getLastAccessed( 713 mActivity, mEnv.providers, mEnv.state)); 714 } 715 assertPermission(Intent intent, int permission, boolean granted)716 private void assertPermission(Intent intent, int permission, boolean granted) { 717 int flags = intent.getFlags(); 718 719 if (granted) { 720 assertEquals(permission, flags & permission); 721 } else { 722 assertEquals(0, flags & permission); 723 } 724 } 725 assertContent(Intent intent, Uri... contents)726 private void assertContent(Intent intent, Uri... contents) { 727 if (contents.length == 1) { 728 assertEquals(contents[0], intent.getData()); 729 } else { 730 ClipData clipData = intent.getClipData(); 731 732 assertNotNull(clipData); 733 for (int i = 0; i < mEnv.state.acceptMimes.length; ++i) { 734 assertEquals(mEnv.state.acceptMimes[i], clipData.getDescription().getMimeType(i)); 735 } 736 for (int i = 0; i < contents.length; ++i) { 737 assertEquals(contents[i], clipData.getItemAt(i).getUri()); 738 } 739 } 740 } 741 }