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.intentresolver; 18 19 import static androidx.test.espresso.Espresso.onView; 20 import static androidx.test.espresso.action.ViewActions.click; 21 import static androidx.test.espresso.action.ViewActions.swipeUp; 22 import static androidx.test.espresso.assertion.ViewAssertions.matches; 23 import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; 24 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; 25 import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; 26 import static androidx.test.espresso.matcher.ViewMatchers.withId; 27 import static androidx.test.espresso.matcher.ViewMatchers.withText; 28 29 import static com.android.intentresolver.MatcherUtils.first; 30 import static com.android.intentresolver.ResolverWrapperActivity.sOverrides; 31 32 import static org.hamcrest.CoreMatchers.allOf; 33 import static org.hamcrest.CoreMatchers.is; 34 import static org.hamcrest.CoreMatchers.not; 35 import static org.hamcrest.MatcherAssert.assertThat; 36 import static org.junit.Assert.assertFalse; 37 import static org.junit.Assert.assertNull; 38 import static org.junit.Assert.fail; 39 import static org.mockito.ArgumentMatchers.eq; 40 import static org.mockito.Mockito.when; 41 42 import android.content.Intent; 43 import android.content.pm.ResolveInfo; 44 import android.net.Uri; 45 import android.os.RemoteException; 46 import android.os.UserHandle; 47 import android.text.TextUtils; 48 import android.view.View; 49 import android.widget.RelativeLayout; 50 import android.widget.TextView; 51 52 import androidx.test.InstrumentationRegistry; 53 import androidx.test.espresso.Espresso; 54 import androidx.test.espresso.NoMatchingViewException; 55 import androidx.test.rule.ActivityTestRule; 56 import androidx.test.runner.AndroidJUnit4; 57 58 import com.android.intentresolver.widget.ResolverDrawerLayout; 59 60 import com.google.android.collect.Lists; 61 62 import org.junit.Before; 63 import org.junit.Ignore; 64 import org.junit.Rule; 65 import org.junit.Test; 66 import org.junit.runner.RunWith; 67 import org.mockito.Mockito; 68 69 import java.util.ArrayList; 70 import java.util.List; 71 72 /** 73 * Resolver activity instrumentation tests 74 */ 75 @RunWith(AndroidJUnit4.class) 76 public class ResolverActivityTest { 77 78 private static final UserHandle PERSONAL_USER_HANDLE = androidx.test.platform.app 79 .InstrumentationRegistry.getInstrumentation().getTargetContext().getUser(); getConcreteIntentForLaunch(Intent clientIntent)80 protected Intent getConcreteIntentForLaunch(Intent clientIntent) { 81 clientIntent.setClass( 82 androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().getTargetContext(), 83 ResolverWrapperActivity.class); 84 return clientIntent; 85 } 86 87 @Rule 88 public ActivityTestRule<ResolverWrapperActivity> mActivityRule = 89 new ActivityTestRule<>(ResolverWrapperActivity.class, false, false); 90 91 @Before setup()92 public void setup() { 93 // TODO: use the other form of `adoptShellPermissionIdentity()` where we explicitly list the 94 // permissions we require (which we'll read from the manifest at runtime). 95 androidx.test.platform.app.InstrumentationRegistry 96 .getInstrumentation() 97 .getUiAutomation() 98 .adoptShellPermissionIdentity(); 99 100 sOverrides.reset(); 101 } 102 103 @Test twoOptionsAndUserSelectsOne()104 public void twoOptionsAndUserSelectsOne() throws InterruptedException { 105 Intent sendIntent = createSendImageIntent(); 106 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2, 107 PERSONAL_USER_HANDLE); 108 109 setupResolverControllers(resolvedComponentInfos); 110 111 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 112 Espresso.registerIdlingResources(activity.getLabelIdlingResource()); 113 waitForIdle(); 114 115 assertThat(activity.getAdapter().getCount(), is(2)); 116 117 ResolveInfo[] chosen = new ResolveInfo[1]; 118 sOverrides.onSafelyStartInternalCallback = result -> { 119 chosen[0] = result.first.getResolveInfo(); 120 return true; 121 }; 122 123 ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0); 124 onView(withText(toChoose.activityInfo.name)) 125 .perform(click()); 126 onView(withId(com.android.internal.R.id.button_once)) 127 .perform(click()); 128 waitForIdle(); 129 assertThat(chosen[0], is(toChoose)); 130 } 131 132 @Ignore // Failing - b/144929805 133 @Test setMaxHeight()134 public void setMaxHeight() throws Exception { 135 Intent sendIntent = createSendImageIntent(); 136 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2, 137 PERSONAL_USER_HANDLE); 138 139 setupResolverControllers(resolvedComponentInfos); 140 waitForIdle(); 141 142 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 143 final View viewPager = activity.findViewById(com.android.internal.R.id.profile_pager); 144 final int initialResolverHeight = viewPager.getHeight(); 145 146 activity.runOnUiThread(() -> { 147 ResolverDrawerLayout layout = (ResolverDrawerLayout) 148 activity.findViewById( 149 com.android.internal.R.id.contentPanel); 150 ((ResolverDrawerLayout.LayoutParams) viewPager.getLayoutParams()).maxHeight 151 = initialResolverHeight - 1; 152 // Force a relayout 153 layout.invalidate(); 154 layout.requestLayout(); 155 }); 156 waitForIdle(); 157 assertThat("Drawer should be capped at maxHeight", 158 viewPager.getHeight() == (initialResolverHeight - 1)); 159 160 activity.runOnUiThread(() -> { 161 ResolverDrawerLayout layout = (ResolverDrawerLayout) 162 activity.findViewById( 163 com.android.internal.R.id.contentPanel); 164 ((ResolverDrawerLayout.LayoutParams) viewPager.getLayoutParams()).maxHeight 165 = initialResolverHeight + 1; 166 // Force a relayout 167 layout.invalidate(); 168 layout.requestLayout(); 169 }); 170 waitForIdle(); 171 assertThat("Drawer should not change height if its height is less than maxHeight", 172 viewPager.getHeight() == initialResolverHeight); 173 } 174 175 @Ignore // Failing - b/144929805 176 @Test setShowAtTopToTrue()177 public void setShowAtTopToTrue() throws Exception { 178 Intent sendIntent = createSendImageIntent(); 179 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2, 180 PERSONAL_USER_HANDLE); 181 182 setupResolverControllers(resolvedComponentInfos); 183 waitForIdle(); 184 185 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 186 final View viewPager = activity.findViewById(com.android.internal.R.id.profile_pager); 187 final View divider = activity.findViewById(com.android.internal.R.id.divider); 188 final RelativeLayout profileView = 189 (RelativeLayout) activity.findViewById(com.android.internal.R.id.profile_button) 190 .getParent(); 191 assertThat("Drawer should show at bottom by default", 192 profileView.getBottom() + divider.getHeight() == viewPager.getTop() 193 && profileView.getTop() > 0); 194 195 activity.runOnUiThread(() -> { 196 ResolverDrawerLayout layout = (ResolverDrawerLayout) 197 activity.findViewById( 198 com.android.internal.R.id.contentPanel); 199 layout.setShowAtTop(true); 200 }); 201 waitForIdle(); 202 assertThat("Drawer should show at top with new attribute", 203 profileView.getBottom() + divider.getHeight() == viewPager.getTop() 204 && profileView.getTop() == 0); 205 } 206 207 @Test hasLastChosenActivity()208 public void hasLastChosenActivity() throws Exception { 209 Intent sendIntent = createSendImageIntent(); 210 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2, 211 PERSONAL_USER_HANDLE); 212 ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0); 213 214 setupResolverControllers(resolvedComponentInfos); 215 when(sOverrides.resolverListController.getLastChosen()) 216 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0)); 217 218 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 219 waitForIdle(); 220 221 // The other entry is filtered to the last used slot 222 assertThat(activity.getAdapter().getCount(), is(1)); 223 assertThat(activity.getAdapter().getPlaceholderCount(), is(1)); 224 225 ResolveInfo[] chosen = new ResolveInfo[1]; 226 sOverrides.onSafelyStartInternalCallback = result -> { 227 chosen[0] = result.first.getResolveInfo(); 228 return true; 229 }; 230 231 onView(withId(com.android.internal.R.id.button_once)).perform(click()); 232 waitForIdle(); 233 assertThat(chosen[0], is(toChoose)); 234 } 235 236 @Test hasOtherProfileOneOption()237 public void hasOtherProfileOneOption() throws Exception { 238 List<ResolvedComponentInfo> personalResolvedComponentInfos = 239 createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10, 240 PERSONAL_USER_HANDLE); 241 markWorkProfileUserAvailable(); 242 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 243 sOverrides.workProfileUserHandle); 244 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 245 246 ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0); 247 Intent sendIntent = createSendImageIntent(); 248 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 249 Espresso.registerIdlingResources(activity.getLabelIdlingResource()); 250 waitForIdle(); 251 252 // The other entry is filtered to the last used slot 253 assertThat(activity.getAdapter().getCount(), is(1)); 254 255 ResolveInfo[] chosen = new ResolveInfo[1]; 256 sOverrides.onSafelyStartInternalCallback = result -> { 257 chosen[0] = result.first.getResolveInfo(); 258 return true; 259 }; 260 // Make a stable copy of the components as the original list may be modified 261 List<ResolvedComponentInfo> stableCopy = 262 createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10, 263 PERSONAL_USER_HANDLE); 264 // We pick the first one as there is another one in the work profile side 265 onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))) 266 .perform(click()); 267 onView(withId(com.android.internal.R.id.button_once)) 268 .perform(click()); 269 waitForIdle(); 270 assertThat(chosen[0], is(toChoose)); 271 } 272 273 @Test hasOtherProfileTwoOptionsAndUserSelectsOne()274 public void hasOtherProfileTwoOptionsAndUserSelectsOne() throws Exception { 275 Intent sendIntent = createSendImageIntent(); 276 List<ResolvedComponentInfo> resolvedComponentInfos = 277 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE); 278 ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); 279 280 setupResolverControllers(resolvedComponentInfos); 281 282 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 283 Espresso.registerIdlingResources(activity.getLabelIdlingResource()); 284 waitForIdle(); 285 286 // The other entry is filtered to the other profile slot 287 assertThat(activity.getAdapter().getCount(), is(2)); 288 289 ResolveInfo[] chosen = new ResolveInfo[1]; 290 sOverrides.onSafelyStartInternalCallback = result -> { 291 chosen[0] = result.first.getResolveInfo(); 292 return true; 293 }; 294 295 // Confirm that the button bar is disabled by default 296 onView(withId(com.android.internal.R.id.button_once)).check(matches(not(isEnabled()))); 297 298 // Make a stable copy of the components as the original list may be modified 299 List<ResolvedComponentInfo> stableCopy = 300 createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE); 301 302 onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)) 303 .perform(click()); 304 onView(withId(com.android.internal.R.id.button_once)).perform(click()); 305 waitForIdle(); 306 assertThat(chosen[0], is(toChoose)); 307 } 308 309 310 @Test hasLastChosenActivityAndOtherProfile()311 public void hasLastChosenActivityAndOtherProfile() throws Exception { 312 // In this case we prefer the other profile and don't display anything about the last 313 // chosen activity. 314 Intent sendIntent = createSendImageIntent(); 315 List<ResolvedComponentInfo> resolvedComponentInfos = 316 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE); 317 ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); 318 319 setupResolverControllers(resolvedComponentInfos); 320 when(sOverrides.resolverListController.getLastChosen()) 321 .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0)); 322 323 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 324 Espresso.registerIdlingResources(activity.getLabelIdlingResource()); 325 waitForIdle(); 326 327 // The other entry is filtered to the other profile slot 328 assertThat(activity.getAdapter().getCount(), is(2)); 329 330 ResolveInfo[] chosen = new ResolveInfo[1]; 331 sOverrides.onSafelyStartInternalCallback = result -> { 332 chosen[0] = result.first.getResolveInfo(); 333 return true; 334 }; 335 336 // Confirm that the button bar is disabled by default 337 onView(withId(com.android.internal.R.id.button_once)).check(matches(not(isEnabled()))); 338 339 // Make a stable copy of the components as the original list may be modified 340 List<ResolvedComponentInfo> stableCopy = 341 createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE); 342 343 onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)) 344 .perform(click()); 345 onView(withId(com.android.internal.R.id.button_once)).perform(click()); 346 waitForIdle(); 347 assertThat(chosen[0], is(toChoose)); 348 } 349 350 @Test testWorkTab_displayedWhenWorkProfileUserAvailable()351 public void testWorkTab_displayedWhenWorkProfileUserAvailable() { 352 Intent sendIntent = createSendImageIntent(); 353 markWorkProfileUserAvailable(); 354 355 mActivityRule.launchActivity(sendIntent); 356 waitForIdle(); 357 358 onView(withId(com.android.internal.R.id.tabs)).check(matches(isDisplayed())); 359 } 360 361 @Test testWorkTab_hiddenWhenWorkProfileUserNotAvailable()362 public void testWorkTab_hiddenWhenWorkProfileUserNotAvailable() { 363 Intent sendIntent = createSendImageIntent(); 364 365 mActivityRule.launchActivity(sendIntent); 366 waitForIdle(); 367 368 onView(withId(com.android.internal.R.id.tabs)).check(matches(not(isDisplayed()))); 369 } 370 371 @Test testWorkTab_workTabListPopulatedBeforeGoingToTab()372 public void testWorkTab_workTabListPopulatedBeforeGoingToTab() throws InterruptedException { 373 List<ResolvedComponentInfo> personalResolvedComponentInfos = 374 createResolvedComponentsForTestWithOtherProfile(3, /* userId = */ 10, 375 PERSONAL_USER_HANDLE); 376 markWorkProfileUserAvailable(); 377 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 378 sOverrides.workProfileUserHandle); 379 setupResolverControllers(personalResolvedComponentInfos, 380 new ArrayList<>(workResolvedComponentInfos)); 381 Intent sendIntent = createSendImageIntent(); 382 383 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 384 waitForIdle(); 385 386 assertThat(activity.getCurrentUserHandle().getIdentifier(), is(0)); 387 // The work list adapter must be populated in advance before tapping the other tab 388 assertThat(activity.getWorkListAdapter().getCount(), is(4)); 389 } 390 391 @Test testWorkTab_workTabUsesExpectedAdapter()392 public void testWorkTab_workTabUsesExpectedAdapter() { 393 List<ResolvedComponentInfo> personalResolvedComponentInfos = 394 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10, 395 PERSONAL_USER_HANDLE); 396 markWorkProfileUserAvailable(); 397 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 398 sOverrides.workProfileUserHandle); 399 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 400 Intent sendIntent = createSendImageIntent(); 401 markWorkProfileUserAvailable(); 402 403 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 404 waitForIdle(); 405 onView(withText(R.string.resolver_work_tab)).perform(click()); 406 407 assertThat(activity.getCurrentUserHandle().getIdentifier(), is(10)); 408 assertThat(activity.getWorkListAdapter().getCount(), is(4)); 409 } 410 411 @Test testWorkTab_personalTabUsesExpectedAdapter()412 public void testWorkTab_personalTabUsesExpectedAdapter() { 413 List<ResolvedComponentInfo> personalResolvedComponentInfos = 414 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE); 415 markWorkProfileUserAvailable(); 416 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 417 sOverrides.workProfileUserHandle); 418 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 419 Intent sendIntent = createSendImageIntent(); 420 421 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 422 waitForIdle(); 423 onView(withText(R.string.resolver_work_tab)).perform(click()); 424 425 assertThat(activity.getCurrentUserHandle().getIdentifier(), is(10)); 426 assertThat(activity.getPersonalListAdapter().getCount(), is(2)); 427 } 428 429 @Test testWorkTab_workProfileHasExpectedNumberOfTargets()430 public void testWorkTab_workProfileHasExpectedNumberOfTargets() throws InterruptedException { 431 markWorkProfileUserAvailable(); 432 List<ResolvedComponentInfo> personalResolvedComponentInfos = 433 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10, 434 PERSONAL_USER_HANDLE); 435 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 436 sOverrides.workProfileUserHandle); 437 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 438 Intent sendIntent = createSendImageIntent(); 439 440 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 441 waitForIdle(); 442 443 onView(withText(R.string.resolver_work_tab)) 444 .perform(click()); 445 waitForIdle(); 446 assertThat(activity.getWorkListAdapter().getCount(), is(4)); 447 } 448 449 @Test testWorkTab_selectingWorkTabAppOpensAppInWorkProfile()450 public void testWorkTab_selectingWorkTabAppOpensAppInWorkProfile() throws InterruptedException { 451 markWorkProfileUserAvailable(); 452 List<ResolvedComponentInfo> personalResolvedComponentInfos = 453 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10, 454 PERSONAL_USER_HANDLE); 455 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 456 sOverrides.workProfileUserHandle); 457 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 458 Intent sendIntent = createSendImageIntent(); 459 ResolveInfo[] chosen = new ResolveInfo[1]; 460 sOverrides.onSafelyStartInternalCallback = result -> { 461 chosen[0] = result.first.getResolveInfo(); 462 return true; 463 }; 464 465 mActivityRule.launchActivity(sendIntent); 466 waitForIdle(); 467 onView(withText(R.string.resolver_work_tab)) 468 .perform(click()); 469 waitForIdle(); 470 onView(first(allOf(withText(workResolvedComponentInfos.get(0) 471 .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed()))) 472 .perform(click()); 473 onView(withId(com.android.internal.R.id.button_once)) 474 .perform(click()); 475 476 waitForIdle(); 477 assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0))); 478 } 479 480 @Test testWorkTab_noPersonalApps_workTabHasExpectedNumberOfTargets()481 public void testWorkTab_noPersonalApps_workTabHasExpectedNumberOfTargets() 482 throws InterruptedException { 483 markWorkProfileUserAvailable(); 484 List<ResolvedComponentInfo> personalResolvedComponentInfos = 485 createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE); 486 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 487 sOverrides.workProfileUserHandle); 488 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 489 Intent sendIntent = createSendImageIntent(); 490 491 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 492 waitForIdle(); 493 onView(withText(R.string.resolver_work_tab)) 494 .perform(click()); 495 496 waitForIdle(); 497 assertThat(activity.getWorkListAdapter().getCount(), is(4)); 498 } 499 500 @Test testWorkTab_headerIsVisibleInPersonalTab()501 public void testWorkTab_headerIsVisibleInPersonalTab() { 502 markWorkProfileUserAvailable(); 503 List<ResolvedComponentInfo> personalResolvedComponentInfos = 504 createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE); 505 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 506 sOverrides.workProfileUserHandle); 507 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 508 Intent sendIntent = createOpenWebsiteIntent(); 509 510 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 511 waitForIdle(); 512 TextView headerText = activity.findViewById(com.android.internal.R.id.title); 513 String initialText = headerText.getText().toString(); 514 assertFalse("Header text is empty.", initialText.isEmpty()); 515 assertThat(headerText.getVisibility(), is(View.VISIBLE)); 516 } 517 518 @Test testWorkTab_switchTabs_headerStaysSame()519 public void testWorkTab_switchTabs_headerStaysSame() { 520 markWorkProfileUserAvailable(); 521 List<ResolvedComponentInfo> personalResolvedComponentInfos = 522 createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE); 523 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 524 sOverrides.workProfileUserHandle); 525 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 526 Intent sendIntent = createOpenWebsiteIntent(); 527 528 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 529 waitForIdle(); 530 TextView headerText = activity.findViewById(com.android.internal.R.id.title); 531 String initialText = headerText.getText().toString(); 532 onView(withText(R.string.resolver_work_tab)) 533 .perform(click()); 534 535 waitForIdle(); 536 String currentText = headerText.getText().toString(); 537 assertThat(headerText.getVisibility(), is(View.VISIBLE)); 538 assertThat(String.format("Header text is not the same when switching tabs, personal profile" 539 + " header was %s but work profile header is %s", initialText, currentText), 540 TextUtils.equals(initialText, currentText)); 541 } 542 543 @Test testWorkTab_noPersonalApps_canStartWorkApps()544 public void testWorkTab_noPersonalApps_canStartWorkApps() 545 throws InterruptedException { 546 markWorkProfileUserAvailable(); 547 List<ResolvedComponentInfo> personalResolvedComponentInfos = 548 createResolvedComponentsForTestWithOtherProfile(3, /* userId= */ 10, 549 PERSONAL_USER_HANDLE); 550 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 551 sOverrides.workProfileUserHandle); 552 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 553 Intent sendIntent = createSendImageIntent(); 554 ResolveInfo[] chosen = new ResolveInfo[1]; 555 sOverrides.onSafelyStartInternalCallback = result -> { 556 chosen[0] = result.first.getResolveInfo(); 557 return true; 558 }; 559 560 mActivityRule.launchActivity(sendIntent); 561 waitForIdle(); 562 onView(withText(R.string.resolver_work_tab)) 563 .perform(click()); 564 waitForIdle(); 565 onView(first(allOf( 566 withText(workResolvedComponentInfos.get(0) 567 .getResolveInfoAt(0).activityInfo.applicationInfo.name), 568 isDisplayed()))) 569 .perform(click()); 570 onView(withId(com.android.internal.R.id.button_once)) 571 .perform(click()); 572 waitForIdle(); 573 574 assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0))); 575 } 576 577 @Test testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown()578 public void testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown() { 579 markWorkProfileUserAvailable(); 580 int workProfileTargets = 4; 581 List<ResolvedComponentInfo> personalResolvedComponentInfos = 582 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10, 583 PERSONAL_USER_HANDLE); 584 List<ResolvedComponentInfo> workResolvedComponentInfos = 585 createResolvedComponentsForTest(workProfileTargets, 586 sOverrides.workProfileUserHandle); 587 sOverrides.hasCrossProfileIntents = false; 588 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 589 Intent sendIntent = createSendImageIntent(); 590 sendIntent.setType("TestType"); 591 592 mActivityRule.launchActivity(sendIntent); 593 waitForIdle(); 594 onView(withText(R.string.resolver_work_tab)).perform(click()); 595 waitForIdle(); 596 onView(withId(com.android.internal.R.id.contentPanel)) 597 .perform(swipeUp()); 598 599 onView(withText(R.string.resolver_cross_profile_blocked)) 600 .check(matches(isDisplayed())); 601 } 602 603 @Test testWorkTab_workProfileDisabled_emptyStateShown()604 public void testWorkTab_workProfileDisabled_emptyStateShown() { 605 markWorkProfileUserAvailable(); 606 int workProfileTargets = 4; 607 List<ResolvedComponentInfo> personalResolvedComponentInfos = 608 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10, 609 PERSONAL_USER_HANDLE); 610 List<ResolvedComponentInfo> workResolvedComponentInfos = 611 createResolvedComponentsForTest(workProfileTargets, 612 sOverrides.workProfileUserHandle); 613 sOverrides.isQuietModeEnabled = true; 614 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 615 Intent sendIntent = createSendImageIntent(); 616 sendIntent.setType("TestType"); 617 618 mActivityRule.launchActivity(sendIntent); 619 waitForIdle(); 620 onView(withId(com.android.internal.R.id.contentPanel)) 621 .perform(swipeUp()); 622 onView(withText(R.string.resolver_work_tab)).perform(click()); 623 waitForIdle(); 624 625 onView(withText(R.string.resolver_turn_on_work_apps)) 626 .check(matches(isDisplayed())); 627 } 628 629 @Test testWorkTab_noWorkAppsAvailable_emptyStateShown()630 public void testWorkTab_noWorkAppsAvailable_emptyStateShown() { 631 markWorkProfileUserAvailable(); 632 List<ResolvedComponentInfo> personalResolvedComponentInfos = 633 createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE); 634 List<ResolvedComponentInfo> workResolvedComponentInfos = 635 createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle); 636 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 637 Intent sendIntent = createSendImageIntent(); 638 sendIntent.setType("TestType"); 639 640 mActivityRule.launchActivity(sendIntent); 641 waitForIdle(); 642 onView(withId(com.android.internal.R.id.contentPanel)) 643 .perform(swipeUp()); 644 onView(withText(R.string.resolver_work_tab)).perform(click()); 645 waitForIdle(); 646 647 onView(withText(R.string.resolver_no_work_apps_available)) 648 .check(matches(isDisplayed())); 649 } 650 651 @Test testWorkTab_xProfileOff_noAppsAvailable_workOff_xProfileOffEmptyStateShown()652 public void testWorkTab_xProfileOff_noAppsAvailable_workOff_xProfileOffEmptyStateShown() { 653 markWorkProfileUserAvailable(); 654 List<ResolvedComponentInfo> personalResolvedComponentInfos = 655 createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE); 656 List<ResolvedComponentInfo> workResolvedComponentInfos = 657 createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle); 658 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 659 Intent sendIntent = createSendImageIntent(); 660 sendIntent.setType("TestType"); 661 sOverrides.isQuietModeEnabled = true; 662 sOverrides.hasCrossProfileIntents = false; 663 664 mActivityRule.launchActivity(sendIntent); 665 waitForIdle(); 666 onView(withId(com.android.internal.R.id.contentPanel)) 667 .perform(swipeUp()); 668 onView(withText(R.string.resolver_work_tab)).perform(click()); 669 waitForIdle(); 670 671 onView(withText(R.string.resolver_cross_profile_blocked)) 672 .check(matches(isDisplayed())); 673 } 674 675 @Test testMiniResolver()676 public void testMiniResolver() { 677 markWorkProfileUserAvailable(); 678 List<ResolvedComponentInfo> personalResolvedComponentInfos = 679 createResolvedComponentsForTest(1, PERSONAL_USER_HANDLE); 680 List<ResolvedComponentInfo> workResolvedComponentInfos = 681 createResolvedComponentsForTest(1, sOverrides.workProfileUserHandle); 682 // Personal profile only has a browser 683 personalResolvedComponentInfos.get(0).getResolveInfoAt(0).handleAllWebDataURI = true; 684 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 685 Intent sendIntent = createSendImageIntent(); 686 sendIntent.setType("TestType"); 687 688 mActivityRule.launchActivity(sendIntent); 689 waitForIdle(); 690 onView(withId(com.android.internal.R.id.open_cross_profile)).check(matches(isDisplayed())); 691 } 692 693 @Test testMiniResolver_noCurrentProfileTarget()694 public void testMiniResolver_noCurrentProfileTarget() { 695 markWorkProfileUserAvailable(); 696 List<ResolvedComponentInfo> personalResolvedComponentInfos = 697 createResolvedComponentsForTest(0, PERSONAL_USER_HANDLE); 698 List<ResolvedComponentInfo> workResolvedComponentInfos = 699 createResolvedComponentsForTest(1, sOverrides.workProfileUserHandle); 700 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 701 Intent sendIntent = createSendImageIntent(); 702 sendIntent.setType("TestType"); 703 704 mActivityRule.launchActivity(sendIntent); 705 waitForIdle(); 706 707 // Need to ensure mini resolver doesn't trigger here. 708 assertNotMiniResolver(); 709 } 710 assertNotMiniResolver()711 private void assertNotMiniResolver() { 712 try { 713 onView(withId(com.android.internal.R.id.open_cross_profile)) 714 .check(matches(isDisplayed())); 715 } catch (NoMatchingViewException e) { 716 return; 717 } 718 fail("Mini resolver present but shouldn't be"); 719 } 720 721 @Test testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown()722 public void testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown() { 723 markWorkProfileUserAvailable(); 724 List<ResolvedComponentInfo> personalResolvedComponentInfos = 725 createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE); 726 List<ResolvedComponentInfo> workResolvedComponentInfos = 727 createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle); 728 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 729 Intent sendIntent = createSendImageIntent(); 730 sendIntent.setType("TestType"); 731 sOverrides.isQuietModeEnabled = true; 732 733 mActivityRule.launchActivity(sendIntent); 734 waitForIdle(); 735 onView(withId(com.android.internal.R.id.contentPanel)) 736 .perform(swipeUp()); 737 onView(withText(R.string.resolver_work_tab)).perform(click()); 738 waitForIdle(); 739 740 onView(withText(R.string.resolver_no_work_apps_available)) 741 .check(matches(isDisplayed())); 742 } 743 744 @Test testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_doesNotAutoLaunch()745 public void testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_doesNotAutoLaunch() { 746 markWorkProfileUserAvailable(); 747 int workProfileTargets = 4; 748 List<ResolvedComponentInfo> personalResolvedComponentInfos = 749 createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10, 750 PERSONAL_USER_HANDLE); 751 List<ResolvedComponentInfo> workResolvedComponentInfos = 752 createResolvedComponentsForTest(workProfileTargets, 753 sOverrides.workProfileUserHandle); 754 sOverrides.hasCrossProfileIntents = false; 755 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 756 Intent sendIntent = createSendImageIntent(); 757 sendIntent.setType("TestType"); 758 ResolveInfo[] chosen = new ResolveInfo[1]; 759 sOverrides.onSafelyStartInternalCallback = result -> { 760 chosen[0] = result.first.getResolveInfo(); 761 return true; 762 }; 763 764 mActivityRule.launchActivity(sendIntent); 765 waitForIdle(); 766 767 assertNull(chosen[0]); 768 } 769 770 @Test testLayoutWithDefault_withWorkTab_neverShown()771 public void testLayoutWithDefault_withWorkTab_neverShown() throws RemoteException { 772 markWorkProfileUserAvailable(); 773 774 // In this case we prefer the other profile and don't display anything about the last 775 // chosen activity. 776 Intent sendIntent = createSendImageIntent(); 777 List<ResolvedComponentInfo> resolvedComponentInfos = 778 createResolvedComponentsForTest(2, PERSONAL_USER_HANDLE); 779 780 setupResolverControllers(resolvedComponentInfos); 781 when(sOverrides.resolverListController.getLastChosen()) 782 .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0)); 783 784 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 785 Espresso.registerIdlingResources(activity.getLabelIdlingResource()); 786 waitForIdle(); 787 788 // The other entry is filtered to the last used slot 789 assertThat(activity.getAdapter().hasFilteredItem(), is(false)); 790 assertThat(activity.getAdapter().getCount(), is(2)); 791 assertThat(activity.getAdapter().getPlaceholderCount(), is(2)); 792 } 793 794 @Test testClonedProfilePresent_personalAdapterIsSetWithPersonalProfile()795 public void testClonedProfilePresent_personalAdapterIsSetWithPersonalProfile() { 796 // enable cloneProfile 797 markCloneProfileUserAvailable(); 798 List<ResolvedComponentInfo> resolvedComponentInfos = 799 createResolvedComponentsWithCloneProfileForTest( 800 3, 801 PERSONAL_USER_HANDLE, 802 sOverrides.cloneProfileUserHandle); 803 setupResolverControllers(resolvedComponentInfos); 804 Intent sendIntent = createSendImageIntent(); 805 806 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 807 waitForIdle(); 808 809 assertThat(activity.getCurrentUserHandle(), is(activity.getPersonalProfileUserHandle())); 810 assertThat(activity.getAdapter().getCount(), is(3)); 811 } 812 813 @Test testClonedProfilePresent_personalTabUsesExpectedAdapter()814 public void testClonedProfilePresent_personalTabUsesExpectedAdapter() { 815 markWorkProfileUserAvailable(); 816 // enable cloneProfile 817 markCloneProfileUserAvailable(); 818 List<ResolvedComponentInfo> personalResolvedComponentInfos = 819 createResolvedComponentsWithCloneProfileForTest( 820 3, 821 PERSONAL_USER_HANDLE, 822 sOverrides.cloneProfileUserHandle); 823 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4, 824 sOverrides.workProfileUserHandle); 825 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 826 Intent sendIntent = createSendImageIntent(); 827 828 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 829 waitForIdle(); 830 831 assertThat(activity.getCurrentUserHandle(), is(activity.getPersonalProfileUserHandle())); 832 assertThat(activity.getAdapter().getCount(), is(3)); 833 } 834 835 @Test testClonedProfilePresent_layoutWithDefault_neverShown()836 public void testClonedProfilePresent_layoutWithDefault_neverShown() throws Exception { 837 // enable cloneProfile 838 markCloneProfileUserAvailable(); 839 Intent sendIntent = createSendImageIntent(); 840 List<ResolvedComponentInfo> resolvedComponentInfos = 841 createResolvedComponentsWithCloneProfileForTest( 842 2, 843 PERSONAL_USER_HANDLE, 844 sOverrides.cloneProfileUserHandle); 845 846 setupResolverControllers(resolvedComponentInfos); 847 when(sOverrides.resolverListController.getLastChosen()) 848 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0)); 849 850 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 851 Espresso.registerIdlingResources(activity.getLabelIdlingResource()); 852 waitForIdle(); 853 854 assertThat(activity.getAdapter().hasFilteredItem(), is(false)); 855 assertThat(activity.getAdapter().getCount(), is(2)); 856 assertThat(activity.getAdapter().getPlaceholderCount(), is(2)); 857 } 858 859 @Test testClonedProfilePresent_alwaysButtonDisabled()860 public void testClonedProfilePresent_alwaysButtonDisabled() throws Exception { 861 // enable cloneProfile 862 markCloneProfileUserAvailable(); 863 Intent sendIntent = createSendImageIntent(); 864 List<ResolvedComponentInfo> resolvedComponentInfos = 865 createResolvedComponentsWithCloneProfileForTest( 866 3, 867 PERSONAL_USER_HANDLE, 868 sOverrides.cloneProfileUserHandle); 869 870 setupResolverControllers(resolvedComponentInfos); 871 when(sOverrides.resolverListController.getLastChosen()) 872 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0)); 873 874 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 875 waitForIdle(); 876 877 // Confirm that the button bar is disabled by default 878 onView(withId(com.android.internal.R.id.button_once)).check(matches(not(isEnabled()))); 879 onView(withId(com.android.internal.R.id.button_always)).check(matches(not(isEnabled()))); 880 881 // Make a stable copy of the components as the original list may be modified 882 List<ResolvedComponentInfo> stableCopy = 883 createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE); 884 885 onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)) 886 .perform(click()); 887 888 onView(withId(com.android.internal.R.id.button_once)).check(matches(isEnabled())); 889 onView(withId(com.android.internal.R.id.button_always)).check(matches(not(isEnabled()))); 890 } 891 892 @Test testClonedProfilePresent_personalProfileActivityIsStartedInCorrectUser()893 public void testClonedProfilePresent_personalProfileActivityIsStartedInCorrectUser() 894 throws Exception { 895 markWorkProfileUserAvailable(); 896 // enable cloneProfile 897 markCloneProfileUserAvailable(); 898 899 List<ResolvedComponentInfo> personalResolvedComponentInfos = 900 createResolvedComponentsWithCloneProfileForTest( 901 3, 902 PERSONAL_USER_HANDLE, 903 sOverrides.cloneProfileUserHandle); 904 List<ResolvedComponentInfo> workResolvedComponentInfos = 905 createResolvedComponentsForTest(3, sOverrides.workProfileUserHandle); 906 sOverrides.hasCrossProfileIntents = false; 907 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 908 Intent sendIntent = createSendImageIntent(); 909 sendIntent.setType("TestType"); 910 final UserHandle[] selectedActivityUserHandle = new UserHandle[1]; 911 sOverrides.onSafelyStartInternalCallback = result -> { 912 selectedActivityUserHandle[0] = result.second; 913 return true; 914 }; 915 916 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 917 waitForIdle(); 918 onView(first(allOf(withText(personalResolvedComponentInfos.get(0) 919 .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed()))) 920 .perform(click()); 921 onView(withId(com.android.internal.R.id.button_once)) 922 .perform(click()); 923 waitForIdle(); 924 925 assertThat(selectedActivityUserHandle[0], is(activity.getAdapter().getUserHandle())); 926 } 927 928 @Test testClonedProfilePresent_workProfileActivityIsStartedInCorrectUser()929 public void testClonedProfilePresent_workProfileActivityIsStartedInCorrectUser() 930 throws Exception { 931 markWorkProfileUserAvailable(); 932 // enable cloneProfile 933 markCloneProfileUserAvailable(); 934 935 List<ResolvedComponentInfo> personalResolvedComponentInfos = 936 createResolvedComponentsWithCloneProfileForTest( 937 3, 938 PERSONAL_USER_HANDLE, 939 sOverrides.cloneProfileUserHandle); 940 List<ResolvedComponentInfo> workResolvedComponentInfos = 941 createResolvedComponentsForTest(3, sOverrides.workProfileUserHandle); 942 setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); 943 Intent sendIntent = createSendImageIntent(); 944 sendIntent.setType("TestType"); 945 final UserHandle[] selectedActivityUserHandle = new UserHandle[1]; 946 sOverrides.onSafelyStartInternalCallback = result -> { 947 selectedActivityUserHandle[0] = result.second; 948 return true; 949 }; 950 951 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 952 waitForIdle(); 953 onView(withText(R.string.resolver_work_tab)) 954 .perform(click()); 955 waitForIdle(); 956 onView(first(allOf(withText(workResolvedComponentInfos.get(0) 957 .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed()))) 958 .perform(click()); 959 onView(withId(com.android.internal.R.id.button_once)) 960 .perform(click()); 961 waitForIdle(); 962 963 assertThat(selectedActivityUserHandle[0], is(activity.getAdapter().getUserHandle())); 964 } 965 966 @Test testClonedProfilePresent_personalProfileResolverComparatorHasCorrectUsers()967 public void testClonedProfilePresent_personalProfileResolverComparatorHasCorrectUsers() 968 throws Exception { 969 // enable cloneProfile 970 markCloneProfileUserAvailable(); 971 List<ResolvedComponentInfo> resolvedComponentInfos = 972 createResolvedComponentsWithCloneProfileForTest( 973 3, 974 PERSONAL_USER_HANDLE, 975 sOverrides.cloneProfileUserHandle); 976 setupResolverControllers(resolvedComponentInfos); 977 Intent sendIntent = createSendImageIntent(); 978 979 final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); 980 waitForIdle(); 981 List<UserHandle> result = activity 982 .getResolverRankerServiceUserHandleList(PERSONAL_USER_HANDLE); 983 984 assertThat(result.containsAll(Lists.newArrayList(PERSONAL_USER_HANDLE, 985 sOverrides.cloneProfileUserHandle)), is(true)); 986 } 987 createSendImageIntent()988 private Intent createSendImageIntent() { 989 Intent sendIntent = new Intent(); 990 sendIntent.setAction(Intent.ACTION_SEND); 991 sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending"); 992 sendIntent.setType("image/jpeg"); 993 return sendIntent; 994 } 995 createOpenWebsiteIntent()996 private Intent createOpenWebsiteIntent() { 997 Intent sendIntent = new Intent(); 998 sendIntent.setAction(Intent.ACTION_VIEW); 999 sendIntent.setData(Uri.parse("https://google.com")); 1000 return sendIntent; 1001 } 1002 createResolvedComponentsForTest(int numberOfResults, UserHandle resolvedForUser)1003 private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults, 1004 UserHandle resolvedForUser) { 1005 List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); 1006 for (int i = 0; i < numberOfResults; i++) { 1007 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser)); 1008 } 1009 return infoList; 1010 } 1011 createResolvedComponentsWithCloneProfileForTest( int numberOfResults, UserHandle resolvedForPersonalUser, UserHandle resolvedForClonedUser)1012 private List<ResolvedComponentInfo> createResolvedComponentsWithCloneProfileForTest( 1013 int numberOfResults, 1014 UserHandle resolvedForPersonalUser, 1015 UserHandle resolvedForClonedUser) { 1016 List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); 1017 for (int i = 0; i < 1; i++) { 1018 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, 1019 resolvedForPersonalUser)); 1020 } 1021 for (int i = 1; i < numberOfResults; i++) { 1022 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, 1023 resolvedForClonedUser)); 1024 } 1025 return infoList; 1026 } 1027 createResolvedComponentsForTestWithOtherProfile( int numberOfResults, UserHandle resolvedForUser)1028 private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile( 1029 int numberOfResults, 1030 UserHandle resolvedForUser) { 1031 List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); 1032 for (int i = 0; i < numberOfResults; i++) { 1033 if (i == 0) { 1034 infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, 1035 resolvedForUser)); 1036 } else { 1037 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser)); 1038 } 1039 } 1040 return infoList; 1041 } 1042 createResolvedComponentsForTestWithOtherProfile( int numberOfResults, int userId, UserHandle resolvedForUser)1043 private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile( 1044 int numberOfResults, int userId, UserHandle resolvedForUser) { 1045 List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); 1046 for (int i = 0; i < numberOfResults; i++) { 1047 if (i == 0) { 1048 infoList.add( 1049 ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId, 1050 resolvedForUser)); 1051 } else { 1052 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser)); 1053 } 1054 } 1055 return infoList; 1056 } 1057 waitForIdle()1058 private void waitForIdle() { 1059 InstrumentationRegistry.getInstrumentation().waitForIdleSync(); 1060 } 1061 markWorkProfileUserAvailable()1062 private void markWorkProfileUserAvailable() { 1063 ResolverWrapperActivity.sOverrides.workProfileUserHandle = UserHandle.of(10); 1064 } 1065 setupResolverControllers( List<ResolvedComponentInfo> personalResolvedComponentInfos)1066 private void setupResolverControllers( 1067 List<ResolvedComponentInfo> personalResolvedComponentInfos) { 1068 setupResolverControllers(personalResolvedComponentInfos, new ArrayList<>()); 1069 } 1070 markCloneProfileUserAvailable()1071 private void markCloneProfileUserAvailable() { 1072 ResolverWrapperActivity.sOverrides.cloneProfileUserHandle = UserHandle.of(11); 1073 } 1074 setupResolverControllers( List<ResolvedComponentInfo> personalResolvedComponentInfos, List<ResolvedComponentInfo> workResolvedComponentInfos)1075 private void setupResolverControllers( 1076 List<ResolvedComponentInfo> personalResolvedComponentInfos, 1077 List<ResolvedComponentInfo> workResolvedComponentInfos) { 1078 when(sOverrides.resolverListController.getResolversForIntentAsUser( 1079 Mockito.anyBoolean(), 1080 Mockito.anyBoolean(), 1081 Mockito.anyBoolean(), 1082 Mockito.isA(List.class), 1083 eq(UserHandle.SYSTEM))) 1084 .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); 1085 when(sOverrides.workResolverListController.getResolversForIntentAsUser( 1086 Mockito.anyBoolean(), 1087 Mockito.anyBoolean(), 1088 Mockito.anyBoolean(), 1089 Mockito.isA(List.class), 1090 eq(UserHandle.SYSTEM))) 1091 .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); 1092 when(sOverrides.workResolverListController.getResolversForIntentAsUser( 1093 Mockito.anyBoolean(), 1094 Mockito.anyBoolean(), 1095 Mockito.anyBoolean(), 1096 Mockito.isA(List.class), 1097 eq(UserHandle.of(10)))) 1098 .thenReturn(new ArrayList<>(workResolvedComponentInfos)); 1099 } 1100 } 1101