• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.internal.app;
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.internal.app.MatcherUtils.first;
30 import static com.android.internal.app.ResolverActivity.EXTRA_RESTRICT_TO_SINGLE_USER;
31 import static com.android.internal.app.ResolverDataProvider.createPackageManagerMockedInfo;
32 import static com.android.internal.app.ResolverWrapperActivity.sOverrides;
33 
34 import static junit.framework.Assert.assertEquals;
35 import static junit.framework.Assert.assertTrue;
36 
37 import static org.hamcrest.CoreMatchers.allOf;
38 import static org.hamcrest.CoreMatchers.is;
39 import static org.hamcrest.CoreMatchers.not;
40 import static org.hamcrest.MatcherAssert.assertThat;
41 import static org.mockito.ArgumentMatchers.eq;
42 import static org.mockito.Mockito.when;
43 import static org.testng.Assert.assertFalse;
44 import static org.testng.Assert.fail;
45 
46 import android.content.Intent;
47 import android.content.pm.ResolveInfo;
48 import android.net.Uri;
49 import android.os.RemoteException;
50 import android.os.UserHandle;
51 import android.platform.test.flag.junit.SetFlagsRule;
52 import android.text.TextUtils;
53 import android.view.View;
54 import android.widget.RelativeLayout;
55 import android.widget.TextView;
56 
57 import androidx.test.InstrumentationRegistry;
58 import androidx.test.espresso.Espresso;
59 import androidx.test.espresso.NoMatchingViewException;
60 import androidx.test.ext.junit.runners.AndroidJUnit4;
61 import androidx.test.rule.ActivityTestRule;
62 
63 import com.android.internal.R;
64 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
65 import com.android.internal.app.ResolverDataProvider.PackageManagerMockedInfo;
66 import com.android.internal.app.ResolverListAdapter.ActivityInfoPresentationGetter;
67 import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter;
68 import com.android.internal.widget.ResolverDrawerLayout;
69 
70 import com.google.android.collect.Lists;
71 
72 import org.junit.Before;
73 import org.junit.Ignore;
74 import org.junit.Rule;
75 import org.junit.Test;
76 import org.junit.runner.RunWith;
77 import org.mockito.Mockito;
78 
79 import java.util.ArrayList;
80 import java.util.List;
81 
82 /**
83  * Resolver activity instrumentation tests
84  */
85 @RunWith(AndroidJUnit4.class)
86 public class ResolverActivityTest {
87 
88     private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry
89             .getInstrumentation().getTargetContext().getUser();
90     private static final int WORK_USER_ID = PERSONAL_USER_HANDLE.getIdentifier() + 1;
91     private static final int CLONE_USER_ID = PERSONAL_USER_HANDLE.getIdentifier() + 2;
92     private static final int PRIVATE_USER_ID = PERSONAL_USER_HANDLE.getIdentifier() + 3;
93 
94     @Rule
95     public ActivityTestRule<ResolverWrapperActivity> mActivityRule =
96             new ActivityTestRule<>(ResolverWrapperActivity.class, false,
97                     false);
98     @Rule
99     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
100     @Before
cleanOverrideData()101     public void cleanOverrideData() {
102         sOverrides.reset();
103     }
104 
105     @Test
twoOptionsAndUserSelectsOne()106     public void twoOptionsAndUserSelectsOne() throws InterruptedException {
107         Intent sendIntent = createSendImageIntent();
108         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
109                 PERSONAL_USER_HANDLE);
110 
111         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
112                 Mockito.anyBoolean(),
113                 Mockito.anyBoolean(),
114                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
115 
116         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
117         Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
118         waitForIdle();
119 
120         assertThat(activity.getAdapter().getCount(), is(2));
121 
122         ResolveInfo[] chosen = new ResolveInfo[1];
123         sOverrides.onSafelyStartInternalCallback = result -> {
124             chosen[0] = result.first.getResolveInfo();
125             return true;
126         };
127 
128         ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
129         onView(withText(toChoose.activityInfo.name))
130                 .perform(click());
131         onView(withId(R.id.button_once))
132                 .perform(click());
133         waitForIdle();
134         assertThat(chosen[0], is(toChoose));
135     }
136 
137     @Ignore // Failing - b/144929805
138     @Test
setMaxHeight()139     public void setMaxHeight() throws Exception {
140         Intent sendIntent = createSendImageIntent();
141         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
142                 PERSONAL_USER_HANDLE);
143 
144         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
145                 Mockito.anyBoolean(),
146                 Mockito.anyBoolean(),
147                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
148         waitForIdle();
149 
150         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
151         final View viewPager = activity.findViewById(R.id.profile_pager);
152         final int initialResolverHeight = viewPager.getHeight();
153 
154         activity.runOnUiThread(() -> {
155             ResolverDrawerLayout layout = (ResolverDrawerLayout)
156                     activity.findViewById(
157                             R.id.contentPanel);
158             ((ResolverDrawerLayout.LayoutParams) viewPager.getLayoutParams()).maxHeight
159                 = initialResolverHeight - 1;
160             // Force a relayout
161             layout.invalidate();
162             layout.requestLayout();
163         });
164         waitForIdle();
165         assertThat("Drawer should be capped at maxHeight",
166                 viewPager.getHeight() == (initialResolverHeight - 1));
167 
168         activity.runOnUiThread(() -> {
169             ResolverDrawerLayout layout = (ResolverDrawerLayout)
170                     activity.findViewById(
171                             R.id.contentPanel);
172             ((ResolverDrawerLayout.LayoutParams) viewPager.getLayoutParams()).maxHeight
173                 = initialResolverHeight + 1;
174             // Force a relayout
175             layout.invalidate();
176             layout.requestLayout();
177         });
178         waitForIdle();
179         assertThat("Drawer should not change height if its height is less than maxHeight",
180                 viewPager.getHeight() == initialResolverHeight);
181     }
182 
183     @Ignore // Failing - b/144929805
184     @Test
setShowAtTopToTrue()185     public void setShowAtTopToTrue() throws Exception {
186         Intent sendIntent = createSendImageIntent();
187         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
188                 PERSONAL_USER_HANDLE);
189 
190         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
191                 Mockito.anyBoolean(),
192                 Mockito.anyBoolean(),
193                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
194         waitForIdle();
195 
196         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
197         final View viewPager = activity.findViewById(R.id.profile_pager);
198         final View divider = activity.findViewById(R.id.divider);
199         final RelativeLayout profileView =
200             (RelativeLayout) activity.findViewById(R.id.profile_button).getParent();
201         assertThat("Drawer should show at bottom by default",
202                 profileView.getBottom() + divider.getHeight() == viewPager.getTop()
203                         && profileView.getTop() > 0);
204 
205         activity.runOnUiThread(() -> {
206             ResolverDrawerLayout layout = (ResolverDrawerLayout)
207                     activity.findViewById(
208                             R.id.contentPanel);
209             layout.setShowAtTop(true);
210         });
211         waitForIdle();
212         assertThat("Drawer should show at top with new attribute",
213             profileView.getBottom() + divider.getHeight() == viewPager.getTop()
214                     && profileView.getTop() == 0);
215     }
216 
217     @Test
hasLastChosenActivity()218     public void hasLastChosenActivity() throws Exception {
219         Intent sendIntent = createSendImageIntent();
220         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
221                 PERSONAL_USER_HANDLE);
222         ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
223 
224         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
225                 Mockito.anyBoolean(),
226                 Mockito.anyBoolean(),
227                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
228         when(sOverrides.resolverListController.getLastChosen())
229                 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
230 
231         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
232         waitForIdle();
233 
234         // The other entry is filtered to the last used slot
235         assertThat(activity.getAdapter().getCount(), is(1));
236         assertThat(activity.getAdapter().getPlaceholderCount(), is(1));
237 
238         ResolveInfo[] chosen = new ResolveInfo[1];
239         sOverrides.onSafelyStartInternalCallback = result -> {
240             chosen[0] = result.first.getResolveInfo();
241             return true;
242         };
243 
244         onView(withId(R.id.button_once)).perform(click());
245         waitForIdle();
246         assertThat(chosen[0], is(toChoose));
247     }
248 
249     @Test
hasOtherProfileOneOption()250     public void hasOtherProfileOneOption() throws Exception {
251         // enable the work tab feature flag
252         ResolverActivity.ENABLE_TABBED_VIEW = true;
253         List<ResolvedComponentInfo> personalResolvedComponentInfos =
254                 createResolvedComponentsForTestWithOtherProfile(2, WORK_USER_ID,
255                         PERSONAL_USER_HANDLE);
256         markWorkProfileUserAvailable();
257         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
258                 sOverrides.workProfileUserHandle);
259         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
260 
261         ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0);
262         Intent sendIntent = createSendImageIntent();
263         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
264         Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
265         waitForIdle();
266 
267         // The other entry is filtered to the last used slot
268         assertThat(activity.getAdapter().getCount(), is(1));
269 
270         ResolveInfo[] chosen = new ResolveInfo[1];
271         sOverrides.onSafelyStartInternalCallback = result -> {
272             chosen[0] = result.first.getResolveInfo();
273             return true;
274         };
275         // Make a stable copy of the components as the original list may be modified
276         List<ResolvedComponentInfo> stableCopy =
277                 createResolvedComponentsForTestWithOtherProfile(2, WORK_USER_ID,
278                         PERSONAL_USER_HANDLE);
279         // We pick the first one as there is another one in the work profile side
280         onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)))
281                 .perform(click());
282         onView(withId(R.id.button_once))
283                 .perform(click());
284         waitForIdle();
285         assertThat(chosen[0], is(toChoose));
286     }
287 
288     @Test
hasOtherProfileTwoOptionsAndUserSelectsOne()289     public void hasOtherProfileTwoOptionsAndUserSelectsOne() throws Exception {
290         // enable the work tab feature flag
291         ResolverActivity.ENABLE_TABBED_VIEW = true;
292 
293         Intent sendIntent = createSendImageIntent();
294         List<ResolvedComponentInfo> resolvedComponentInfos =
295                 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
296         ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
297 
298         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
299                 Mockito.anyBoolean(),
300                 Mockito.anyBoolean(),
301                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
302 
303         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
304         Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
305         waitForIdle();
306 
307         // The other entry is filtered to the other profile slot
308         assertThat(activity.getAdapter().getCount(), is(2));
309 
310         ResolveInfo[] chosen = new ResolveInfo[1];
311         sOverrides.onSafelyStartInternalCallback = result -> {
312             chosen[0] = result.first.getResolveInfo();
313             return true;
314         };
315 
316         // Confirm that the button bar is disabled by default
317         onView(withId(R.id.button_once)).check(matches(not(isEnabled())));
318 
319         // Make a stable copy of the components as the original list may be modified
320         List<ResolvedComponentInfo> stableCopy =
321                 createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE);
322 
323         onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
324                 .perform(click());
325         onView(withId(R.id.button_once)).perform(click());
326         waitForIdle();
327         assertThat(chosen[0], is(toChoose));
328     }
329 
330 
331     @Test
hasLastChosenActivityAndOtherProfile()332     public void hasLastChosenActivityAndOtherProfile() throws Exception {
333         // enable the work tab feature flag
334         ResolverActivity.ENABLE_TABBED_VIEW = true;
335 
336         // In this case we prefer the other profile and don't display anything about the last
337         // chosen activity.
338         Intent sendIntent = createSendImageIntent();
339         List<ResolvedComponentInfo> resolvedComponentInfos =
340                 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
341         ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
342 
343         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
344                 Mockito.anyBoolean(),
345                 Mockito.anyBoolean(),
346                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
347         when(sOverrides.resolverListController.getLastChosen())
348                 .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0));
349 
350         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
351         Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
352         waitForIdle();
353 
354         // The other entry is filtered to the other profile slot
355         assertThat(activity.getAdapter().getCount(), is(2));
356 
357         ResolveInfo[] chosen = new ResolveInfo[1];
358         sOverrides.onSafelyStartInternalCallback = result -> {
359             chosen[0] = result.first.getResolveInfo();
360             return true;
361         };
362 
363         // Confirm that the button bar is disabled by default
364         onView(withId(R.id.button_once)).check(matches(not(isEnabled())));
365 
366         // Make a stable copy of the components as the original list may be modified
367         List<ResolvedComponentInfo> stableCopy =
368                 createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE);
369 
370         onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
371                 .perform(click());
372         onView(withId(R.id.button_once)).perform(click());
373         waitForIdle();
374         assertThat(chosen[0], is(toChoose));
375     }
376 
377     @Test
getActivityLabelAndSubLabel()378     public void getActivityLabelAndSubLabel() throws Exception {
379         ActivityInfoPresentationGetter pg;
380         PackageManagerMockedInfo info;
381 
382         info = createPackageManagerMockedInfo(false);
383         pg = new ActivityInfoPresentationGetter(
384                 info.ctx, 0, info.activityInfo);
385         assertThat("Label should match app label", pg.getLabel().equals(
386                 info.setAppLabel));
387         assertThat("Sublabel should match activity label if set",
388                 pg.getSubLabel().equals(info.setActivityLabel));
389 
390         info = createPackageManagerMockedInfo(true);
391         pg = new ActivityInfoPresentationGetter(
392                 info.ctx, 0, info.activityInfo);
393         assertThat("With override permission label should match activity label if set",
394                 pg.getLabel().equals(info.setActivityLabel));
395         assertThat("With override permission sublabel should be empty",
396                 TextUtils.isEmpty(pg.getSubLabel()));
397     }
398 
399     @Test
getResolveInfoLabelAndSubLabel()400     public void getResolveInfoLabelAndSubLabel() throws Exception {
401         ResolveInfoPresentationGetter pg;
402         PackageManagerMockedInfo info;
403 
404         info = createPackageManagerMockedInfo(false);
405         pg = new ResolveInfoPresentationGetter(
406                 info.ctx, 0, info.resolveInfo);
407         assertThat("Label should match app label", pg.getLabel().equals(
408                 info.setAppLabel));
409         assertThat("Sublabel should match resolve info label if set",
410                 pg.getSubLabel().equals(info.setResolveInfoLabel));
411 
412         info = createPackageManagerMockedInfo(true);
413         pg = new ResolveInfoPresentationGetter(
414                 info.ctx, 0, info.resolveInfo);
415         assertThat("With override permission label should match activity label if set",
416                 pg.getLabel().equals(info.setActivityLabel));
417         assertThat("With override permission the sublabel should be the resolve info label",
418                 pg.getSubLabel().equals(info.setResolveInfoLabel));
419     }
420 
421     @Test
testWorkTab_displayedWhenWorkProfileUserAvailable()422     public void testWorkTab_displayedWhenWorkProfileUserAvailable() {
423         // enable the work tab feature flag
424         ResolverActivity.ENABLE_TABBED_VIEW = true;
425         Intent sendIntent = createSendImageIntent();
426         markWorkProfileUserAvailable();
427 
428         mActivityRule.launchActivity(sendIntent);
429         waitForIdle();
430 
431         onView(withId(R.id.tabs)).check(matches(isDisplayed()));
432     }
433 
434     @Test
testWorkTab_hiddenWhenWorkProfileUserNotAvailable()435     public void testWorkTab_hiddenWhenWorkProfileUserNotAvailable() {
436         // enable the work tab feature flag
437         ResolverActivity.ENABLE_TABBED_VIEW = true;
438         Intent sendIntent = createSendImageIntent();
439 
440         mActivityRule.launchActivity(sendIntent);
441         waitForIdle();
442 
443         onView(withId(R.id.tabs)).check(matches(not(isDisplayed())));
444     }
445 
446     @Test
testWorkTab_workTabListPopulatedBeforeGoingToTab()447     public void testWorkTab_workTabListPopulatedBeforeGoingToTab() throws InterruptedException {
448         // enable the work tab feature flag
449         ResolverActivity.ENABLE_TABBED_VIEW = true;
450         List<ResolvedComponentInfo> personalResolvedComponentInfos =
451                 createResolvedComponentsForTestWithOtherProfile(3, WORK_USER_ID,
452                         PERSONAL_USER_HANDLE);
453         markWorkProfileUserAvailable();
454         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
455                 sOverrides.workProfileUserHandle);
456         setupResolverControllers(personalResolvedComponentInfos,
457                 new ArrayList<>(workResolvedComponentInfos));
458         Intent sendIntent = createSendImageIntent();
459 
460         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
461         waitForIdle();
462 
463         assertThat(activity.getCurrentUserHandle(), is(PERSONAL_USER_HANDLE));
464         // The work list adapter must be populated in advance before tapping the other tab
465         assertThat(activity.getWorkListAdapter().getCount(), is(4));
466     }
467 
468     @Test
testWorkTab_workTabUsesExpectedAdapter()469     public void testWorkTab_workTabUsesExpectedAdapter() {
470         // enable the work tab feature flag
471         ResolverActivity.ENABLE_TABBED_VIEW = true;
472         List<ResolvedComponentInfo> personalResolvedComponentInfos =
473                 createResolvedComponentsForTestWithOtherProfile(3, WORK_USER_ID,
474                         PERSONAL_USER_HANDLE);
475         markWorkProfileUserAvailable();
476         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
477                 sOverrides.workProfileUserHandle);
478         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
479         Intent sendIntent = createSendImageIntent();
480 
481         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
482         waitForIdle();
483         onView(withText(R.string.resolver_work_tab)).perform(click());
484 
485         assertThat(activity.getCurrentUserHandle().getIdentifier(), is(WORK_USER_ID));
486         assertThat(activity.getWorkListAdapter().getCount(), is(4));
487     }
488 
489     @Test
testWorkTab_personalTabUsesExpectedAdapter()490     public void testWorkTab_personalTabUsesExpectedAdapter() {
491         // enable the work tab feature flag
492         ResolverActivity.ENABLE_TABBED_VIEW = true;
493         List<ResolvedComponentInfo> personalResolvedComponentInfos =
494                 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
495         markWorkProfileUserAvailable();
496         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
497                 sOverrides.workProfileUserHandle);
498         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
499         Intent sendIntent = createSendImageIntent();
500 
501         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
502         waitForIdle();
503         onView(withText(R.string.resolver_work_tab)).perform(click());
504 
505         assertThat(activity.getCurrentUserHandle().getIdentifier(), is(WORK_USER_ID));
506         assertThat(activity.getPersonalListAdapter().getCount(), is(2));
507     }
508 
509     @Test
testWorkTab_workProfileHasExpectedNumberOfTargets()510     public void testWorkTab_workProfileHasExpectedNumberOfTargets() throws InterruptedException {
511         // enable the work tab feature flag
512         ResolverActivity.ENABLE_TABBED_VIEW = true;
513         markWorkProfileUserAvailable();
514         List<ResolvedComponentInfo> personalResolvedComponentInfos =
515                 createResolvedComponentsForTestWithOtherProfile(3, WORK_USER_ID,
516                         PERSONAL_USER_HANDLE);
517         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
518                 sOverrides.workProfileUserHandle);
519         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
520         Intent sendIntent = createSendImageIntent();
521 
522         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
523         waitForIdle();
524 
525         onView(withText(R.string.resolver_work_tab))
526                 .perform(click());
527         waitForIdle();
528         assertThat(activity.getWorkListAdapter().getCount(), is(4));
529     }
530 
531     @Test
testWorkTab_selectingWorkTabAppOpensAppInWorkProfile()532     public void testWorkTab_selectingWorkTabAppOpensAppInWorkProfile() throws InterruptedException {
533         // enable the work tab feature flag
534         ResolverActivity.ENABLE_TABBED_VIEW = true;
535         markWorkProfileUserAvailable();
536         List<ResolvedComponentInfo> personalResolvedComponentInfos =
537                 createResolvedComponentsForTestWithOtherProfile(3, WORK_USER_ID,
538                         PERSONAL_USER_HANDLE);
539         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
540                 sOverrides.workProfileUserHandle);
541         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
542         Intent sendIntent = createSendImageIntent();
543         ResolveInfo[] chosen = new ResolveInfo[1];
544         sOverrides.onSafelyStartInternalCallback = result -> {
545             chosen[0] = result.first.getResolveInfo();
546             return true;
547         };
548 
549         mActivityRule.launchActivity(sendIntent);
550         waitForIdle();
551         onView(withText(R.string.resolver_work_tab))
552                 .perform(click());
553         waitForIdle();
554         onView(first(allOf(withText(workResolvedComponentInfos.get(0)
555                 .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
556                 .perform(click());
557         onView(withId(R.id.button_once))
558                 .perform(click());
559 
560         waitForIdle();
561         assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0)));
562     }
563 
564     @Test
testWorkTab_noPersonalApps_workTabHasExpectedNumberOfTargets()565     public void testWorkTab_noPersonalApps_workTabHasExpectedNumberOfTargets()
566             throws InterruptedException {
567         // enable the work tab feature flag
568         ResolverActivity.ENABLE_TABBED_VIEW = true;
569         markWorkProfileUserAvailable();
570         List<ResolvedComponentInfo> personalResolvedComponentInfos =
571                 createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE);
572         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
573                 sOverrides.workProfileUserHandle);
574         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
575         Intent sendIntent = createSendImageIntent();
576 
577         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
578         waitForIdle();
579         onView(withText(R.string.resolver_work_tab))
580                 .perform(click());
581 
582         waitForIdle();
583         assertThat(activity.getWorkListAdapter().getCount(), is(4));
584     }
585 
586     @Test
testWorkTab_headerIsVisibleInPersonalTab()587     public void testWorkTab_headerIsVisibleInPersonalTab() {
588         // enable the work tab feature flag
589         ResolverActivity.ENABLE_TABBED_VIEW = true;
590         markWorkProfileUserAvailable();
591         List<ResolvedComponentInfo> personalResolvedComponentInfos =
592                 createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE);
593         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
594                 sOverrides.workProfileUserHandle);
595         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
596         Intent sendIntent = createOpenWebsiteIntent();
597 
598         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
599         waitForIdle();
600         TextView headerText = activity.findViewById(R.id.title);
601         String initialText = headerText.getText().toString();
602         assertFalse(initialText.isEmpty(), "Header text is empty.");
603         assertThat(headerText.getVisibility(), is(View.VISIBLE));
604     }
605 
606     @Test
testWorkTab_switchTabs_headerStaysSame()607     public void testWorkTab_switchTabs_headerStaysSame() {
608         // enable the work tab feature flag
609         ResolverActivity.ENABLE_TABBED_VIEW = true;
610         markWorkProfileUserAvailable();
611         List<ResolvedComponentInfo> personalResolvedComponentInfos =
612                 createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE);
613         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
614                 sOverrides.workProfileUserHandle);
615         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
616         Intent sendIntent = createOpenWebsiteIntent();
617 
618         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
619         waitForIdle();
620         TextView headerText = activity.findViewById(R.id.title);
621         String initialText = headerText.getText().toString();
622         onView(withText(R.string.resolver_work_tab))
623                 .perform(click());
624 
625         waitForIdle();
626         String currentText = headerText.getText().toString();
627         assertThat(headerText.getVisibility(), is(View.VISIBLE));
628         assertThat(String.format("Header text is not the same when switching tabs, personal profile"
629                         + " header was %s but work profile header is %s", initialText, currentText),
630                 TextUtils.equals(initialText, currentText));
631     }
632 
633     @Test
testWorkTab_noPersonalApps_canStartWorkApps()634     public void testWorkTab_noPersonalApps_canStartWorkApps()
635             throws InterruptedException {
636         // enable the work tab feature flag
637         ResolverActivity.ENABLE_TABBED_VIEW = true;
638         markWorkProfileUserAvailable();
639         List<ResolvedComponentInfo> personalResolvedComponentInfos =
640                 createResolvedComponentsForTestWithOtherProfile(3, WORK_USER_ID,
641                         PERSONAL_USER_HANDLE);
642         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
643                 sOverrides.workProfileUserHandle);
644         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
645         Intent sendIntent = createSendImageIntent();
646         ResolveInfo[] chosen = new ResolveInfo[1];
647         sOverrides.onSafelyStartInternalCallback = result -> {
648             chosen[0] = result.first.getResolveInfo();
649             return true;
650         };
651 
652         mActivityRule.launchActivity(sendIntent);
653         waitForIdle();
654         onView(withText(R.string.resolver_work_tab))
655                 .perform(click());
656         waitForIdle();
657         onView(first(allOf(
658                 withText(workResolvedComponentInfos.get(0)
659                         .getResolveInfoAt(0).activityInfo.applicationInfo.name),
660                 isDisplayed())))
661                 .perform(click());
662         onView(withId(R.id.button_once))
663                 .perform(click());
664         waitForIdle();
665 
666         assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0)));
667     }
668 
669     @Test
testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown()670     public void testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown() {
671         // enable the work tab feature flag
672         ResolverActivity.ENABLE_TABBED_VIEW = true;
673         markWorkProfileUserAvailable();
674         int workProfileTargets = 4;
675         List<ResolvedComponentInfo> personalResolvedComponentInfos =
676                 createResolvedComponentsForTestWithOtherProfile(3, WORK_USER_ID,
677                         PERSONAL_USER_HANDLE);
678         List<ResolvedComponentInfo> workResolvedComponentInfos =
679                 createResolvedComponentsForTest(workProfileTargets,
680                         sOverrides.workProfileUserHandle);
681         sOverrides.hasCrossProfileIntents = false;
682         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
683         Intent sendIntent = createSendImageIntent();
684         sendIntent.setType("TestType");
685 
686         mActivityRule.launchActivity(sendIntent);
687         waitForIdle();
688         onView(withText(R.string.resolver_work_tab)).perform(click());
689         waitForIdle();
690         onView(withId(R.id.contentPanel))
691                 .perform(swipeUp());
692 
693         onView(withText(R.string.resolver_cross_profile_blocked))
694                 .check(matches(isDisplayed()));
695     }
696 
697     @Test
testWorkTab_workProfileDisabled_emptyStateShown()698     public void testWorkTab_workProfileDisabled_emptyStateShown() {
699         // enable the work tab feature flag
700         ResolverActivity.ENABLE_TABBED_VIEW = true;
701         markWorkProfileUserAvailable();
702         int workProfileTargets = 4;
703         List<ResolvedComponentInfo> personalResolvedComponentInfos =
704                 createResolvedComponentsForTestWithOtherProfile(3, WORK_USER_ID,
705                         PERSONAL_USER_HANDLE);
706         List<ResolvedComponentInfo> workResolvedComponentInfos =
707                 createResolvedComponentsForTest(workProfileTargets,
708                         sOverrides.workProfileUserHandle);
709         sOverrides.isQuietModeEnabled = true;
710         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
711         Intent sendIntent = createSendImageIntent();
712         sendIntent.setType("TestType");
713 
714         mActivityRule.launchActivity(sendIntent);
715         waitForIdle();
716         onView(withId(R.id.contentPanel))
717                 .perform(swipeUp());
718         onView(withText(R.string.resolver_work_tab)).perform(click());
719         waitForIdle();
720 
721         onView(withText(R.string.resolver_turn_on_work_apps))
722                 .check(matches(isDisplayed()));
723     }
724 
725     @Test
testWorkTab_noWorkAppsAvailable_emptyStateShown()726     public void testWorkTab_noWorkAppsAvailable_emptyStateShown() {
727         // enable the work tab feature flag
728         ResolverActivity.ENABLE_TABBED_VIEW = true;
729         markWorkProfileUserAvailable();
730         List<ResolvedComponentInfo> personalResolvedComponentInfos =
731                 createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE);
732         List<ResolvedComponentInfo> workResolvedComponentInfos =
733                 createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle);
734         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
735         Intent sendIntent = createSendImageIntent();
736         sendIntent.setType("TestType");
737 
738         mActivityRule.launchActivity(sendIntent);
739         waitForIdle();
740         onView(withId(R.id.contentPanel))
741                 .perform(swipeUp());
742         onView(withText(R.string.resolver_work_tab)).perform(click());
743         waitForIdle();
744 
745         onView(withText(R.string.resolver_no_work_apps_available))
746                 .check(matches(isDisplayed()));
747     }
748 
749     @Test
testWorkTab_xProfileOff_noAppsAvailable_workOff_xProfileOffEmptyStateShown()750     public void testWorkTab_xProfileOff_noAppsAvailable_workOff_xProfileOffEmptyStateShown() {
751         // enable the work tab feature flag
752         ResolverActivity.ENABLE_TABBED_VIEW = true;
753         markWorkProfileUserAvailable();
754         List<ResolvedComponentInfo> personalResolvedComponentInfos =
755                 createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE);
756         List<ResolvedComponentInfo> workResolvedComponentInfos =
757                 createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle);
758         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
759         Intent sendIntent = createSendImageIntent();
760         sendIntent.setType("TestType");
761         sOverrides.isQuietModeEnabled = true;
762         sOverrides.hasCrossProfileIntents = false;
763 
764         mActivityRule.launchActivity(sendIntent);
765         waitForIdle();
766         onView(withId(R.id.contentPanel))
767                 .perform(swipeUp());
768         onView(withText(R.string.resolver_work_tab)).perform(click());
769         waitForIdle();
770 
771         onView(withText(R.string.resolver_cross_profile_blocked))
772                 .check(matches(isDisplayed()));
773     }
774 
775     @Test
testMiniResolver()776     public void testMiniResolver() {
777         ResolverActivity.ENABLE_TABBED_VIEW = true;
778         markWorkProfileUserAvailable();
779         List<ResolvedComponentInfo> personalResolvedComponentInfos =
780                 createResolvedComponentsForTest(1, PERSONAL_USER_HANDLE);
781         List<ResolvedComponentInfo> workResolvedComponentInfos =
782                 createResolvedComponentsForTest(1, sOverrides.workProfileUserHandle);
783         // Personal profile only has a browser
784         personalResolvedComponentInfos.get(0).getResolveInfoAt(0).handleAllWebDataURI = true;
785         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
786         Intent sendIntent = createSendImageIntent();
787         sendIntent.setType("TestType");
788 
789         mActivityRule.launchActivity(sendIntent);
790         waitForIdle();
791         onView(withId(R.id.open_cross_profile)).check(matches(isDisplayed()));
792     }
793 
794     @Test
testMiniResolver_noCurrentProfileTarget()795     public void testMiniResolver_noCurrentProfileTarget() {
796         ResolverActivity.ENABLE_TABBED_VIEW = true;
797         markWorkProfileUserAvailable();
798         List<ResolvedComponentInfo> personalResolvedComponentInfos =
799                 createResolvedComponentsForTest(0, PERSONAL_USER_HANDLE);
800         List<ResolvedComponentInfo> workResolvedComponentInfos =
801                 createResolvedComponentsForTest(1, sOverrides.workProfileUserHandle);
802         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
803         Intent sendIntent = createSendImageIntent();
804         sendIntent.setType("TestType");
805 
806         mActivityRule.launchActivity(sendIntent);
807         waitForIdle();
808 
809         // Need to ensure mini resolver doesn't trigger here.
810         assertNotMiniResolver();
811     }
812 
assertNotMiniResolver()813     private void assertNotMiniResolver() {
814         try {
815             onView(withId(R.id.open_cross_profile)).check(matches(isDisplayed()));
816         } catch (NoMatchingViewException e) {
817             return;
818         }
819         fail("Mini resolver present but shouldn't be");
820     }
821 
822     @Test
testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown()823     public void testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown() {
824         // enable the work tab feature flag
825         ResolverActivity.ENABLE_TABBED_VIEW = true;
826         markWorkProfileUserAvailable();
827         List<ResolvedComponentInfo> personalResolvedComponentInfos =
828                 createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE);
829         List<ResolvedComponentInfo> workResolvedComponentInfos =
830                 createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle);
831         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
832         Intent sendIntent = createSendImageIntent();
833         sendIntent.setType("TestType");
834         sOverrides.isQuietModeEnabled = true;
835 
836         mActivityRule.launchActivity(sendIntent);
837         waitForIdle();
838         onView(withId(R.id.contentPanel))
839                 .perform(swipeUp());
840         onView(withText(R.string.resolver_work_tab)).perform(click());
841         waitForIdle();
842 
843         onView(withText(R.string.resolver_no_work_apps_available))
844                 .check(matches(isDisplayed()));
845     }
846 
847     @Test
testAutolaunch_singleTarget_withWorkProfileAndTabbedViewOff_noAutolaunch()848     public void testAutolaunch_singleTarget_withWorkProfileAndTabbedViewOff_noAutolaunch() {
849         ResolverActivity.ENABLE_TABBED_VIEW = false;
850         List<ResolvedComponentInfo> personalResolvedComponentInfos =
851                 createResolvedComponentsForTestWithOtherProfile(2, WORK_USER_ID,
852                         PERSONAL_USER_HANDLE);
853         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
854                 Mockito.anyBoolean(),
855                 Mockito.anyBoolean(),
856                 Mockito.isA(List.class)))
857                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
858         Intent sendIntent = createSendImageIntent();
859         sendIntent.setType("TestType");
860         ResolveInfo[] chosen = new ResolveInfo[1];
861         sOverrides.onSafelyStartInternalCallback = result -> {
862             chosen[0] = result.first.getResolveInfo();
863             return true;
864         };
865         waitForIdle();
866 
867         mActivityRule.launchActivity(sendIntent);
868         waitForIdle();
869 
870         assertTrue(chosen[0] == null);
871     }
872 
873     @Test
testAutolaunch_singleTarget_noWorkProfile_autolaunch()874     public void testAutolaunch_singleTarget_noWorkProfile_autolaunch() {
875         ResolverActivity.ENABLE_TABBED_VIEW = false;
876         List<ResolvedComponentInfo> personalResolvedComponentInfos =
877                 createResolvedComponentsForTest(1, PERSONAL_USER_HANDLE);
878         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
879                 Mockito.anyBoolean(),
880                 Mockito.anyBoolean(),
881                 Mockito.isA(List.class)))
882                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
883         Intent sendIntent = createSendImageIntent();
884         sendIntent.setType("TestType");
885         ResolveInfo[] chosen = new ResolveInfo[1];
886         sOverrides.onSafelyStartInternalCallback = result -> {
887             chosen[0] = result.first.getResolveInfo();
888             return true;
889         };
890         waitForIdle();
891 
892         mActivityRule.launchActivity(sendIntent);
893         waitForIdle();
894 
895         assertThat(chosen[0], is(personalResolvedComponentInfos.get(0).getResolveInfoAt(0)));
896     }
897 
898     @Test
testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_autolaunch()899     public void testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_autolaunch() {
900         // enable the work tab feature flag
901         ResolverActivity.ENABLE_TABBED_VIEW = true;
902         markWorkProfileUserAvailable();
903         int workProfileTargets = 4;
904         List<ResolvedComponentInfo> personalResolvedComponentInfos =
905                 createResolvedComponentsForTestWithOtherProfile(2, WORK_USER_ID,
906                         PERSONAL_USER_HANDLE);
907         List<ResolvedComponentInfo> workResolvedComponentInfos =
908                 createResolvedComponentsForTest(workProfileTargets,
909                         sOverrides.workProfileUserHandle);
910         sOverrides.hasCrossProfileIntents = false;
911         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
912         Intent sendIntent = createSendImageIntent();
913         sendIntent.setType("TestType");
914         ResolveInfo[] chosen = new ResolveInfo[1];
915         sOverrides.onSafelyStartInternalCallback = result -> {
916             chosen[0] = result.first.getResolveInfo();
917             return true;
918         };
919 
920         mActivityRule.launchActivity(sendIntent);
921         waitForIdle();
922 
923         assertThat(chosen[0], is(personalResolvedComponentInfos.get(1).getResolveInfoAt(0)));
924     }
925 
926     @Test
testLayoutWithDefault_withWorkTab_neverShown()927     public void testLayoutWithDefault_withWorkTab_neverShown() throws RemoteException {
928         // enable the work tab feature flag
929         ResolverActivity.ENABLE_TABBED_VIEW = true;
930         markWorkProfileUserAvailable();
931 
932         // In this case we prefer the other profile and don't display anything about the last
933         // chosen activity.
934         Intent sendIntent = createSendImageIntent();
935         List<ResolvedComponentInfo> resolvedComponentInfos =
936                 createResolvedComponentsForTest(2, PERSONAL_USER_HANDLE);
937 
938         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
939                 Mockito.anyBoolean(),
940                 Mockito.anyBoolean(),
941                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
942         when(sOverrides.resolverListController.getLastChosen())
943                 .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0));
944 
945         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
946         Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
947         waitForIdle();
948 
949         // The other entry is filtered to the last used slot
950         assertThat(activity.getAdapter().hasFilteredItem(), is(false));
951         assertThat(activity.getAdapter().getCount(), is(2));
952         assertThat(activity.getAdapter().getPlaceholderCount(), is(2));
953     }
954 
955     @Test
testClonedProfilePresent_personalAdapterIsSetWithPersonalProfile()956     public void testClonedProfilePresent_personalAdapterIsSetWithPersonalProfile() {
957         // enable cloneProfile
958         markCloneProfileUserAvailable();
959         List<ResolvedComponentInfo> resolvedComponentInfos =
960                 createResolvedComponentsWithCloneProfileForTest(
961                         3,
962                         PERSONAL_USER_HANDLE,
963                         sOverrides.cloneProfileUserHandle);
964         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
965                 Mockito.anyBoolean(),
966                 Mockito.anyBoolean(),
967                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
968         Intent sendIntent = createSendImageIntent();
969 
970         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
971         waitForIdle();
972 
973         assertThat(activity.getCurrentUserHandle(), is(activity.getPersonalProfileUserHandle()));
974         assertThat(activity.getAdapter().getCount(), is(3));
975     }
976 
977     @Test
testClonedProfilePresent_personalTabUsesExpectedAdapter()978     public void testClonedProfilePresent_personalTabUsesExpectedAdapter() {
979         // enable the work tab feature flag
980         ResolverActivity.ENABLE_TABBED_VIEW = true;
981         markWorkProfileUserAvailable();
982         // enable cloneProfile
983         markCloneProfileUserAvailable();
984         List<ResolvedComponentInfo> personalResolvedComponentInfos =
985                 createResolvedComponentsWithCloneProfileForTest(
986                         3,
987                         PERSONAL_USER_HANDLE,
988                         sOverrides.cloneProfileUserHandle);
989         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
990                 sOverrides.workProfileUserHandle);
991         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
992         Intent sendIntent = createSendImageIntent();
993 
994         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
995         waitForIdle();
996 
997         assertThat(activity.getCurrentUserHandle(), is(activity.getPersonalProfileUserHandle()));
998         assertThat(activity.getAdapter().getCount(), is(3));
999     }
1000 
1001     @Test
testClonedProfilePresent_layoutWithDefault_neverShown()1002     public void testClonedProfilePresent_layoutWithDefault_neverShown() throws Exception {
1003         // enable cloneProfile
1004         markCloneProfileUserAvailable();
1005         Intent sendIntent = createSendImageIntent();
1006         List<ResolvedComponentInfo> resolvedComponentInfos =
1007                 createResolvedComponentsWithCloneProfileForTest(
1008                         2,
1009                 PERSONAL_USER_HANDLE,
1010                         sOverrides.cloneProfileUserHandle);
1011 
1012         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1013                 Mockito.anyBoolean(),
1014                 Mockito.anyBoolean(),
1015                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1016         when(sOverrides.resolverListController.getLastChosen())
1017                 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
1018 
1019         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1020         Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
1021         waitForIdle();
1022 
1023         assertThat(activity.getAdapter().hasFilteredItem(), is(false));
1024         assertThat(activity.getAdapter().getCount(), is(2));
1025         assertThat(activity.getAdapter().getPlaceholderCount(), is(2));
1026     }
1027 
1028     @Test
testClonedProfilePresent_alwaysButtonDisabled()1029     public void testClonedProfilePresent_alwaysButtonDisabled() throws Exception {
1030         // enable cloneProfile
1031         markCloneProfileUserAvailable();
1032         Intent sendIntent = createSendImageIntent();
1033         List<ResolvedComponentInfo> resolvedComponentInfos =
1034                 createResolvedComponentsWithCloneProfileForTest(
1035                         3,
1036                         PERSONAL_USER_HANDLE,
1037                         sOverrides.cloneProfileUserHandle);
1038 
1039         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1040                 Mockito.anyBoolean(),
1041                 Mockito.anyBoolean(),
1042                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1043         when(sOverrides.resolverListController.getLastChosen())
1044                 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
1045 
1046         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1047         waitForIdle();
1048 
1049         // Confirm that the button bar is disabled by default
1050         onView(withId(R.id.button_once)).check(matches(not(isEnabled())));
1051         onView(withId(R.id.button_always)).check(matches(not(isEnabled())));
1052 
1053         // Make a stable copy of the components as the original list may be modified
1054         List<ResolvedComponentInfo> stableCopy =
1055                 createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE);
1056 
1057         onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
1058                 .perform(click());
1059 
1060         onView(withId(R.id.button_once)).check(matches(isEnabled()));
1061         onView(withId(R.id.button_always)).check(matches(not(isEnabled())));
1062     }
1063 
1064     @Test
testClonedProfilePresent_personalProfileActivityIsStartedInCorrectUser()1065     public void testClonedProfilePresent_personalProfileActivityIsStartedInCorrectUser()
1066             throws Exception {
1067         // enable the work tab feature flag
1068         ResolverActivity.ENABLE_TABBED_VIEW = true;
1069         markWorkProfileUserAvailable();
1070         // enable cloneProfile
1071         markCloneProfileUserAvailable();
1072 
1073         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1074                 createResolvedComponentsWithCloneProfileForTest(
1075                         3,
1076                         PERSONAL_USER_HANDLE,
1077                         sOverrides.cloneProfileUserHandle);
1078         List<ResolvedComponentInfo> workResolvedComponentInfos =
1079                 createResolvedComponentsForTest(3, sOverrides.workProfileUserHandle);
1080         sOverrides.hasCrossProfileIntents = false;
1081         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1082         Intent sendIntent = createSendImageIntent();
1083         sendIntent.setType("TestType");
1084         final UserHandle[] selectedActivityUserHandle = new UserHandle[1];
1085         sOverrides.onSafelyStartInternalCallback = result -> {
1086             selectedActivityUserHandle[0] = result.second;
1087             return true;
1088         };
1089 
1090         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1091         waitForIdle();
1092         onView(first(allOf(withText(personalResolvedComponentInfos.get(0)
1093                 .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
1094                 .perform(click());
1095         onView(withId(R.id.button_once))
1096                 .perform(click());
1097         waitForIdle();
1098 
1099         assertThat(selectedActivityUserHandle[0], is(activity.getAdapter().getUserHandle()));
1100     }
1101 
1102     @Test
testClonedProfilePresent_workProfileActivityIsStartedInCorrectUser()1103     public void testClonedProfilePresent_workProfileActivityIsStartedInCorrectUser()
1104             throws Exception {
1105         // enable the work tab feature flag
1106         ResolverActivity.ENABLE_TABBED_VIEW = true;
1107         markWorkProfileUserAvailable();
1108         // enable cloneProfile
1109         markCloneProfileUserAvailable();
1110 
1111         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1112                 createResolvedComponentsWithCloneProfileForTest(
1113                         3,
1114                         PERSONAL_USER_HANDLE,
1115                         sOverrides.cloneProfileUserHandle);
1116         List<ResolvedComponentInfo> workResolvedComponentInfos =
1117                 createResolvedComponentsForTest(3, sOverrides.workProfileUserHandle);
1118         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1119         Intent sendIntent = createSendImageIntent();
1120         sendIntent.setType("TestType");
1121         final UserHandle[] selectedActivityUserHandle = new UserHandle[1];
1122         sOverrides.onSafelyStartInternalCallback = result -> {
1123             selectedActivityUserHandle[0] = result.second;
1124             return true;
1125         };
1126 
1127         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1128         waitForIdle();
1129         onView(withText(R.string.resolver_work_tab))
1130                 .perform(click());
1131         waitForIdle();
1132         onView(first(allOf(withText(workResolvedComponentInfos.get(0)
1133                 .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
1134                 .perform(click());
1135         onView(withId(R.id.button_once))
1136                 .perform(click());
1137         waitForIdle();
1138 
1139         assertThat(selectedActivityUserHandle[0], is(activity.getAdapter().getUserHandle()));
1140     }
1141 
1142     @Test
testClonedProfilePresent_personalProfileResolverComparatorHasCorrectUsers()1143     public void testClonedProfilePresent_personalProfileResolverComparatorHasCorrectUsers()
1144             throws Exception {
1145         // enable cloneProfile
1146         markCloneProfileUserAvailable();
1147         List<ResolvedComponentInfo> resolvedComponentInfos =
1148                 createResolvedComponentsWithCloneProfileForTest(
1149                         3,
1150                         PERSONAL_USER_HANDLE,
1151                         sOverrides.cloneProfileUserHandle);
1152         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1153                 Mockito.anyBoolean(),
1154                 Mockito.anyBoolean(),
1155                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1156         Intent sendIntent = createSendImageIntent();
1157 
1158         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1159         waitForIdle();
1160         List<UserHandle> result = activity
1161                 .getResolverRankerServiceUserHandleList(PERSONAL_USER_HANDLE);
1162 
1163         assertTrue(result.containsAll(Lists.newArrayList(PERSONAL_USER_HANDLE,
1164                 sOverrides.cloneProfileUserHandle)));
1165     }
1166 
1167     @Test
testTriggerFromPrivateProfile_withoutWorkProfile()1168     public void testTriggerFromPrivateProfile_withoutWorkProfile() throws RemoteException {
1169         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1170                 android.multiuser.Flags.FLAG_ALLOW_RESOLVER_SHEET_FOR_PRIVATE_SPACE,
1171                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1172         markPrivateProfileUserAvailable();
1173         Intent sendIntent = createSendImageIntent();
1174         List<ResolvedComponentInfo> privateResolvedComponentInfos =
1175                 createResolvedComponentsForTest(3, sOverrides.privateProfileUserHandle);
1176         setupResolverControllers(privateResolvedComponentInfos);
1177         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1178         waitForIdle();
1179         onView(withId(R.id.tabs)).check(matches(not(isDisplayed())));
1180         assertThat(activity.getPersonalListAdapter().getCount(), is(3));
1181         onView(withId(R.id.button_once)).check(matches(not(isEnabled())));
1182         onView(withId(R.id.button_always)).check(matches(not(isEnabled())));
1183         for (ResolvedComponentInfo resolvedInfo : privateResolvedComponentInfos) {
1184             assertEquals(resolvedInfo.getResolveInfoAt(0).userHandle,
1185                     sOverrides.privateProfileUserHandle);
1186         }
1187     }
1188 
1189     @Test
testTriggerFromPrivateProfile_withWorkProfilePresent()1190     public void testTriggerFromPrivateProfile_withWorkProfilePresent(){
1191         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1192                 android.multiuser.Flags.FLAG_ALLOW_RESOLVER_SHEET_FOR_PRIVATE_SPACE,
1193                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1194         ResolverActivity.ENABLE_TABBED_VIEW = false;
1195         markPrivateProfileUserAvailable();
1196         markWorkProfileUserAvailable();
1197         Intent sendIntent = createSendImageIntent();
1198         List<ResolvedComponentInfo> privateResolvedComponentInfos =
1199                 createResolvedComponentsForTest(3, sOverrides.privateProfileUserHandle);
1200         setupResolverControllers(privateResolvedComponentInfos);
1201         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1202         waitForIdle();
1203         assertThat(activity.getPersonalListAdapter().getCount(), is(3));
1204         onView(withId(R.id.tabs)).check(matches(not(isDisplayed())));
1205         assertEquals(activity.getMultiProfilePagerAdapterCount(), 1);
1206         for (ResolvedComponentInfo resolvedInfo : privateResolvedComponentInfos) {
1207             assertEquals(resolvedInfo.getResolveInfoAt(0).userHandle,
1208                     sOverrides.privateProfileUserHandle);
1209         }
1210     }
1211 
1212     @Test
testPrivateProfile_triggerFromPrimaryUser_withWorkProfilePresent()1213     public void testPrivateProfile_triggerFromPrimaryUser_withWorkProfilePresent(){
1214         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1215                 android.multiuser.Flags.FLAG_ALLOW_RESOLVER_SHEET_FOR_PRIVATE_SPACE,
1216                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1217         markPrivateProfileUserAvailable();
1218         markWorkProfileUserAvailable();
1219         Intent sendIntent = createSendImageIntent();
1220         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1221                 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
1222         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
1223                 sOverrides.workProfileUserHandle);
1224         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1225         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1226         waitForIdle();
1227         assertThat(activity.getAdapter().getCount(), is(2));
1228         assertThat(activity.getWorkListAdapter().getCount(), is(4));
1229         onView(withId(R.id.tabs)).check(matches(isDisplayed()));
1230         for (ResolvedComponentInfo resolvedInfo : personalResolvedComponentInfos) {
1231             assertEquals(resolvedInfo.getResolveInfoAt(0).userHandle,
1232                     activity.getPersonalProfileUserHandle());
1233         }
1234     }
1235 
1236     @Test
testPrivateProfile_triggerFromWorkProfile()1237     public void testPrivateProfile_triggerFromWorkProfile(){
1238         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1239                 android.multiuser.Flags.FLAG_ALLOW_RESOLVER_SHEET_FOR_PRIVATE_SPACE,
1240                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1241         markPrivateProfileUserAvailable();
1242         markWorkProfileUserAvailable();
1243         Intent sendIntent = createSendImageIntent();
1244 
1245         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1246                 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
1247         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
1248                 sOverrides.workProfileUserHandle);
1249         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1250         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1251         waitForIdle();
1252         assertThat(activity.getAdapter().getCount(), is(2));
1253         assertThat(activity.getWorkListAdapter().getCount(), is(4));
1254         onView(withId(R.id.tabs)).check(matches(isDisplayed()));
1255         for (ResolvedComponentInfo resolvedInfo : personalResolvedComponentInfos) {
1256             assertTrue(resolvedInfo.getResolveInfoAt(0).userHandle.equals(
1257                     activity.getPersonalProfileUserHandle()) || resolvedInfo.getResolveInfoAt(
1258                     0).userHandle.equals(activity.getWorkProfileUserHandle()));
1259         }
1260     }
1261 
1262     @Test
testTriggerFromMainProfile_inSingleUserMode_withWorkProfilePresent()1263     public void testTriggerFromMainProfile_inSingleUserMode_withWorkProfilePresent() {
1264         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1265                 android.multiuser.Flags.FLAG_ALLOW_RESOLVER_SHEET_FOR_PRIVATE_SPACE,
1266                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1267         markWorkProfileUserAvailable();
1268         setTabOwnerUserHandleForLaunch(PERSONAL_USER_HANDLE);
1269         Intent sendIntent = createSendImageIntent();
1270         sendIntent.putExtra(EXTRA_RESTRICT_TO_SINGLE_USER, true);
1271         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1272                 createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
1273         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
1274                 sOverrides.workProfileUserHandle);
1275         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1276         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1277         waitForIdle();
1278         assertThat(activity.getPersonalListAdapter().getCount(), is(2));
1279         onView(withId(R.id.tabs)).check(matches(not(isDisplayed())));
1280         assertEquals(activity.getMultiProfilePagerAdapterCount(), 1);
1281         for (ResolvedComponentInfo resolvedInfo : personalResolvedComponentInfos) {
1282             assertEquals(resolvedInfo.getResolveInfoAt(0).userHandle, PERSONAL_USER_HANDLE);
1283         }
1284     }
1285 
1286     @Test
testTriggerFromWorkProfile_inSingleUserMode()1287     public void testTriggerFromWorkProfile_inSingleUserMode() {
1288         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1289                 android.multiuser.Flags.FLAG_ALLOW_RESOLVER_SHEET_FOR_PRIVATE_SPACE,
1290                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1291         markWorkProfileUserAvailable();
1292         setTabOwnerUserHandleForLaunch(sOverrides.workProfileUserHandle);
1293         Intent sendIntent = createSendImageIntent();
1294         sendIntent.putExtra(EXTRA_RESTRICT_TO_SINGLE_USER, true);
1295         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1296                 createResolvedComponentsForTest(3, sOverrides.workProfileUserHandle);
1297         setupResolverControllers(personalResolvedComponentInfos);
1298         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
1299         waitForIdle();
1300         assertThat(activity.getPersonalListAdapter().getCount(), is(3));
1301         onView(withId(R.id.tabs)).check(matches(not(isDisplayed())));
1302         assertEquals(activity.getMultiProfilePagerAdapterCount(), 1);
1303         for (ResolvedComponentInfo resolvedInfo : personalResolvedComponentInfos) {
1304             assertEquals(resolvedInfo.getResolveInfoAt(0).userHandle,
1305                     sOverrides.workProfileUserHandle);
1306         }
1307     }
1308 
createSendImageIntent()1309     private Intent createSendImageIntent() {
1310         Intent sendIntent = new Intent();
1311         sendIntent.setAction(Intent.ACTION_SEND);
1312         sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
1313         sendIntent.setType("image/jpeg");
1314         return sendIntent;
1315     }
1316 
createOpenWebsiteIntent()1317     private Intent createOpenWebsiteIntent() {
1318         Intent sendIntent = new Intent();
1319         sendIntent.setAction(Intent.ACTION_VIEW);
1320         sendIntent.setData(Uri.parse("https://google.com"));
1321         return sendIntent;
1322     }
1323 
createResolvedComponentsForTest(int numberOfResults, UserHandle resolvedForUser)1324     private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults,
1325             UserHandle resolvedForUser) {
1326         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
1327         for (int i = 0; i < numberOfResults; i++) {
1328             infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
1329         }
1330         return infoList;
1331     }
1332 
createResolvedComponentsWithCloneProfileForTest( int numberOfResults, UserHandle resolvedForPersonalUser, UserHandle resolvedForClonedUser)1333     private List<ResolvedComponentInfo> createResolvedComponentsWithCloneProfileForTest(
1334             int numberOfResults,
1335             UserHandle resolvedForPersonalUser,
1336             UserHandle resolvedForClonedUser) {
1337         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
1338         for (int i = 0; i < 1; i++) {
1339             infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
1340                     resolvedForPersonalUser));
1341         }
1342         for (int i = 1; i < numberOfResults; i++) {
1343             infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
1344                     resolvedForClonedUser));
1345         }
1346         return infoList;
1347     }
1348 
createResolvedComponentsForTestWithOtherProfile( int numberOfResults, UserHandle resolvedForUser)1349     private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
1350             int numberOfResults, UserHandle resolvedForUser) {
1351         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
1352         for (int i = 0; i < numberOfResults; i++) {
1353             if (i == 0) {
1354                 infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i,
1355                         resolvedForUser));
1356             } else {
1357                 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
1358             }
1359         }
1360         return infoList;
1361     }
1362 
createResolvedComponentsForTestWithOtherProfile( int numberOfResults, int userId, UserHandle resolvedForUser)1363     private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
1364             int numberOfResults, int userId, UserHandle resolvedForUser) {
1365         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
1366         for (int i = 0; i < numberOfResults; i++) {
1367             if (i == 0) {
1368                 infoList.add(
1369                         ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId,
1370                                 resolvedForUser));
1371             } else {
1372                 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
1373             }
1374         }
1375         return infoList;
1376     }
1377 
waitForIdle()1378     private void waitForIdle() {
1379         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
1380     }
1381 
markWorkProfileUserAvailable()1382     private void markWorkProfileUserAvailable() {
1383         ResolverWrapperActivity.sOverrides.workProfileUserHandle = UserHandle.of(WORK_USER_ID);
1384     }
1385 
markCloneProfileUserAvailable()1386     private void markCloneProfileUserAvailable() {
1387         ResolverWrapperActivity.sOverrides.cloneProfileUserHandle = UserHandle.of(CLONE_USER_ID);
1388     }
1389 
markPrivateProfileUserAvailable()1390     private void markPrivateProfileUserAvailable() {
1391         ResolverWrapperActivity.sOverrides.privateProfileUserHandle =
1392                 UserHandle.of(PRIVATE_USER_ID);
1393     }
1394 
setTabOwnerUserHandleForLaunch(UserHandle tabOwnerUserHandleForLaunch)1395     private void setTabOwnerUserHandleForLaunch(UserHandle tabOwnerUserHandleForLaunch) {
1396         sOverrides.tabOwnerUserHandleForLaunch = tabOwnerUserHandleForLaunch;
1397     }
1398 
setupResolverControllers( List<ResolvedComponentInfo> personalResolvedComponentInfos, List<ResolvedComponentInfo> workResolvedComponentInfos)1399     private void setupResolverControllers(
1400             List<ResolvedComponentInfo> personalResolvedComponentInfos,
1401             List<ResolvedComponentInfo> workResolvedComponentInfos) {
1402         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1403                 Mockito.anyBoolean(),
1404                 Mockito.anyBoolean(),
1405                 Mockito.isA(List.class)))
1406                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
1407         when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
1408                 Mockito.anyBoolean(),
1409                 Mockito.anyBoolean(),
1410                 Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
1411         when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
1412                 Mockito.anyBoolean(),
1413                 Mockito.anyBoolean(),
1414                 Mockito.isA(List.class),
1415                 eq(UserHandle.SYSTEM)))
1416                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
1417     }
1418 
setupResolverControllers( List<ResolvedComponentInfo> resolvedComponentInfos)1419     private void setupResolverControllers(
1420             List<ResolvedComponentInfo> resolvedComponentInfos) {
1421         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1422                 Mockito.anyBoolean(),
1423                 Mockito.anyBoolean(),
1424                 Mockito.isA(List.class)))
1425                 .thenReturn(new ArrayList<>(resolvedComponentInfos));
1426     }
1427 }
1428