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.doesNotExist;
23 import static androidx.test.espresso.assertion.ViewAssertions.matches;
24 import static androidx.test.espresso.matcher.ViewMatchers.hasSibling;
25 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
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.ChooserActivity.TARGET_TYPE_CHOOSER_TARGET;
30 import static com.android.internal.app.ChooserActivity.TARGET_TYPE_DEFAULT;
31 import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
32 import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER;
33 import static com.android.internal.app.ChooserListAdapter.CALLER_TARGET_SCORE_BOOST;
34 import static com.android.internal.app.ChooserListAdapter.SHORTCUT_TARGET_SCORE_BOOST;
35 import static com.android.internal.app.ChooserWrapperActivity.sOverrides;
36 import static com.android.internal.app.MatcherUtils.first;
37 
38 import static junit.framework.Assert.assertFalse;
39 import static junit.framework.Assert.assertNull;
40 import static junit.framework.Assert.assertTrue;
41 
42 import static org.hamcrest.CoreMatchers.allOf;
43 import static org.hamcrest.CoreMatchers.is;
44 import static org.hamcrest.CoreMatchers.not;
45 import static org.hamcrest.CoreMatchers.notNullValue;
46 import static org.hamcrest.MatcherAssert.assertThat;
47 import static org.junit.Assert.assertEquals;
48 import static org.mockito.ArgumentMatchers.any;
49 import static org.mockito.ArgumentMatchers.anyInt;
50 import static org.mockito.ArgumentMatchers.eq;
51 import static org.mockito.Mockito.atLeastOnce;
52 import static org.mockito.Mockito.mock;
53 import static org.mockito.Mockito.times;
54 import static org.mockito.Mockito.verify;
55 import static org.mockito.Mockito.when;
56 
57 import android.app.usage.UsageStatsManager;
58 import android.content.ClipData;
59 import android.content.ClipDescription;
60 import android.content.ClipboardManager;
61 import android.content.ComponentName;
62 import android.content.Context;
63 import android.content.Intent;
64 import android.content.pm.ActivityInfo;
65 import android.content.pm.ApplicationInfo;
66 import android.content.pm.PackageManager;
67 import android.content.pm.ResolveInfo;
68 import android.content.pm.ShortcutInfo;
69 import android.content.pm.ShortcutManager.ShareShortcutInfo;
70 import android.content.res.Configuration;
71 import android.database.Cursor;
72 import android.graphics.Bitmap;
73 import android.graphics.Canvas;
74 import android.graphics.Color;
75 import android.graphics.Paint;
76 import android.graphics.drawable.Icon;
77 import android.metrics.LogMaker;
78 import android.net.Uri;
79 import android.os.UserHandle;
80 import android.provider.DeviceConfig;
81 import android.service.chooser.ChooserTarget;
82 
83 import androidx.test.platform.app.InstrumentationRegistry;
84 import androidx.test.rule.ActivityTestRule;
85 
86 import com.android.internal.R;
87 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
88 import com.android.internal.app.chooser.DisplayResolveInfo;
89 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
90 import com.android.internal.logging.MetricsLogger;
91 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
92 import com.android.internal.util.FrameworkStatsLog;
93 
94 import org.junit.Before;
95 import org.junit.Ignore;
96 import org.junit.Rule;
97 import org.junit.Test;
98 import org.junit.runner.RunWith;
99 import org.junit.runners.Parameterized;
100 import org.mockito.ArgumentCaptor;
101 import org.mockito.Mockito;
102 
103 import java.util.ArrayList;
104 import java.util.Arrays;
105 import java.util.Collection;
106 import java.util.HashMap;
107 import java.util.List;
108 import java.util.Map;
109 import java.util.function.Function;
110 
111 /**
112  * Chooser activity instrumentation tests
113  */
114 @RunWith(Parameterized.class)
115 public class ChooserActivityTest {
116 
117     private static final Function<PackageManager, PackageManager> DEFAULT_PM = pm -> pm;
118     private static final Function<PackageManager, PackageManager> NO_APP_PREDICTION_SERVICE_PM =
119             pm -> {
120                 PackageManager mock = Mockito.spy(pm);
121                 when(mock.getAppPredictionServicePackageName()).thenReturn(null);
122                 return mock;
123             };
124 
125     @Parameterized.Parameters
packageManagers()126     public static Collection packageManagers() {
127         return Arrays.asList(new Object[][] {
128                 {0, "Default PackageManager", DEFAULT_PM},
129                 {1, "No App Prediction Service", NO_APP_PREDICTION_SERVICE_PM}
130         });
131     }
132 
133     private static final int CONTENT_PREVIEW_IMAGE = 1;
134     private static final int CONTENT_PREVIEW_FILE = 2;
135     private static final int CONTENT_PREVIEW_TEXT = 3;
136     private Function<PackageManager, PackageManager> mPackageManagerOverride;
137     private int mTestNum;
138 
139     @Rule
140     public ActivityTestRule<ChooserWrapperActivity> mActivityRule =
141             new ActivityTestRule<>(ChooserWrapperActivity.class, false,
142                     false);
143 
ChooserActivityTest( int testNum, String testName, Function<PackageManager, PackageManager> packageManagerOverride)144     public ChooserActivityTest(
145                 int testNum,
146                 String testName,
147                 Function<PackageManager, PackageManager> packageManagerOverride) {
148         mPackageManagerOverride = packageManagerOverride;
149         mTestNum = testNum;
150     }
151 
152     @Before
cleanOverrideData()153     public void cleanOverrideData() {
154         sOverrides.reset();
155         sOverrides.createPackageManager = mPackageManagerOverride;
156         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
157                 SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
158                 Boolean.toString(false),
159                 true /* makeDefault*/);
160     }
161 
162     @Test
customTitle()163     public void customTitle() throws InterruptedException {
164         Intent viewIntent = createViewTextIntent();
165         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
166 
167         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
168                 Mockito.anyBoolean(),
169                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
170         final ChooserWrapperActivity activity = mActivityRule.launchActivity(
171                 Intent.createChooser(viewIntent, "chooser test"));
172 
173         waitForIdle();
174         assertThat(activity.getAdapter().getCount(), is(2));
175         assertThat(activity.getAdapter().getServiceTargetCount(), is(0));
176         onView(withId(R.id.title)).check(matches(withText("chooser test")));
177     }
178 
179     @Test
customTitleIgnoredForSendIntents()180     public void customTitleIgnoredForSendIntents() throws InterruptedException {
181         Intent sendIntent = createSendTextIntent();
182         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
183 
184         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
185                 Mockito.anyBoolean(),
186                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
187         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "chooser test"));
188         waitForIdle();
189         onView(withId(R.id.title)).check(matches(withText(R.string.whichSendApplication)));
190     }
191 
192     @Test
emptyTitle()193     public void emptyTitle() throws InterruptedException {
194         Intent sendIntent = createSendTextIntent();
195         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
196 
197         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
198                 Mockito.anyBoolean(),
199                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
200         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
201         waitForIdle();
202         onView(withId(R.id.title))
203                 .check(matches(withText(R.string.whichSendApplication)));
204     }
205 
206     @Test
emptyPreviewTitleAndThumbnail()207     public void emptyPreviewTitleAndThumbnail() throws InterruptedException {
208         Intent sendIntent = createSendTextIntentWithPreview(null, null);
209         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
210 
211         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
212                 Mockito.anyBoolean(),
213                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
214         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
215         waitForIdle();
216         onView(withId(R.id.content_preview_title)).check(matches(not(isDisplayed())));
217         onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
218     }
219 
220     @Test
visiblePreviewTitleWithoutThumbnail()221     public void visiblePreviewTitleWithoutThumbnail() throws InterruptedException {
222         String previewTitle = "My Content Preview Title";
223         Intent sendIntent = createSendTextIntentWithPreview(previewTitle, null);
224         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
225 
226         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
227                 Mockito.anyBoolean(),
228                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
229         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
230         waitForIdle();
231         onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
232         onView(withId(R.id.content_preview_title)).check(matches(withText(previewTitle)));
233         onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
234     }
235 
236     @Test
visiblePreviewTitleWithInvalidThumbnail()237     public void visiblePreviewTitleWithInvalidThumbnail() throws InterruptedException {
238         String previewTitle = "My Content Preview Title";
239         Intent sendIntent = createSendTextIntentWithPreview(previewTitle,
240                 Uri.parse("tel:(+49)12345789"));
241         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
242 
243         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
244                 Mockito.anyBoolean(),
245                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
246         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
247         waitForIdle();
248         onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
249         onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
250     }
251 
252     @Test
visiblePreviewTitleAndThumbnail()253     public void visiblePreviewTitleAndThumbnail() throws InterruptedException {
254         String previewTitle = "My Content Preview Title";
255         Intent sendIntent = createSendTextIntentWithPreview(previewTitle,
256                 Uri.parse("android.resource://com.android.frameworks.coretests/"
257                         + com.android.frameworks.coretests.R.drawable.test320x240));
258         sOverrides.previewThumbnail = createBitmap();
259         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
260 
261         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
262                 Mockito.anyBoolean(),
263                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
264         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
265         waitForIdle();
266         onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
267         onView(withId(R.id.content_preview_thumbnail)).check(matches(isDisplayed()));
268     }
269 
270     @Test
twoOptionsAndUserSelectsOne()271     public void twoOptionsAndUserSelectsOne() throws InterruptedException {
272         Intent sendIntent = createSendTextIntent();
273         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
274 
275         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
276                 Mockito.anyBoolean(),
277                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
278 
279         final ChooserWrapperActivity activity = mActivityRule
280                 .launchActivity(Intent.createChooser(sendIntent, null));
281         waitForIdle();
282 
283         assertThat(activity.getAdapter().getCount(), is(2));
284         onView(withId(R.id.profile_button)).check(doesNotExist());
285 
286         ResolveInfo[] chosen = new ResolveInfo[1];
287         sOverrides.onSafelyStartCallback = targetInfo -> {
288             chosen[0] = targetInfo.getResolveInfo();
289             return true;
290         };
291 
292         ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
293         onView(withText(toChoose.activityInfo.name))
294                 .perform(click());
295         waitForIdle();
296         assertThat(chosen[0], is(toChoose));
297     }
298 
299     @Test
fourOptionsStackedIntoOneTarget()300     public void fourOptionsStackedIntoOneTarget() throws InterruptedException {
301         Intent sendIntent = createSendTextIntent();
302 
303         // create just enough targets to ensure the a-z list should be shown
304         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(1);
305 
306         // next create 4 targets in a single app that should be stacked into a single target
307         String packageName = "xxx.yyy";
308         String appName = "aaa";
309         ComponentName cn = new ComponentName(packageName, appName);
310         Intent intent = new Intent("fakeIntent");
311         List<ResolvedComponentInfo> infosToStack = new ArrayList<>();
312         for (int i = 0; i < 4; i++) {
313             ResolveInfo resolveInfo = ResolverDataProvider.createResolveInfo(i,
314                     UserHandle.USER_CURRENT);
315             resolveInfo.activityInfo.applicationInfo.name = appName;
316             resolveInfo.activityInfo.applicationInfo.packageName = packageName;
317             resolveInfo.activityInfo.packageName = packageName;
318             resolveInfo.activityInfo.name = "ccc" + i;
319             infosToStack.add(new ResolvedComponentInfo(cn, intent, resolveInfo));
320         }
321         resolvedComponentInfos.addAll(infosToStack);
322 
323         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
324                 Mockito.anyBoolean(),
325                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
326 
327         final ChooserWrapperActivity activity = mActivityRule
328                 .launchActivity(Intent.createChooser(sendIntent, null));
329         waitForIdle();
330 
331         // expect 1 unique targets + 1 group + 4 ranked app targets
332         assertThat(activity.getAdapter().getCount(), is(6));
333 
334         ResolveInfo[] chosen = new ResolveInfo[1];
335         sOverrides.onSafelyStartCallback = targetInfo -> {
336             chosen[0] = targetInfo.getResolveInfo();
337             return true;
338         };
339 
340         onView(allOf(withText(appName), hasSibling(withText("")))).perform(click());
341         waitForIdle();
342 
343         // clicking will launch a dialog to choose the activity within the app
344         onView(withText(appName)).check(matches(isDisplayed()));
345         int i = 0;
346         for (ResolvedComponentInfo rci: infosToStack) {
347             onView(withText("ccc" + i)).check(matches(isDisplayed()));
348             ++i;
349         }
350     }
351 
352     @Test
updateChooserCountsAndModelAfterUserSelection()353     public void updateChooserCountsAndModelAfterUserSelection() throws InterruptedException {
354         Intent sendIntent = createSendTextIntent();
355         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
356 
357         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
358                 Mockito.anyBoolean(),
359                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
360 
361         final ChooserWrapperActivity activity = mActivityRule
362                 .launchActivity(Intent.createChooser(sendIntent, null));
363         waitForIdle();
364         UsageStatsManager usm = activity.getUsageStatsManager();
365         verify(sOverrides.resolverListController, times(1))
366                 .topK(any(List.class), anyInt());
367         assertThat(activity.getIsSelected(), is(false));
368         sOverrides.onSafelyStartCallback = targetInfo -> {
369             return true;
370         };
371         ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
372         onView(withText(toChoose.activityInfo.name))
373                 .perform(click());
374         waitForIdle();
375         verify(sOverrides.resolverListController, times(1))
376                 .updateChooserCounts(Mockito.anyString(), anyInt(), Mockito.anyString());
377         verify(sOverrides.resolverListController, times(1))
378                 .updateModel(toChoose.activityInfo.getComponentName());
379         assertThat(activity.getIsSelected(), is(true));
380     }
381 
382     @Ignore // b/148158199
383     @Test
noResultsFromPackageManager()384     public void noResultsFromPackageManager() {
385         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
386                 Mockito.anyBoolean(),
387                 Mockito.isA(List.class))).thenReturn(null);
388         Intent sendIntent = createSendTextIntent();
389         final ChooserWrapperActivity activity = mActivityRule
390                 .launchActivity(Intent.createChooser(sendIntent, null));
391         waitForIdle();
392         assertThat(activity.isFinishing(), is(false));
393 
394         onView(withId(R.id.empty)).check(matches(isDisplayed()));
395         onView(withId(R.id.profile_pager)).check(matches(not(isDisplayed())));
396         InstrumentationRegistry.getInstrumentation().runOnMainSync(
397                 () -> activity.getAdapter().handlePackagesChanged()
398         );
399         // backward compatibility. looks like we finish when data is empty after package change
400         assertThat(activity.isFinishing(), is(true));
401     }
402 
403     @Test
autoLaunchSingleResult()404     public void autoLaunchSingleResult() throws InterruptedException {
405         ResolveInfo[] chosen = new ResolveInfo[1];
406         sOverrides.onSafelyStartCallback = targetInfo -> {
407             chosen[0] = targetInfo.getResolveInfo();
408             return true;
409         };
410 
411         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(1);
412         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
413                 Mockito.anyBoolean(),
414                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
415 
416         Intent sendIntent = createSendTextIntent();
417         final ChooserWrapperActivity activity = mActivityRule
418                 .launchActivity(Intent.createChooser(sendIntent, null));
419         waitForIdle();
420 
421         assertThat(chosen[0], is(resolvedComponentInfos.get(0).getResolveInfoAt(0)));
422         assertThat(activity.isFinishing(), is(true));
423     }
424 
425     @Test
hasOtherProfileOneOption()426     public void hasOtherProfileOneOption() throws Exception {
427         // enable the work tab feature flag
428         ResolverActivity.ENABLE_TABBED_VIEW = true;
429         List<ResolvedComponentInfo> personalResolvedComponentInfos =
430                 createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
431         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
432         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
433         markWorkProfileUserAvailable();
434 
435         ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0);
436         Intent sendIntent = createSendTextIntent();
437         final ChooserWrapperActivity activity = mActivityRule
438                 .launchActivity(Intent.createChooser(sendIntent, null));
439         waitForIdle();
440 
441         // The other entry is filtered to the other profile slot
442         assertThat(activity.getAdapter().getCount(), is(1));
443 
444         ResolveInfo[] chosen = new ResolveInfo[1];
445         ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> {
446             chosen[0] = targetInfo.getResolveInfo();
447             return true;
448         };
449 
450         // Make a stable copy of the components as the original list may be modified
451         List<ResolvedComponentInfo> stableCopy =
452                 createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10);
453         waitForIdle();
454         Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
455 
456         onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)))
457                 .perform(click());
458         waitForIdle();
459         assertThat(chosen[0], is(toChoose));
460     }
461 
462     @Test
hasOtherProfileTwoOptionsAndUserSelectsOne()463     public void hasOtherProfileTwoOptionsAndUserSelectsOne() throws Exception {
464         // enable the work tab feature flag
465         ResolverActivity.ENABLE_TABBED_VIEW = true;
466 
467         Intent sendIntent = createSendTextIntent();
468         List<ResolvedComponentInfo> resolvedComponentInfos =
469                 createResolvedComponentsForTestWithOtherProfile(3);
470         ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
471 
472         when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
473                 Mockito.anyBoolean(),
474                 Mockito.anyBoolean(),
475                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
476         when(ChooserWrapperActivity.sOverrides.resolverListController.getLastChosen())
477                 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
478 
479         final ChooserWrapperActivity activity = mActivityRule
480                 .launchActivity(Intent.createChooser(sendIntent, null));
481         waitForIdle();
482 
483         // The other entry is filtered to the other profile slot
484         assertThat(activity.getAdapter().getCount(), is(2));
485 
486         ResolveInfo[] chosen = new ResolveInfo[1];
487         ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> {
488             chosen[0] = targetInfo.getResolveInfo();
489             return true;
490         };
491 
492         // Make a stable copy of the components as the original list may be modified
493         List<ResolvedComponentInfo> stableCopy =
494                 createResolvedComponentsForTestWithOtherProfile(3);
495         onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
496                 .perform(click());
497         waitForIdle();
498         assertThat(chosen[0], is(toChoose));
499     }
500 
501     @Test
hasLastChosenActivityAndOtherProfile()502     public void hasLastChosenActivityAndOtherProfile() throws Exception {
503         // enable the work tab feature flag
504         ResolverActivity.ENABLE_TABBED_VIEW = true;
505 
506         Intent sendIntent = createSendTextIntent();
507         List<ResolvedComponentInfo> resolvedComponentInfos =
508                 createResolvedComponentsForTestWithOtherProfile(3);
509         ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
510 
511         when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
512                 Mockito.anyBoolean(),
513                 Mockito.anyBoolean(),
514                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
515 
516         final ChooserWrapperActivity activity = mActivityRule
517                 .launchActivity(Intent.createChooser(sendIntent, null));
518         waitForIdle();
519 
520         // The other entry is filtered to the last used slot
521         assertThat(activity.getAdapter().getCount(), is(2));
522 
523         ResolveInfo[] chosen = new ResolveInfo[1];
524         ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> {
525             chosen[0] = targetInfo.getResolveInfo();
526             return true;
527         };
528 
529         // Make a stable copy of the components as the original list may be modified
530         List<ResolvedComponentInfo> stableCopy =
531                 createResolvedComponentsForTestWithOtherProfile(3);
532         onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
533                 .perform(click());
534         waitForIdle();
535         assertThat(chosen[0], is(toChoose));
536     }
537 
538     @Test
copyTextToClipboard()539     public void copyTextToClipboard() throws Exception {
540         Intent sendIntent = createSendTextIntent();
541         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
542 
543         when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
544             Mockito.anyBoolean(),
545             Mockito.anyBoolean(),
546             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
547 
548         final ChooserWrapperActivity activity = mActivityRule
549                 .launchActivity(Intent.createChooser(sendIntent, null));
550         waitForIdle();
551 
552         onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
553         onView(withId(R.id.chooser_copy_button)).perform(click());
554         ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(
555                 Context.CLIPBOARD_SERVICE);
556         ClipData clipData = clipboard.getPrimaryClip();
557         assertThat("testing intent sending", is(clipData.getItemAt(0).getText()));
558 
559         ClipDescription clipDescription = clipData.getDescription();
560         assertThat("text/plain", is(clipDescription.getMimeType(0)));
561     }
562 
563     @Test
copyTextToClipboardLogging()564     public void copyTextToClipboardLogging() throws Exception {
565         Intent sendIntent = createSendTextIntent();
566         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
567 
568         when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
569             Mockito.anyBoolean(),
570             Mockito.anyBoolean(),
571             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
572 
573         MetricsLogger mockLogger = sOverrides.metricsLogger;
574         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
575 
576         final ChooserWrapperActivity activity = mActivityRule
577                 .launchActivity(Intent.createChooser(sendIntent, null));
578         waitForIdle();
579 
580         onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
581         onView(withId(R.id.chooser_copy_button)).perform(click());
582 
583         verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
584         // First is  Activity shown, Second is "with preview"
585         assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
586                 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET));
587         assertThat(logMakerCaptor
588                         .getAllValues().get(2)
589                         .getSubtype(),
590                 is(1));
591     }
592 
593     @Test
oneVisibleImagePreview()594     public void oneVisibleImagePreview() throws InterruptedException {
595         Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
596                 + com.android.frameworks.coretests.R.drawable.test320x240);
597 
598         ArrayList<Uri> uris = new ArrayList<>();
599         uris.add(uri);
600 
601         Intent sendIntent = createSendUriIntentWithPreview(uris);
602         sOverrides.previewThumbnail = createBitmap();
603         sOverrides.isImageType = true;
604 
605         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
606 
607         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
608                 Mockito.anyBoolean(),
609                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
610         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
611         waitForIdle();
612         onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
613         onView(withId(R.id.content_preview_image_2_large)).check(matches(not(isDisplayed())));
614         onView(withId(R.id.content_preview_image_2_small)).check(matches(not(isDisplayed())));
615         onView(withId(R.id.content_preview_image_3_small)).check(matches(not(isDisplayed())));
616     }
617 
618     @Test
twoVisibleImagePreview()619     public void twoVisibleImagePreview() throws InterruptedException {
620         Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
621                 + com.android.frameworks.coretests.R.drawable.test320x240);
622 
623         ArrayList<Uri> uris = new ArrayList<>();
624         uris.add(uri);
625         uris.add(uri);
626 
627         Intent sendIntent = createSendUriIntentWithPreview(uris);
628         sOverrides.previewThumbnail = createBitmap();
629         sOverrides.isImageType = true;
630 
631         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
632 
633         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
634                 Mockito.anyBoolean(),
635                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
636         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
637         waitForIdle();
638         onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
639         onView(withId(R.id.content_preview_image_2_large)).check(matches(isDisplayed()));
640         onView(withId(R.id.content_preview_image_2_small)).check(matches(not(isDisplayed())));
641         onView(withId(R.id.content_preview_image_3_small)).check(matches(not(isDisplayed())));
642     }
643 
644     @Test
threeOrMoreVisibleImagePreview()645     public void threeOrMoreVisibleImagePreview() throws InterruptedException {
646         Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
647                 + com.android.frameworks.coretests.R.drawable.test320x240);
648 
649         ArrayList<Uri> uris = new ArrayList<>();
650         uris.add(uri);
651         uris.add(uri);
652         uris.add(uri);
653         uris.add(uri);
654         uris.add(uri);
655 
656         Intent sendIntent = createSendUriIntentWithPreview(uris);
657         sOverrides.previewThumbnail = createBitmap();
658         sOverrides.isImageType = true;
659 
660         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
661 
662         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
663             Mockito.anyBoolean(),
664             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
665         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
666         waitForIdle();
667         onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
668         onView(withId(R.id.content_preview_image_2_large)).check(matches(not(isDisplayed())));
669         onView(withId(R.id.content_preview_image_2_small)).check(matches(isDisplayed()));
670         onView(withId(R.id.content_preview_image_3_small)).check(matches(isDisplayed()));
671     }
672 
673     @Test
testOnCreateLogging()674     public void testOnCreateLogging() {
675         Intent sendIntent = createSendTextIntent();
676         sendIntent.setType("TestType");
677 
678         MetricsLogger mockLogger = sOverrides.metricsLogger;
679         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
680         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
681         waitForIdle();
682         verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
683         assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
684                 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
685         assertThat(logMakerCaptor
686                 .getAllValues().get(0)
687                 .getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
688                 is(notNullValue()));
689         assertThat(logMakerCaptor
690                 .getAllValues().get(0)
691                 .getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
692                 is("TestType"));
693         assertThat(logMakerCaptor
694                         .getAllValues().get(0)
695                         .getSubtype(),
696                 is(MetricsEvent.PARENT_PROFILE));
697     }
698 
699     @Test
testOnCreateLoggingFromWorkProfile()700     public void testOnCreateLoggingFromWorkProfile() {
701         Intent sendIntent = createSendTextIntent();
702         sendIntent.setType("TestType");
703         sOverrides.alternateProfileSetting = MetricsEvent.MANAGED_PROFILE;
704         MetricsLogger mockLogger = sOverrides.metricsLogger;
705         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
706         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
707         waitForIdle();
708         verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
709         assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
710                 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
711         assertThat(logMakerCaptor
712                         .getAllValues().get(0)
713                         .getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
714                 is(notNullValue()));
715         assertThat(logMakerCaptor
716                         .getAllValues().get(0)
717                         .getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
718                 is("TestType"));
719         assertThat(logMakerCaptor
720                         .getAllValues().get(0)
721                         .getSubtype(),
722                 is(MetricsEvent.MANAGED_PROFILE));
723     }
724 
725     @Test
testEmptyPreviewLogging()726     public void testEmptyPreviewLogging() {
727         Intent sendIntent = createSendTextIntentWithPreview(null, null);
728 
729         MetricsLogger mockLogger = sOverrides.metricsLogger;
730         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
731         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "empty preview logger test"));
732         waitForIdle();
733 
734         verify(mockLogger, Mockito.times(1)).write(logMakerCaptor.capture());
735         // First invocation is from onCreate
736         assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
737                 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
738     }
739 
740     @Test
testTitlePreviewLogging()741     public void testTitlePreviewLogging() {
742         Intent sendIntent = createSendTextIntentWithPreview("TestTitle", null);
743 
744         MetricsLogger mockLogger = sOverrides.metricsLogger;
745         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
746 
747         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
748 
749         when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
750             Mockito.anyBoolean(),
751             Mockito.anyBoolean(),
752             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
753 
754         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
755         waitForIdle();
756         // Second invocation is from onCreate
757         verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
758         assertThat(logMakerCaptor.getAllValues().get(0).getSubtype(),
759                 is(CONTENT_PREVIEW_TEXT));
760         assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
761                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
762     }
763 
764     @Test
testImagePreviewLogging()765     public void testImagePreviewLogging() {
766         Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
767                 + com.android.frameworks.coretests.R.drawable.test320x240);
768 
769         ArrayList<Uri> uris = new ArrayList<>();
770         uris.add(uri);
771 
772         Intent sendIntent = createSendUriIntentWithPreview(uris);
773         sOverrides.previewThumbnail = createBitmap();
774         sOverrides.isImageType = true;
775 
776         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
777 
778         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
779             Mockito.anyBoolean(),
780             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
781 
782         MetricsLogger mockLogger = sOverrides.metricsLogger;
783         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
784         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
785         waitForIdle();
786         verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
787         // First invocation is from onCreate
788         assertThat(logMakerCaptor.getAllValues().get(0).getSubtype(),
789                 is(CONTENT_PREVIEW_IMAGE));
790         assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
791                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
792     }
793 
794     @Test
oneVisibleFilePreview()795     public void oneVisibleFilePreview() throws InterruptedException {
796         Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
797 
798         ArrayList<Uri> uris = new ArrayList<>();
799         uris.add(uri);
800 
801         Intent sendIntent = createSendUriIntentWithPreview(uris);
802 
803         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
804 
805         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
806                 Mockito.anyBoolean(),
807                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
808         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
809         waitForIdle();
810         onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
811         onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf")));
812         onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
813     }
814 
815 
816     @Test
moreThanOneVisibleFilePreview()817     public void moreThanOneVisibleFilePreview() throws InterruptedException {
818         Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
819 
820         ArrayList<Uri> uris = new ArrayList<>();
821         uris.add(uri);
822         uris.add(uri);
823         uris.add(uri);
824 
825         Intent sendIntent = createSendUriIntentWithPreview(uris);
826 
827         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
828 
829         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
830                 Mockito.anyBoolean(),
831                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
832         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
833         waitForIdle();
834         onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
835         onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf + 2 files")));
836         onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
837     }
838 
839     @Test
contentProviderThrowSecurityException()840     public void contentProviderThrowSecurityException() throws InterruptedException {
841         Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
842 
843         ArrayList<Uri> uris = new ArrayList<>();
844         uris.add(uri);
845 
846         Intent sendIntent = createSendUriIntentWithPreview(uris);
847 
848         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
849         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
850                 Mockito.anyBoolean(),
851                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
852 
853         sOverrides.resolverForceException = true;
854 
855         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
856         waitForIdle();
857         onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
858         onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf")));
859         onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
860     }
861 
862     @Test
contentProviderReturnsNoColumns()863     public void contentProviderReturnsNoColumns() throws InterruptedException {
864         Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
865 
866         ArrayList<Uri> uris = new ArrayList<>();
867         uris.add(uri);
868         uris.add(uri);
869 
870         Intent sendIntent = createSendUriIntentWithPreview(uris);
871 
872         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
873         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
874                 Mockito.anyBoolean(),
875                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
876 
877         Cursor cursor = mock(Cursor.class);
878         when(cursor.getCount()).thenReturn(1);
879         Mockito.doNothing().when(cursor).close();
880         when(cursor.moveToFirst()).thenReturn(true);
881         when(cursor.getColumnIndex(Mockito.anyString())).thenReturn(-1);
882 
883         sOverrides.resolverCursor = cursor;
884 
885         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
886         waitForIdle();
887         onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
888         onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf + 1 file")));
889         onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
890     }
891 
892     @Test
testGetBaseScore()893     public void testGetBaseScore() {
894         final float testBaseScore = 0.89f;
895 
896         Intent sendIntent = createSendTextIntent();
897         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
898 
899         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
900                 Mockito.anyBoolean(),
901                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
902         when(sOverrides.resolverListController.getScore(Mockito.isA(DisplayResolveInfo.class)))
903                 .thenReturn(testBaseScore);
904 
905         final ChooserWrapperActivity activity = mActivityRule
906                 .launchActivity(Intent.createChooser(sendIntent, null));
907         waitForIdle();
908 
909         final DisplayResolveInfo testDri =
910                 activity.createTestDisplayResolveInfo(sendIntent,
911                 ResolverDataProvider.createResolveInfo(3, 0), "testLabel", "testInfo", sendIntent,
912                 /* resolveInfoPresentationGetter */ null);
913         final ChooserListAdapter adapter = activity.getAdapter();
914 
915         assertThat(adapter.getBaseScore(null, 0), is(CALLER_TARGET_SCORE_BOOST));
916         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_DEFAULT), is(testBaseScore));
917         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_CHOOSER_TARGET), is(testBaseScore));
918         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE),
919                 is(SHORTCUT_TARGET_SCORE_BOOST));
920         assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER),
921                 is(testBaseScore * SHORTCUT_TARGET_SCORE_BOOST));
922     }
923 
924     /**
925      * The case when AppPrediction service is not defined in PackageManager is already covered
926      * as a test parameter {@link ChooserActivityTest#packageManagers}. This test is checking the
927      * case when the prediction service is defined but the component is not available on the device.
928      */
929     @Test
testIsAppPredictionServiceAvailable()930     public void testIsAppPredictionServiceAvailable() {
931         Intent sendIntent = createSendTextIntent();
932         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
933         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
934                 Mockito.anyBoolean(),
935                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
936 
937         final ChooserWrapperActivity activity = mActivityRule
938                 .launchActivity(Intent.createChooser(sendIntent, null));
939         waitForIdle();
940 
941         if (activity.getPackageManager().getAppPredictionServicePackageName() == null) {
942             assertThat(activity.isAppPredictionServiceAvailable(), is(false));
943         } else {
944             assertThat(activity.isAppPredictionServiceAvailable(), is(true));
945 
946             sOverrides.resources = Mockito.spy(activity.getResources());
947             when(sOverrides.resources.getString(R.string.config_defaultAppPredictionService))
948                     .thenReturn("ComponentNameThatDoesNotExist");
949 
950             assertThat(activity.isAppPredictionServiceAvailable(), is(false));
951         }
952     }
953 
954     @Test
testConvertToChooserTarget_predictionService()955     public void testConvertToChooserTarget_predictionService() {
956         Intent sendIntent = createSendTextIntent();
957         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
958         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
959                 Mockito.anyBoolean(),
960                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
961 
962         final ChooserWrapperActivity activity = mActivityRule
963                 .launchActivity(Intent.createChooser(sendIntent, null));
964         waitForIdle();
965 
966         List<ShareShortcutInfo> shortcuts = createShortcuts(activity);
967 
968         int[] expectedOrderAllShortcuts = {0, 1, 2, 3};
969         float[] expectedScoreAllShortcuts = {1.0f, 0.99f, 0.98f, 0.97f};
970 
971         List<ChooserTarget> chooserTargets = activity.convertToChooserTarget(shortcuts, shortcuts,
972                 null, TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
973         assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
974                 expectedOrderAllShortcuts, expectedScoreAllShortcuts);
975 
976         List<ShareShortcutInfo> subset = new ArrayList<>();
977         subset.add(shortcuts.get(1));
978         subset.add(shortcuts.get(2));
979         subset.add(shortcuts.get(3));
980 
981         int[] expectedOrderSubset = {1, 2, 3};
982         float[] expectedScoreSubset = {0.99f, 0.98f, 0.97f};
983 
984         chooserTargets = activity.convertToChooserTarget(subset, shortcuts, null,
985                 TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
986         assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
987                 expectedOrderSubset, expectedScoreSubset);
988     }
989 
990     @Test
testConvertToChooserTarget_shortcutManager()991     public void testConvertToChooserTarget_shortcutManager() {
992         Intent sendIntent = createSendTextIntent();
993         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
994         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
995                 Mockito.anyBoolean(),
996                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
997 
998         final ChooserWrapperActivity activity = mActivityRule
999                 .launchActivity(Intent.createChooser(sendIntent, null));
1000         waitForIdle();
1001 
1002         List<ShareShortcutInfo> shortcuts = createShortcuts(activity);
1003 
1004         int[] expectedOrderAllShortcuts = {2, 0, 3, 1};
1005         float[] expectedScoreAllShortcuts = {1.0f, 0.99f, 0.99f, 0.98f};
1006 
1007         List<ChooserTarget> chooserTargets = activity.convertToChooserTarget(shortcuts, shortcuts,
1008                 null, TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER);
1009         assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
1010                 expectedOrderAllShortcuts, expectedScoreAllShortcuts);
1011 
1012         List<ShareShortcutInfo> subset = new ArrayList<>();
1013         subset.add(shortcuts.get(1));
1014         subset.add(shortcuts.get(2));
1015         subset.add(shortcuts.get(3));
1016 
1017         int[] expectedOrderSubset = {2, 3, 1};
1018         float[] expectedScoreSubset = {1.0f, 0.99f, 0.98f};
1019 
1020         chooserTargets = activity.convertToChooserTarget(subset, shortcuts, null,
1021                 TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER);
1022         assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
1023                 expectedOrderSubset, expectedScoreSubset);
1024     }
1025 
1026     // This test is too long and too slow and should not be taken as an example for future tests.
1027     @Test
testDirectTargetSelectionLogging()1028     public void testDirectTargetSelectionLogging() throws InterruptedException {
1029         Intent sendIntent = createSendTextIntent();
1030         // We need app targets for direct targets to get displayed
1031         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
1032         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1033                 Mockito.anyBoolean(),
1034                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1035 
1036         // Set up resources
1037         MetricsLogger mockLogger = sOverrides.metricsLogger;
1038         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
1039         // Create direct share target
1040         List<ChooserTarget> serviceTargets = createDirectShareTargets(1, "");
1041         ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
1042 
1043         // Start activity
1044         final ChooserWrapperActivity activity = mActivityRule
1045                 .launchActivity(Intent.createChooser(sendIntent, null));
1046 
1047         // Insert the direct share target
1048         Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
1049         directShareToShortcutInfos.put(serviceTargets.get(0), null);
1050         InstrumentationRegistry.getInstrumentation().runOnMainSync(
1051                 () -> activity.getAdapter().addServiceResults(
1052                         activity.createTestDisplayResolveInfo(sendIntent,
1053                                 ri,
1054                                 "testLabel",
1055                                 "testInfo",
1056                                 sendIntent,
1057                                 /* resolveInfoPresentationGetter */ null),
1058                         serviceTargets,
1059                         TARGET_TYPE_CHOOSER_TARGET,
1060                         directShareToShortcutInfos,
1061                         List.of())
1062         );
1063 
1064         // Thread.sleep shouldn't be a thing in an integration test but it's
1065         // necessary here because of the way the code is structured
1066         // TODO: restructure the tests b/129870719
1067         Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1068 
1069         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
1070                 activity.getAdapter().getCount(), is(3));
1071         assertThat("Chooser should have exactly one selectable direct target",
1072                 activity.getAdapter().getSelectableServiceTargetCount(), is(1));
1073         assertThat("The resolver info must match the resolver info used to create the target",
1074                 activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
1075 
1076         // Click on the direct target
1077         String name = serviceTargets.get(0).getTitle().toString();
1078         onView(withText(name))
1079                 .perform(click());
1080         waitForIdle();
1081 
1082         // Currently we're seeing 3 invocations
1083         //      1. ChooserActivity.onCreate()
1084         //      2. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
1085         //      3. ChooserActivity.startSelected -- which is the one we're after
1086         verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
1087         assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
1088                 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
1089         String hashedName = (String) logMakerCaptor
1090                 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_HASHED_TARGET_NAME);
1091         assertThat("Hash is not predictable but must be obfuscated",
1092                 hashedName, is(not(name)));
1093         assertThat("The packages shouldn't match for app target and direct target", logMakerCaptor
1094                 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(-1));
1095     }
1096 
1097     // This test is too long and too slow and should not be taken as an example for future tests.
1098     @Test
testDirectTargetLoggingWithRankedAppTarget()1099     public void testDirectTargetLoggingWithRankedAppTarget() throws InterruptedException {
1100         Intent sendIntent = createSendTextIntent();
1101         // We need app targets for direct targets to get displayed
1102         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
1103         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1104                 Mockito.anyBoolean(),
1105                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1106 
1107         // Set up resources
1108         MetricsLogger mockLogger = sOverrides.metricsLogger;
1109         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
1110         // Create direct share target
1111         List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
1112                 resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
1113         ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
1114 
1115         // Start activity
1116         final ChooserWrapperActivity activity = mActivityRule
1117                 .launchActivity(Intent.createChooser(sendIntent, null));
1118 
1119         // Insert the direct share target
1120         Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
1121         directShareToShortcutInfos.put(serviceTargets.get(0), null);
1122         InstrumentationRegistry.getInstrumentation().runOnMainSync(
1123                 () -> activity.getAdapter().addServiceResults(
1124                         activity.createTestDisplayResolveInfo(sendIntent,
1125                                 ri,
1126                                 "testLabel",
1127                                 "testInfo",
1128                                 sendIntent,
1129                                 /* resolveInfoPresentationGetter */ null),
1130                         serviceTargets,
1131                         TARGET_TYPE_CHOOSER_TARGET,
1132                         directShareToShortcutInfos,
1133                         List.of())
1134         );
1135         // Thread.sleep shouldn't be a thing in an integration test but it's
1136         // necessary here because of the way the code is structured
1137         // TODO: restructure the tests b/129870719
1138         Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1139 
1140         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
1141                 activity.getAdapter().getCount(), is(3));
1142         assertThat("Chooser should have exactly one selectable direct target",
1143                 activity.getAdapter().getSelectableServiceTargetCount(), is(1));
1144         assertThat("The resolver info must match the resolver info used to create the target",
1145                 activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
1146 
1147         // Click on the direct target
1148         String name = serviceTargets.get(0).getTitle().toString();
1149         onView(withText(name))
1150                 .perform(click());
1151         waitForIdle();
1152 
1153         // Currently we're seeing 3 invocations
1154         //      1. ChooserActivity.onCreate()
1155         //      2. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
1156         //      3. ChooserActivity.startSelected -- which is the one we're after
1157         verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
1158         assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
1159                 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
1160         assertThat("The packages should match for app target and direct target", logMakerCaptor
1161                 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(0));
1162     }
1163 
1164     // This test is too long and too slow and should not be taken as an example for future tests.
1165     @Test
testDirectTargetLoggingWithAppTargetNotRankedPortrait()1166     public void testDirectTargetLoggingWithAppTargetNotRankedPortrait()
1167             throws InterruptedException {
1168         testDirectTargetLoggingWithAppTargetNotRanked(Configuration.ORIENTATION_PORTRAIT, 4);
1169     }
1170 
1171     @Test
testDirectTargetLoggingWithAppTargetNotRankedLandscape()1172     public void testDirectTargetLoggingWithAppTargetNotRankedLandscape()
1173             throws InterruptedException {
1174         testDirectTargetLoggingWithAppTargetNotRanked(Configuration.ORIENTATION_LANDSCAPE, 8);
1175     }
1176 
testDirectTargetLoggingWithAppTargetNotRanked( int orientation, int appTargetsExpected )1177     private void testDirectTargetLoggingWithAppTargetNotRanked(
1178             int orientation, int appTargetsExpected
1179     ) throws InterruptedException {
1180         Configuration configuration =
1181                 new Configuration(InstrumentationRegistry.getInstrumentation().getContext()
1182                         .getResources().getConfiguration());
1183         configuration.orientation = orientation;
1184 
1185         sOverrides.resources = Mockito.spy(
1186                 InstrumentationRegistry.getInstrumentation().getContext().getResources());
1187         when(sOverrides.resources.getConfiguration()).thenReturn(configuration);
1188 
1189         Intent sendIntent = createSendTextIntent();
1190         // We need app targets for direct targets to get displayed
1191         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(15);
1192         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1193                 Mockito.anyBoolean(),
1194                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1195 
1196         // Set up resources
1197         MetricsLogger mockLogger = sOverrides.metricsLogger;
1198         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
1199         // Create direct share target
1200         List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
1201                 resolvedComponentInfos.get(14).getResolveInfoAt(0).activityInfo.packageName);
1202         ResolveInfo ri = ResolverDataProvider.createResolveInfo(16, 0);
1203 
1204         // Start activity
1205         final ChooserWrapperActivity activity = mActivityRule
1206                 .launchActivity(Intent.createChooser(sendIntent, null));
1207         // Insert the direct share target
1208         Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
1209         directShareToShortcutInfos.put(serviceTargets.get(0), null);
1210         InstrumentationRegistry.getInstrumentation().runOnMainSync(
1211                 () -> activity.getAdapter().addServiceResults(
1212                         activity.createTestDisplayResolveInfo(sendIntent,
1213                                 ri,
1214                                 "testLabel",
1215                                 "testInfo",
1216                                 sendIntent,
1217                                 /* resolveInfoPresentationGetter */ null),
1218                         serviceTargets,
1219                         TARGET_TYPE_CHOOSER_TARGET,
1220                         directShareToShortcutInfos,
1221                         List.of())
1222         );
1223         // Thread.sleep shouldn't be a thing in an integration test but it's
1224         // necessary here because of the way the code is structured
1225         // TODO: restructure the tests b/129870719
1226         Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1227 
1228         assertThat(
1229                 String.format("Chooser should have %d targets (%d apps, 1 direct, 15 A-Z)",
1230                         appTargetsExpected + 16, appTargetsExpected),
1231                 activity.getAdapter().getCount(), is(appTargetsExpected + 16));
1232         assertThat("Chooser should have exactly one selectable direct target",
1233                 activity.getAdapter().getSelectableServiceTargetCount(), is(1));
1234         assertThat("The resolver info must match the resolver info used to create the target",
1235                 activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
1236 
1237         // Click on the direct target
1238         String name = serviceTargets.get(0).getTitle().toString();
1239         onView(withText(name))
1240                 .perform(click());
1241         waitForIdle();
1242 
1243         // Currently we're seeing 3 invocations
1244         //      1. ChooserActivity.onCreate()
1245         //      2. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
1246         //      3. ChooserActivity.startSelected -- which is the one we're after
1247         verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
1248         assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
1249                 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
1250         assertThat("The packages shouldn't match for app target and direct target", logMakerCaptor
1251                 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(-1));
1252     }
1253 
1254     @Test
testWorkTab_displayedWhenWorkProfileUserAvailable()1255     public void testWorkTab_displayedWhenWorkProfileUserAvailable() {
1256         // enable the work tab feature flag
1257         ResolverActivity.ENABLE_TABBED_VIEW = true;
1258         Intent sendIntent = createSendTextIntent();
1259         sendIntent.setType("TestType");
1260         markWorkProfileUserAvailable();
1261 
1262         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1263         waitForIdle();
1264 
1265         onView(withId(R.id.tabs)).check(matches(isDisplayed()));
1266     }
1267 
1268     @Test
testWorkTab_hiddenWhenWorkProfileUserNotAvailable()1269     public void testWorkTab_hiddenWhenWorkProfileUserNotAvailable() {
1270         // enable the work tab feature flag
1271         ResolverActivity.ENABLE_TABBED_VIEW = true;
1272         Intent sendIntent = createSendTextIntent();
1273         sendIntent.setType("TestType");
1274 
1275         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1276         waitForIdle();
1277 
1278         onView(withId(R.id.tabs)).check(matches(not(isDisplayed())));
1279     }
1280 
1281     @Test
testWorkTab_eachTabUsesExpectedAdapter()1282     public void testWorkTab_eachTabUsesExpectedAdapter() {
1283         // enable the work tab feature flag
1284         ResolverActivity.ENABLE_TABBED_VIEW = true;
1285         int personalProfileTargets = 3;
1286         int otherProfileTargets = 1;
1287         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1288                 createResolvedComponentsForTestWithOtherProfile(
1289                         personalProfileTargets + otherProfileTargets, /* userID */ 10);
1290         int workProfileTargets = 4;
1291         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(
1292                 workProfileTargets);
1293         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1294         Intent sendIntent = createSendTextIntent();
1295         sendIntent.setType("TestType");
1296         markWorkProfileUserAvailable();
1297 
1298         final ChooserWrapperActivity activity =
1299                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1300         waitForIdle();
1301 
1302         assertThat(activity.getCurrentUserHandle().getIdentifier(), is(0));
1303         onView(withText(R.string.resolver_work_tab)).perform(click());
1304         assertThat(activity.getCurrentUserHandle().getIdentifier(), is(10));
1305         assertThat(activity.getPersonalListAdapter().getCount(), is(personalProfileTargets));
1306         assertThat(activity.getWorkListAdapter().getCount(), is(workProfileTargets));
1307     }
1308 
1309     @Test
testWorkTab_workProfileHasExpectedNumberOfTargets()1310     public void testWorkTab_workProfileHasExpectedNumberOfTargets() throws InterruptedException {
1311         // enable the work tab feature flag
1312         ResolverActivity.ENABLE_TABBED_VIEW = true;
1313         markWorkProfileUserAvailable();
1314         int workProfileTargets = 4;
1315         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1316                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
1317         List<ResolvedComponentInfo> workResolvedComponentInfos =
1318                 createResolvedComponentsForTest(workProfileTargets);
1319         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1320         Intent sendIntent = createSendTextIntent();
1321         sendIntent.setType("TestType");
1322 
1323         final ChooserWrapperActivity activity =
1324                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1325         waitForIdle();
1326         onView(withText(R.string.resolver_work_tab)).perform(click());
1327         waitForIdle();
1328 
1329         assertThat(activity.getWorkListAdapter().getCount(), is(workProfileTargets));
1330     }
1331 
1332     @Test
testWorkTab_selectingWorkTabAppOpensAppInWorkProfile()1333     public void testWorkTab_selectingWorkTabAppOpensAppInWorkProfile() throws InterruptedException {
1334         // enable the work tab feature flag
1335         ResolverActivity.ENABLE_TABBED_VIEW = true;
1336         markWorkProfileUserAvailable();
1337         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1338                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
1339         int workProfileTargets = 4;
1340         List<ResolvedComponentInfo> workResolvedComponentInfos =
1341                 createResolvedComponentsForTest(workProfileTargets);
1342         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1343         Intent sendIntent = createSendTextIntent();
1344         sendIntent.setType("TestType");
1345         ResolveInfo[] chosen = new ResolveInfo[1];
1346         sOverrides.onSafelyStartCallback = targetInfo -> {
1347             chosen[0] = targetInfo.getResolveInfo();
1348             return true;
1349         };
1350 
1351         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1352         waitForIdle();
1353         onView(withText(R.string.resolver_work_tab)).perform(click());
1354         waitForIdle();
1355         // wait for the share sheet to expand
1356         Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1357 
1358         onView(first(allOf(
1359                 withText(workResolvedComponentInfos.get(0)
1360                         .getResolveInfoAt(0).activityInfo.applicationInfo.name),
1361                 isDisplayed())))
1362                 .perform(click());
1363         waitForIdle();
1364         assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0)));
1365     }
1366 
1367     @Test
testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown()1368     public void testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown() {
1369         // enable the work tab feature flag
1370         ResolverActivity.ENABLE_TABBED_VIEW = true;
1371         markWorkProfileUserAvailable();
1372         int workProfileTargets = 4;
1373         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1374                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
1375         List<ResolvedComponentInfo> workResolvedComponentInfos =
1376                 createResolvedComponentsForTest(workProfileTargets);
1377         sOverrides.hasCrossProfileIntents = false;
1378         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1379         Intent sendIntent = createSendTextIntent();
1380         sendIntent.setType("TestType");
1381 
1382         final ChooserWrapperActivity activity =
1383                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1384         waitForIdle();
1385         onView(withText(R.string.resolver_work_tab)).perform(click());
1386         waitForIdle();
1387         onView(withId(R.id.contentPanel))
1388                 .perform(swipeUp());
1389 
1390         onView(withText(R.string.resolver_cant_share_with_work_apps))
1391                 .check(matches(isDisplayed()));
1392     }
1393 
1394     @Test
testWorkTab_workProfileDisabled_emptyStateShown()1395     public void testWorkTab_workProfileDisabled_emptyStateShown() {
1396         // enable the work tab feature flag
1397         ResolverActivity.ENABLE_TABBED_VIEW = true;
1398         markWorkProfileUserAvailable();
1399         int workProfileTargets = 4;
1400         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1401                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
1402         List<ResolvedComponentInfo> workResolvedComponentInfos =
1403                 createResolvedComponentsForTest(workProfileTargets);
1404         sOverrides.isQuietModeEnabled = true;
1405         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1406         Intent sendIntent = createSendTextIntent();
1407         sendIntent.setType("TestType");
1408 
1409         final ChooserWrapperActivity activity =
1410                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1411         waitForIdle();
1412         onView(withId(R.id.contentPanel))
1413                 .perform(swipeUp());
1414         onView(withText(R.string.resolver_work_tab)).perform(click());
1415         waitForIdle();
1416 
1417         onView(withText(R.string.resolver_turn_on_work_apps))
1418                 .check(matches(isDisplayed()));
1419     }
1420 
1421     @Test
testWorkTab_noWorkAppsAvailable_emptyStateShown()1422     public void testWorkTab_noWorkAppsAvailable_emptyStateShown() {
1423         // enable the work tab feature flag
1424         ResolverActivity.ENABLE_TABBED_VIEW = true;
1425         markWorkProfileUserAvailable();
1426         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1427                 createResolvedComponentsForTest(3);
1428         List<ResolvedComponentInfo> workResolvedComponentInfos =
1429                 createResolvedComponentsForTest(0);
1430         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1431         Intent sendIntent = createSendTextIntent();
1432         sendIntent.setType("TestType");
1433 
1434         final ChooserWrapperActivity activity =
1435                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1436         waitForIdle();
1437         onView(withId(R.id.contentPanel))
1438                 .perform(swipeUp());
1439         onView(withText(R.string.resolver_work_tab)).perform(click());
1440         waitForIdle();
1441 
1442         onView(withText(R.string.resolver_no_work_apps_available_share))
1443                 .check(matches(isDisplayed()));
1444     }
1445 
1446     @Test
testWorkTab_xProfileOff_noAppsAvailable_workOff_xProfileOffEmptyStateShown()1447     public void testWorkTab_xProfileOff_noAppsAvailable_workOff_xProfileOffEmptyStateShown() {
1448         // enable the work tab feature flag
1449         ResolverActivity.ENABLE_TABBED_VIEW = true;
1450         markWorkProfileUserAvailable();
1451         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1452                 createResolvedComponentsForTest(3);
1453         List<ResolvedComponentInfo> workResolvedComponentInfos =
1454                 createResolvedComponentsForTest(0);
1455         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1456         sOverrides.isQuietModeEnabled = true;
1457         sOverrides.hasCrossProfileIntents = false;
1458         Intent sendIntent = createSendTextIntent();
1459         sendIntent.setType("TestType");
1460 
1461         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1462         waitForIdle();
1463         onView(withId(R.id.contentPanel))
1464                 .perform(swipeUp());
1465         onView(withText(R.string.resolver_work_tab)).perform(click());
1466         waitForIdle();
1467 
1468         onView(withText(R.string.resolver_cant_share_with_work_apps))
1469                 .check(matches(isDisplayed()));
1470     }
1471 
1472     @Test
testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown()1473     public void testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown() {
1474         // enable the work tab feature flag
1475         ResolverActivity.ENABLE_TABBED_VIEW = true;
1476         markWorkProfileUserAvailable();
1477         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1478                 createResolvedComponentsForTest(3);
1479         List<ResolvedComponentInfo> workResolvedComponentInfos =
1480                 createResolvedComponentsForTest(0);
1481         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1482         sOverrides.isQuietModeEnabled = true;
1483         Intent sendIntent = createSendTextIntent();
1484         sendIntent.setType("TestType");
1485 
1486         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1487         waitForIdle();
1488         onView(withId(R.id.contentPanel))
1489                 .perform(swipeUp());
1490         onView(withText(R.string.resolver_work_tab)).perform(click());
1491         waitForIdle();
1492 
1493         onView(withText(R.string.resolver_no_work_apps_available_share))
1494                 .check(matches(isDisplayed()));
1495     }
1496 
1497     @Test
testAppTargetLogging()1498     public void testAppTargetLogging() throws InterruptedException {
1499         Intent sendIntent = createSendTextIntent();
1500         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
1501 
1502         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1503                 Mockito.anyBoolean(),
1504                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1505 
1506         final ChooserWrapperActivity activity = mActivityRule
1507                 .launchActivity(Intent.createChooser(sendIntent, null));
1508         waitForIdle();
1509 
1510         assertThat(activity.getAdapter().getCount(), is(2));
1511         onView(withId(R.id.profile_button)).check(doesNotExist());
1512 
1513         ResolveInfo[] chosen = new ResolveInfo[1];
1514         sOverrides.onSafelyStartCallback = targetInfo -> {
1515             chosen[0] = targetInfo.getResolveInfo();
1516             return true;
1517         };
1518 
1519         ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
1520         onView(withText(toChoose.activityInfo.name))
1521                 .perform(click());
1522         waitForIdle();
1523 
1524         ChooserActivityLoggerFake logger =
1525                 (ChooserActivityLoggerFake) activity.getChooserActivityLogger();
1526         assertThat(logger.numCalls(), is(6));
1527         // first one should be SHARESHEET_TRIGGERED uievent
1528         assertThat(logger.get(0).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1529         assertThat(logger.get(0).event.getId(),
1530                 is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId()));
1531         // second one should be SHARESHEET_STARTED event
1532         assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED));
1533         assertThat(logger.get(1).intent, is(Intent.ACTION_SEND));
1534         assertThat(logger.get(1).mimeType, is("text/plain"));
1535         assertThat(logger.get(1).packageName, is("com.android.frameworks.coretests"));
1536         assertThat(logger.get(1).appProvidedApp, is(0));
1537         assertThat(logger.get(1).appProvidedDirect, is(0));
1538         assertThat(logger.get(1).isWorkprofile, is(false));
1539         assertThat(logger.get(1).previewType, is(3));
1540         // third one should be SHARESHEET_APP_LOAD_COMPLETE uievent
1541         assertThat(logger.get(2).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1542         assertThat(logger.get(2).event.getId(),
1543                 is(ChooserActivityLogger
1544                         .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId()));
1545         // fourth and fifth are just artifacts of test set-up
1546         // sixth one should be ranking atom with SHARESHEET_APP_TARGET_SELECTED event
1547         assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED));
1548         assertThat(logger.get(5).targetType,
1549                 is(ChooserActivityLogger
1550                         .SharesheetTargetSelectedEvent.SHARESHEET_APP_TARGET_SELECTED.getId()));
1551     }
1552 
1553     @Test
testDirectTargetLogging()1554     public void testDirectTargetLogging() throws InterruptedException {
1555         Intent sendIntent = createSendTextIntent();
1556         // We need app targets for direct targets to get displayed
1557         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
1558         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1559                 Mockito.anyBoolean(),
1560                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1561 
1562         // Create direct share target
1563         List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
1564                 resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
1565         ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
1566 
1567         // Start activity
1568         final ChooserWrapperActivity activity = mActivityRule
1569                 .launchActivity(Intent.createChooser(sendIntent, null));
1570 
1571         // Insert the direct share target
1572         Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
1573         directShareToShortcutInfos.put(serviceTargets.get(0), null);
1574         InstrumentationRegistry.getInstrumentation().runOnMainSync(
1575                 () -> activity.getAdapter().addServiceResults(
1576                         activity.createTestDisplayResolveInfo(sendIntent,
1577                                 ri,
1578                                 "testLabel",
1579                                 "testInfo",
1580                                 sendIntent,
1581                                 /* resolveInfoPresentationGetter */ null),
1582                         serviceTargets,
1583                         TARGET_TYPE_CHOOSER_TARGET,
1584                         directShareToShortcutInfos,
1585                         null)
1586         );
1587         // Thread.sleep shouldn't be a thing in an integration test but it's
1588         // necessary here because of the way the code is structured
1589         // TODO: restructure the tests b/129870719
1590         Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1591 
1592         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
1593                 activity.getAdapter().getCount(), is(3));
1594         assertThat("Chooser should have exactly one selectable direct target",
1595                 activity.getAdapter().getSelectableServiceTargetCount(), is(1));
1596         assertThat("The resolver info must match the resolver info used to create the target",
1597                 activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
1598 
1599         // Click on the direct target
1600         String name = serviceTargets.get(0).getTitle().toString();
1601         onView(withText(name))
1602                 .perform(click());
1603         waitForIdle();
1604 
1605         ChooserActivityLoggerFake logger =
1606                 (ChooserActivityLoggerFake) activity.getChooserActivityLogger();
1607         assertThat(logger.numCalls(), is(6));
1608         // first one should be SHARESHEET_TRIGGERED uievent
1609         assertThat(logger.get(0).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1610         assertThat(logger.get(0).event.getId(),
1611                 is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId()));
1612         // second one should be SHARESHEET_STARTED event
1613         assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED));
1614         assertThat(logger.get(1).intent, is(Intent.ACTION_SEND));
1615         assertThat(logger.get(1).mimeType, is("text/plain"));
1616         assertThat(logger.get(1).packageName, is("com.android.frameworks.coretests"));
1617         assertThat(logger.get(1).appProvidedApp, is(0));
1618         assertThat(logger.get(1).appProvidedDirect, is(0));
1619         assertThat(logger.get(1).isWorkprofile, is(false));
1620         assertThat(logger.get(1).previewType, is(3));
1621         // third one should be SHARESHEET_APP_LOAD_COMPLETE uievent
1622         assertThat(logger.get(2).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1623         assertThat(logger.get(2).event.getId(),
1624                 is(ChooserActivityLogger
1625                         .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId()));
1626         // fourth and fifth are just artifacts of test set-up
1627         // sixth one should be ranking atom with SHARESHEET_COPY_TARGET_SELECTED event
1628         assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED));
1629         assertThat(logger.get(5).targetType,
1630                 is(ChooserActivityLogger
1631                         .SharesheetTargetSelectedEvent.SHARESHEET_SERVICE_TARGET_SELECTED.getId()));
1632     }
1633 
1634     @Test
testCopyTextToClipboardLogging()1635     public void testCopyTextToClipboardLogging() throws Exception {
1636         Intent sendIntent = createSendTextIntent();
1637         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
1638 
1639         when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
1640                 Mockito.anyBoolean(),
1641                 Mockito.anyBoolean(),
1642                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1643 
1644         final ChooserWrapperActivity activity = mActivityRule
1645                 .launchActivity(Intent.createChooser(sendIntent, null));
1646         waitForIdle();
1647 
1648         onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
1649         onView(withId(R.id.chooser_copy_button)).perform(click());
1650 
1651         ChooserActivityLoggerFake logger =
1652                 (ChooserActivityLoggerFake) activity.getChooserActivityLogger();
1653         assertThat(logger.numCalls(), is(6));
1654         // first one should be SHARESHEET_TRIGGERED uievent
1655         assertThat(logger.get(0).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1656         assertThat(logger.get(0).event.getId(),
1657                 is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId()));
1658         // second one should be SHARESHEET_STARTED event
1659         assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED));
1660         assertThat(logger.get(1).intent, is(Intent.ACTION_SEND));
1661         assertThat(logger.get(1).mimeType, is("text/plain"));
1662         assertThat(logger.get(1).packageName, is("com.android.frameworks.coretests"));
1663         assertThat(logger.get(1).appProvidedApp, is(0));
1664         assertThat(logger.get(1).appProvidedDirect, is(0));
1665         assertThat(logger.get(1).isWorkprofile, is(false));
1666         assertThat(logger.get(1).previewType, is(3));
1667         // third one should be SHARESHEET_APP_LOAD_COMPLETE uievent
1668         assertThat(logger.get(2).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1669         assertThat(logger.get(2).event.getId(),
1670                 is(ChooserActivityLogger
1671                         .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId()));
1672         // fourth and fifth are just artifacts of test set-up
1673         // sixth one should be ranking atom with SHARESHEET_COPY_TARGET_SELECTED event
1674         assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED));
1675         assertThat(logger.get(5).targetType,
1676                 is(ChooserActivityLogger
1677                         .SharesheetTargetSelectedEvent.SHARESHEET_COPY_TARGET_SELECTED.getId()));
1678     }
1679 
1680     @Test
testSwitchProfileLogging()1681     public void testSwitchProfileLogging() throws InterruptedException {
1682         // enable the work tab feature flag
1683         ResolverActivity.ENABLE_TABBED_VIEW = true;
1684         markWorkProfileUserAvailable();
1685         int workProfileTargets = 4;
1686         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1687                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
1688         List<ResolvedComponentInfo> workResolvedComponentInfos =
1689                 createResolvedComponentsForTest(workProfileTargets);
1690         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1691         Intent sendIntent = createSendTextIntent();
1692         sendIntent.setType("TestType");
1693 
1694         final ChooserWrapperActivity activity =
1695                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1696         waitForIdle();
1697         onView(withText(R.string.resolver_work_tab)).perform(click());
1698         waitForIdle();
1699         onView(withText(R.string.resolver_personal_tab)).perform(click());
1700         waitForIdle();
1701 
1702         ChooserActivityLoggerFake logger =
1703                 (ChooserActivityLoggerFake) activity.getChooserActivityLogger();
1704         assertThat(logger.numCalls(), is(8));
1705         // first one should be SHARESHEET_TRIGGERED uievent
1706         assertThat(logger.get(0).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1707         assertThat(logger.get(0).event.getId(),
1708                 is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId()));
1709         // second one should be SHARESHEET_STARTED event
1710         assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED));
1711         assertThat(logger.get(1).intent, is(Intent.ACTION_SEND));
1712         assertThat(logger.get(1).mimeType, is("TestType"));
1713         assertThat(logger.get(1).packageName, is("com.android.frameworks.coretests"));
1714         assertThat(logger.get(1).appProvidedApp, is(0));
1715         assertThat(logger.get(1).appProvidedDirect, is(0));
1716         assertThat(logger.get(1).isWorkprofile, is(false));
1717         assertThat(logger.get(1).previewType, is(3));
1718         // third one should be SHARESHEET_APP_LOAD_COMPLETE uievent
1719         assertThat(logger.get(2).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1720         assertThat(logger.get(2).event.getId(),
1721                 is(ChooserActivityLogger
1722                         .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId()));
1723         // fourth one is artifact of test setup
1724         // fifth one is switch to work profile
1725         assertThat(logger.get(4).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1726         assertThat(logger.get(4).event.getId(),
1727                 is(ChooserActivityLogger
1728                         .SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED.getId()));
1729         // sixth one should be SHARESHEET_APP_LOAD_COMPLETE uievent
1730         assertThat(logger.get(5).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1731         assertThat(logger.get(5).event.getId(),
1732                 is(ChooserActivityLogger
1733                         .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId()));
1734         // seventh one is artifact of test setup
1735         // eigth one is switch to work profile
1736         assertThat(logger.get(7).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
1737         assertThat(logger.get(7).event.getId(),
1738                 is(ChooserActivityLogger
1739                         .SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED.getId()));
1740     }
1741 
1742     @Test
testAutolaunch_singleTarget_wifthWorkProfileAndTabbedViewOff_noAutolaunch()1743     public void testAutolaunch_singleTarget_wifthWorkProfileAndTabbedViewOff_noAutolaunch() {
1744         ResolverActivity.ENABLE_TABBED_VIEW = false;
1745         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1746                 createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
1747         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1748                 Mockito.anyBoolean(),
1749                 Mockito.isA(List.class)))
1750                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
1751         Intent sendIntent = createSendTextIntent();
1752         sendIntent.setType("TestType");
1753         ResolveInfo[] chosen = new ResolveInfo[1];
1754         sOverrides.onSafelyStartCallback = targetInfo -> {
1755             chosen[0] = targetInfo.getResolveInfo();
1756             return true;
1757         };
1758         waitForIdle();
1759 
1760         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1761         waitForIdle();
1762 
1763         assertTrue(chosen[0] == null);
1764     }
1765 
1766     @Test
testAutolaunch_singleTarget_noWorkProfile_autolaunch()1767     public void testAutolaunch_singleTarget_noWorkProfile_autolaunch() {
1768         ResolverActivity.ENABLE_TABBED_VIEW = false;
1769         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1770                 createResolvedComponentsForTest(1);
1771         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1772                 Mockito.anyBoolean(),
1773                 Mockito.isA(List.class)))
1774                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
1775         Intent sendIntent = createSendTextIntent();
1776         sendIntent.setType("TestType");
1777         ResolveInfo[] chosen = new ResolveInfo[1];
1778         sOverrides.onSafelyStartCallback = targetInfo -> {
1779             chosen[0] = targetInfo.getResolveInfo();
1780             return true;
1781         };
1782         waitForIdle();
1783 
1784         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1785         waitForIdle();
1786 
1787         assertThat(chosen[0], is(personalResolvedComponentInfos.get(0).getResolveInfoAt(0)));
1788     }
1789 
1790     @Test
testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_autolaunch()1791     public void testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_autolaunch() {
1792         // enable the work tab feature flag
1793         ResolverActivity.ENABLE_TABBED_VIEW = true;
1794         markWorkProfileUserAvailable();
1795         int workProfileTargets = 4;
1796         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1797                 createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
1798         List<ResolvedComponentInfo> workResolvedComponentInfos =
1799                 createResolvedComponentsForTest(workProfileTargets);
1800         sOverrides.hasCrossProfileIntents = false;
1801         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1802         Intent sendIntent = createSendTextIntent();
1803         ResolveInfo[] chosen = new ResolveInfo[1];
1804         sOverrides.onSafelyStartCallback = targetInfo -> {
1805             chosen[0] = targetInfo.getResolveInfo();
1806             return true;
1807         };
1808 
1809         mActivityRule.launchActivity(sendIntent);
1810         waitForIdle();
1811 
1812         assertThat(chosen[0], is(personalResolvedComponentInfos.get(1).getResolveInfoAt(0)));
1813     }
1814 
1815     @Test
testOneInitialIntent_noAutolaunch()1816     public void testOneInitialIntent_noAutolaunch() {
1817         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1818                 createResolvedComponentsForTest(1);
1819         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1820                 Mockito.anyBoolean(),
1821                 Mockito.isA(List.class)))
1822                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
1823         Intent chooserIntent = createChooserIntent(createSendTextIntent(),
1824                 new Intent[] {new Intent("action.fake")});
1825         ResolveInfo[] chosen = new ResolveInfo[1];
1826         sOverrides.onSafelyStartCallback = targetInfo -> {
1827             chosen[0] = targetInfo.getResolveInfo();
1828             return true;
1829         };
1830         sOverrides.packageManager = mock(PackageManager.class);
1831         ResolveInfo ri = createFakeResolveInfo();
1832         when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(ri);
1833         waitForIdle();
1834 
1835         ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent);
1836         waitForIdle();
1837 
1838         assertNull(chosen[0]);
1839         assertThat(activity.getPersonalListAdapter().getCallerTargetCount(), is(1));
1840     }
1841 
1842     @Test
testWorkTab_withInitialIntents_workTabDoesNotIncludePersonalInitialIntents()1843     public void testWorkTab_withInitialIntents_workTabDoesNotIncludePersonalInitialIntents() {
1844         // enable the work tab feature flag
1845         ResolverActivity.ENABLE_TABBED_VIEW = true;
1846         markWorkProfileUserAvailable();
1847         int workProfileTargets = 1;
1848         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1849                 createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
1850         List<ResolvedComponentInfo> workResolvedComponentInfos =
1851                 createResolvedComponentsForTest(workProfileTargets);
1852         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1853         Intent[] initialIntents = {
1854                 new Intent("action.fake1"),
1855                 new Intent("action.fake2")
1856         };
1857         Intent chooserIntent = createChooserIntent(createSendTextIntent(), initialIntents);
1858         sOverrides.packageManager = mock(PackageManager.class);
1859         when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt()))
1860                 .thenReturn(createFakeResolveInfo());
1861         waitForIdle();
1862 
1863         ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent);
1864         waitForIdle();
1865 
1866         assertThat(activity.getPersonalListAdapter().getCallerTargetCount(), is(2));
1867         assertThat(activity.getWorkListAdapter().getCallerTargetCount(), is(0));
1868     }
1869 
1870     @Test
testWorkTab_xProfileIntentsDisabled_personalToWork_nonSendIntent_emptyStateShown()1871     public void testWorkTab_xProfileIntentsDisabled_personalToWork_nonSendIntent_emptyStateShown() {
1872         // enable the work tab feature flag
1873         ResolverActivity.ENABLE_TABBED_VIEW = true;
1874         markWorkProfileUserAvailable();
1875         int workProfileTargets = 4;
1876         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1877                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
1878         List<ResolvedComponentInfo> workResolvedComponentInfos =
1879                 createResolvedComponentsForTest(workProfileTargets);
1880         sOverrides.hasCrossProfileIntents = false;
1881         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1882         Intent[] initialIntents = {
1883                 new Intent("action.fake1"),
1884                 new Intent("action.fake2")
1885         };
1886         Intent chooserIntent = createChooserIntent(new Intent(), initialIntents);
1887         sOverrides.packageManager = mock(PackageManager.class);
1888         when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt()))
1889                 .thenReturn(createFakeResolveInfo());
1890 
1891         final ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent);
1892         waitForIdle();
1893         onView(withText(R.string.resolver_work_tab)).perform(click());
1894         waitForIdle();
1895         onView(withId(R.id.contentPanel))
1896                 .perform(swipeUp());
1897 
1898         onView(withText(R.string.resolver_cant_access_work_apps))
1899                 .check(matches(isDisplayed()));
1900     }
1901 
1902     @Test
testWorkTab_noWorkAppsAvailable_nonSendIntent_emptyStateShown()1903     public void testWorkTab_noWorkAppsAvailable_nonSendIntent_emptyStateShown() {
1904         // enable the work tab feature flag
1905         ResolverActivity.ENABLE_TABBED_VIEW = true;
1906         markWorkProfileUserAvailable();
1907         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1908                 createResolvedComponentsForTest(3);
1909         List<ResolvedComponentInfo> workResolvedComponentInfos =
1910                 createResolvedComponentsForTest(0);
1911         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1912         Intent[] initialIntents = {
1913                 new Intent("action.fake1"),
1914                 new Intent("action.fake2")
1915         };
1916         Intent chooserIntent = createChooserIntent(new Intent(), initialIntents);
1917         sOverrides.packageManager = mock(PackageManager.class);
1918         when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt()))
1919                 .thenReturn(createFakeResolveInfo());
1920 
1921         mActivityRule.launchActivity(chooserIntent);
1922         waitForIdle();
1923         onView(withId(R.id.contentPanel))
1924                 .perform(swipeUp());
1925         onView(withText(R.string.resolver_work_tab)).perform(click());
1926         waitForIdle();
1927 
1928         onView(withText(R.string.resolver_no_work_apps_available_resolve))
1929                 .check(matches(isDisplayed()));
1930     }
1931 
1932     @Test
testDeduplicateCallerTargetRankedTarget()1933     public void testDeduplicateCallerTargetRankedTarget() {
1934         // Create 4 ranked app targets.
1935         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1936                 createResolvedComponentsForTest(4);
1937         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1938                 Mockito.anyBoolean(),
1939                 Mockito.isA(List.class)))
1940                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
1941         // Create caller target which is duplicate with one of app targets
1942         Intent chooserIntent = createChooserIntent(createSendTextIntent(),
1943                 new Intent[] {new Intent("action.fake")});
1944         sOverrides.packageManager = mock(PackageManager.class);
1945         ResolveInfo ri = ResolverDataProvider.createResolveInfo(0,
1946                 UserHandle.USER_CURRENT);
1947         when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(ri);
1948         waitForIdle();
1949 
1950         ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent);
1951         waitForIdle();
1952 
1953         // Total 4 targets (1 caller target, 3 ranked targets)
1954         assertThat(activity.getAdapter().getCount(), is(4));
1955         assertThat(activity.getAdapter().getCallerTargetCount(), is(1));
1956         assertThat(activity.getAdapter().getRankedTargetCount(), is(3));
1957     }
1958 
1959     @Test
testWorkTab_selectingWorkTabWithPausedWorkProfile_directShareTargetsNotQueried()1960     public void testWorkTab_selectingWorkTabWithPausedWorkProfile_directShareTargetsNotQueried() {
1961         // enable the work tab feature flag
1962         ResolverActivity.ENABLE_TABBED_VIEW = true;
1963         markWorkProfileUserAvailable();
1964         List<ResolvedComponentInfo> personalResolvedComponentInfos =
1965                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
1966         List<ResolvedComponentInfo> workResolvedComponentInfos =
1967                 createResolvedComponentsForTest(3);
1968         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
1969         sOverrides.isQuietModeEnabled = true;
1970         boolean[] isQueryDirectShareCalledOnWorkProfile = new boolean[] { false };
1971         sOverrides.onQueryDirectShareTargets = chooserListAdapter -> {
1972             isQueryDirectShareCalledOnWorkProfile[0] =
1973                     (chooserListAdapter.getUserHandle().getIdentifier() == 10);
1974             return null;
1975         };
1976         boolean[] isQueryTargetServicesCalledOnWorkProfile = new boolean[] { false };
1977         sOverrides.onQueryTargetServices = chooserListAdapter -> {
1978             isQueryTargetServicesCalledOnWorkProfile[0] =
1979                     (chooserListAdapter.getUserHandle().getIdentifier() == 10);
1980             return null;
1981         };
1982         Intent sendIntent = createSendTextIntent();
1983         sendIntent.setType("TestType");
1984 
1985         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1986         waitForIdle();
1987         onView(withId(R.id.contentPanel))
1988                 .perform(swipeUp());
1989         onView(withText(R.string.resolver_work_tab)).perform(click());
1990         waitForIdle();
1991 
1992         assertFalse("Direct share targets were queried on a paused work profile",
1993                 isQueryDirectShareCalledOnWorkProfile[0]);
1994         assertFalse("Target services were queried on a paused work profile",
1995                 isQueryTargetServicesCalledOnWorkProfile[0]);
1996     }
1997 
1998     @Test
testWorkTab_selectingWorkTabWithNotRunningWorkUser_directShareTargetsNotQueried()1999     public void testWorkTab_selectingWorkTabWithNotRunningWorkUser_directShareTargetsNotQueried() {
2000         // enable the work tab feature flag
2001         ResolverActivity.ENABLE_TABBED_VIEW = true;
2002         markWorkProfileUserAvailable();
2003         List<ResolvedComponentInfo> personalResolvedComponentInfos =
2004                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
2005         List<ResolvedComponentInfo> workResolvedComponentInfos =
2006                 createResolvedComponentsForTest(3);
2007         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
2008         sOverrides.isWorkProfileUserRunning = false;
2009         boolean[] isQueryDirectShareCalledOnWorkProfile = new boolean[] { false };
2010         sOverrides.onQueryDirectShareTargets = chooserListAdapter -> {
2011             isQueryDirectShareCalledOnWorkProfile[0] =
2012                     (chooserListAdapter.getUserHandle().getIdentifier() == 10);
2013             return null;
2014         };
2015         boolean[] isQueryTargetServicesCalledOnWorkProfile = new boolean[] { false };
2016         sOverrides.onQueryTargetServices = chooserListAdapter -> {
2017             isQueryTargetServicesCalledOnWorkProfile[0] =
2018                     (chooserListAdapter.getUserHandle().getIdentifier() == 10);
2019             return null;
2020         };
2021         Intent sendIntent = createSendTextIntent();
2022         sendIntent.setType("TestType");
2023 
2024         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
2025         waitForIdle();
2026         onView(withId(R.id.contentPanel))
2027                 .perform(swipeUp());
2028         onView(withText(R.string.resolver_work_tab)).perform(click());
2029         waitForIdle();
2030 
2031         assertFalse("Direct share targets were queried on a locked work profile user",
2032                 isQueryDirectShareCalledOnWorkProfile[0]);
2033         assertFalse("Target services were queried on a locked work profile user",
2034                 isQueryTargetServicesCalledOnWorkProfile[0]);
2035     }
2036 
2037     @Test
testWorkTab_workUserNotRunning_workTargetsShown()2038     public void testWorkTab_workUserNotRunning_workTargetsShown() {
2039         // enable the work tab feature flag
2040         ResolverActivity.ENABLE_TABBED_VIEW = true;
2041         markWorkProfileUserAvailable();
2042         List<ResolvedComponentInfo> personalResolvedComponentInfos =
2043                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
2044         List<ResolvedComponentInfo> workResolvedComponentInfos =
2045                 createResolvedComponentsForTest(3);
2046         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
2047         Intent sendIntent = createSendTextIntent();
2048         sendIntent.setType("TestType");
2049         sOverrides.isWorkProfileUserRunning = false;
2050 
2051         final ChooserWrapperActivity activity =
2052                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
2053         waitForIdle();
2054         onView(withId(R.id.contentPanel))
2055                 .perform(swipeUp());
2056         onView(withText(R.string.resolver_work_tab)).perform(click());
2057         waitForIdle();
2058 
2059         assertEquals(3, activity.getWorkListAdapter().getCount());
2060     }
2061 
2062     @Test
testWorkTab_selectingWorkTabWithLockedWorkUser_directShareTargetsNotQueried()2063     public void testWorkTab_selectingWorkTabWithLockedWorkUser_directShareTargetsNotQueried() {
2064         // enable the work tab feature flag
2065         ResolverActivity.ENABLE_TABBED_VIEW = true;
2066         markWorkProfileUserAvailable();
2067         List<ResolvedComponentInfo> personalResolvedComponentInfos =
2068                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
2069         List<ResolvedComponentInfo> workResolvedComponentInfos =
2070                 createResolvedComponentsForTest(3);
2071         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
2072         sOverrides.isWorkProfileUserUnlocked = false;
2073         boolean[] isQueryDirectShareCalledOnWorkProfile = new boolean[] { false };
2074         sOverrides.onQueryDirectShareTargets = chooserListAdapter -> {
2075             isQueryDirectShareCalledOnWorkProfile[0] =
2076                     (chooserListAdapter.getUserHandle().getIdentifier() == 10);
2077             return null;
2078         };
2079         boolean[] isQueryTargetServicesCalledOnWorkProfile = new boolean[] { false };
2080         sOverrides.onQueryTargetServices = chooserListAdapter -> {
2081             isQueryTargetServicesCalledOnWorkProfile[0] =
2082                     (chooserListAdapter.getUserHandle().getIdentifier() == 10);
2083             return null;
2084         };
2085         Intent sendIntent = createSendTextIntent();
2086         sendIntent.setType("TestType");
2087 
2088         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
2089         waitForIdle();
2090         onView(withId(R.id.contentPanel))
2091                 .perform(swipeUp());
2092         onView(withText(R.string.resolver_work_tab)).perform(click());
2093         waitForIdle();
2094 
2095         assertFalse("Direct share targets were queried on a locked work profile user",
2096                 isQueryDirectShareCalledOnWorkProfile[0]);
2097         assertFalse("Target services were queried on a locked work profile user",
2098                 isQueryTargetServicesCalledOnWorkProfile[0]);
2099     }
2100 
2101     @Test
testWorkTab_workUserLocked_workTargetsShown()2102     public void testWorkTab_workUserLocked_workTargetsShown() {
2103         // enable the work tab feature flag
2104         ResolverActivity.ENABLE_TABBED_VIEW = true;
2105         markWorkProfileUserAvailable();
2106         List<ResolvedComponentInfo> personalResolvedComponentInfos =
2107                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
2108         List<ResolvedComponentInfo> workResolvedComponentInfos =
2109                 createResolvedComponentsForTest(3);
2110         setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
2111         Intent sendIntent = createSendTextIntent();
2112         sendIntent.setType("TestType");
2113         sOverrides.isWorkProfileUserUnlocked = false;
2114 
2115         final ChooserWrapperActivity activity =
2116                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
2117         waitForIdle();
2118         onView(withId(R.id.contentPanel))
2119                 .perform(swipeUp());
2120         onView(withText(R.string.resolver_work_tab)).perform(click());
2121         waitForIdle();
2122 
2123         assertEquals(3, activity.getWorkListAdapter().getCount());
2124     }
2125 
createChooserIntent(Intent intent, Intent[] initialIntents)2126     private Intent createChooserIntent(Intent intent, Intent[] initialIntents) {
2127         Intent chooserIntent = new Intent();
2128         chooserIntent.setAction(Intent.ACTION_CHOOSER);
2129         chooserIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
2130         chooserIntent.putExtra(Intent.EXTRA_TITLE, "some title");
2131         chooserIntent.putExtra(Intent.EXTRA_INTENT, intent);
2132         chooserIntent.setType("text/plain");
2133         if (initialIntents != null) {
2134             chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, initialIntents);
2135         }
2136         return chooserIntent;
2137     }
2138 
createFakeResolveInfo()2139     private ResolveInfo createFakeResolveInfo() {
2140         ResolveInfo ri = new ResolveInfo();
2141         ri.activityInfo = new ActivityInfo();
2142         ri.activityInfo.name = "FakeActivityName";
2143         ri.activityInfo.packageName = "fake.package.name";
2144         ri.activityInfo.applicationInfo = new ApplicationInfo();
2145         ri.activityInfo.applicationInfo.packageName = "fake.package.name";
2146         return ri;
2147     }
2148 
createSendTextIntent()2149     private Intent createSendTextIntent() {
2150         Intent sendIntent = new Intent();
2151         sendIntent.setAction(Intent.ACTION_SEND);
2152         sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
2153         sendIntent.setType("text/plain");
2154         return sendIntent;
2155     }
2156 
createSendTextIntentWithPreview(String title, Uri imageThumbnail)2157     private Intent createSendTextIntentWithPreview(String title, Uri imageThumbnail) {
2158         Intent sendIntent = new Intent();
2159         sendIntent.setAction(Intent.ACTION_SEND);
2160         sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
2161         sendIntent.putExtra(Intent.EXTRA_TITLE, title);
2162         if (imageThumbnail != null) {
2163             ClipData.Item clipItem = new ClipData.Item(imageThumbnail);
2164             sendIntent.setClipData(new ClipData("Clip Label", new String[]{"image/png"}, clipItem));
2165         }
2166 
2167         return sendIntent;
2168     }
2169 
createSendUriIntentWithPreview(ArrayList<Uri> uris)2170     private Intent createSendUriIntentWithPreview(ArrayList<Uri> uris) {
2171         Intent sendIntent = new Intent();
2172 
2173         if (uris.size() > 1) {
2174             sendIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
2175             sendIntent.putExtra(Intent.EXTRA_STREAM, uris);
2176         } else {
2177             sendIntent.setAction(Intent.ACTION_SEND);
2178             sendIntent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
2179         }
2180 
2181         return sendIntent;
2182     }
2183 
createViewTextIntent()2184     private Intent createViewTextIntent() {
2185         Intent viewIntent = new Intent();
2186         viewIntent.setAction(Intent.ACTION_VIEW);
2187         viewIntent.putExtra(Intent.EXTRA_TEXT, "testing intent viewing");
2188         return viewIntent;
2189     }
2190 
createResolvedComponentsForTest(int numberOfResults)2191     private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
2192         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
2193         for (int i = 0; i < numberOfResults; i++) {
2194             infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
2195         }
2196         return infoList;
2197     }
2198 
createResolvedComponentsForTestWithOtherProfile( int numberOfResults)2199     private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
2200             int numberOfResults) {
2201         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
2202         for (int i = 0; i < numberOfResults; i++) {
2203             if (i == 0) {
2204                 infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i));
2205             } else {
2206                 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
2207             }
2208         }
2209         return infoList;
2210     }
2211 
createResolvedComponentsForTestWithOtherProfile( int numberOfResults, int userId)2212     private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
2213             int numberOfResults, int userId) {
2214         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
2215         for (int i = 0; i < numberOfResults; i++) {
2216             if (i == 0) {
2217                 infoList.add(
2218                         ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
2219             } else {
2220                 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
2221             }
2222         }
2223         return infoList;
2224     }
2225 
createResolvedComponentsForTestWithUserId( int numberOfResults, int userId)2226     private List<ResolvedComponentInfo> createResolvedComponentsForTestWithUserId(
2227             int numberOfResults, int userId) {
2228         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
2229         for (int i = 0; i < numberOfResults; i++) {
2230             infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
2231         }
2232         return infoList;
2233     }
2234 
createDirectShareTargets(int numberOfResults, String packageName)2235     private List<ChooserTarget> createDirectShareTargets(int numberOfResults, String packageName) {
2236         Icon icon = Icon.createWithBitmap(createBitmap());
2237         String testTitle = "testTitle";
2238         List<ChooserTarget> targets = new ArrayList<>();
2239         for (int i = 0; i < numberOfResults; i++) {
2240             ComponentName componentName;
2241             if (packageName.isEmpty()) {
2242                 componentName = ResolverDataProvider.createComponentName(i);
2243             } else {
2244                 componentName = new ComponentName(packageName, packageName + ".class");
2245             }
2246             ChooserTarget tempTarget = new ChooserTarget(
2247                     testTitle + i,
2248                     icon,
2249                     (float) (1 - ((i + 1) / 10.0)),
2250                     componentName,
2251                     null);
2252             targets.add(tempTarget);
2253         }
2254         return targets;
2255     }
2256 
waitForIdle()2257     private void waitForIdle() {
2258         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
2259     }
2260 
createBitmap()2261     private Bitmap createBitmap() {
2262         int width = 200;
2263         int height = 200;
2264         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
2265         Canvas canvas = new Canvas(bitmap);
2266 
2267         Paint paint = new Paint();
2268         paint.setColor(Color.RED);
2269         paint.setStyle(Paint.Style.FILL);
2270         canvas.drawPaint(paint);
2271 
2272         paint.setColor(Color.WHITE);
2273         paint.setAntiAlias(true);
2274         paint.setTextSize(14.f);
2275         paint.setTextAlign(Paint.Align.CENTER);
2276         canvas.drawText("Hi!", (width / 2.f), (height / 2.f), paint);
2277 
2278         return bitmap;
2279     }
2280 
createShortcuts(Context context)2281     private List<ShareShortcutInfo> createShortcuts(Context context) {
2282         Intent testIntent = new Intent("TestIntent");
2283 
2284         List<ShareShortcutInfo> shortcuts = new ArrayList<>();
2285         shortcuts.add(new ShareShortcutInfo(
2286                 new ShortcutInfo.Builder(context, "shortcut1")
2287                         .setIntent(testIntent).setShortLabel("label1").setRank(3).build(), // 0  2
2288                 new ComponentName("package1", "class1")));
2289         shortcuts.add(new ShareShortcutInfo(
2290                 new ShortcutInfo.Builder(context, "shortcut2")
2291                         .setIntent(testIntent).setShortLabel("label2").setRank(7).build(), // 1  3
2292                 new ComponentName("package2", "class2")));
2293         shortcuts.add(new ShareShortcutInfo(
2294                 new ShortcutInfo.Builder(context, "shortcut3")
2295                         .setIntent(testIntent).setShortLabel("label3").setRank(1).build(), // 2  0
2296                 new ComponentName("package3", "class3")));
2297         shortcuts.add(new ShareShortcutInfo(
2298                 new ShortcutInfo.Builder(context, "shortcut4")
2299                         .setIntent(testIntent).setShortLabel("label4").setRank(3).build(), // 3  2
2300                 new ComponentName("package4", "class4")));
2301 
2302         return shortcuts;
2303     }
2304 
assertCorrectShortcutToChooserTargetConversion(List<ShareShortcutInfo> shortcuts, List<ChooserTarget> chooserTargets, int[] expectedOrder, float[] expectedScores)2305     private void assertCorrectShortcutToChooserTargetConversion(List<ShareShortcutInfo> shortcuts,
2306             List<ChooserTarget> chooserTargets, int[] expectedOrder, float[] expectedScores) {
2307         assertEquals(expectedOrder.length, chooserTargets.size());
2308         for (int i = 0; i < chooserTargets.size(); i++) {
2309             ChooserTarget ct = chooserTargets.get(i);
2310             ShortcutInfo si = shortcuts.get(expectedOrder[i]).getShortcutInfo();
2311             ComponentName cn = shortcuts.get(expectedOrder[i]).getTargetComponent();
2312 
2313             assertEquals(si.getId(), ct.getIntentExtras().getString(Intent.EXTRA_SHORTCUT_ID));
2314             assertEquals(si.getShortLabel(), ct.getTitle());
2315             assertThat(Math.abs(expectedScores[i] - ct.getScore()) < 0.000001, is(true));
2316             assertEquals(cn.flattenToString(), ct.getComponentName().flattenToString());
2317         }
2318     }
2319 
2320     private void markWorkProfileUserAvailable() {
2321         sOverrides.workProfileUserHandle = UserHandle.of(10);
2322     }
2323 
2324     private void setupResolverControllers(
2325             List<ResolvedComponentInfo> personalResolvedComponentInfos,
2326             List<ResolvedComponentInfo> workResolvedComponentInfos) {
2327         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
2328                 Mockito.anyBoolean(),
2329                 Mockito.isA(List.class)))
2330                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
2331         when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
2332                 Mockito.anyBoolean(),
2333                 Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
2334         when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
2335                 Mockito.anyBoolean(),
2336                 Mockito.isA(List.class),
2337                 eq(UserHandle.SYSTEM)))
2338                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
2339     }
2340 }
2341