blob: df6b9066ea5c1b0aeba69b0b8326b501984b337e [file] [log] [blame]
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -08001/*
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
17package com.android.internal.app;
18
Matt Pietal26038402019-01-08 07:29:34 -050019import static androidx.test.espresso.Espresso.onView;
20import static androidx.test.espresso.action.ViewActions.click;
Matt Pietal74c6ed02019-04-18 13:38:46 -040021import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
Matt Pietal26038402019-01-08 07:29:34 -050022import static androidx.test.espresso.assertion.ViewAssertions.matches;
23import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
24import static androidx.test.espresso.matcher.ViewMatchers.withId;
25import static androidx.test.espresso.matcher.ViewMatchers.withText;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090026
Mehdi Alizadeh06955f62019-09-11 17:23:10 -070027import static com.android.internal.app.ChooserActivity.TARGET_TYPE_CHOOSER_TARGET;
28import static com.android.internal.app.ChooserActivity.TARGET_TYPE_DEFAULT;
29import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
30import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER;
arangelovb0802dc2019-10-18 18:03:44 +010031import static com.android.internal.app.ChooserListAdapter.CALLER_TARGET_SCORE_BOOST;
32import static com.android.internal.app.ChooserListAdapter.SHORTCUT_TARGET_SCORE_BOOST;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090033import static com.android.internal.app.ChooserWrapperActivity.sOverrides;
arangelovb4fc3972020-01-15 15:10:12 +000034import static com.android.internal.app.MatcherUtils.first;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090035
36import static org.hamcrest.CoreMatchers.is;
37import static org.hamcrest.CoreMatchers.not;
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -050038import static org.hamcrest.CoreMatchers.notNullValue;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090039import static org.hamcrest.MatcherAssert.assertThat;
Mehdi Alizadeh707c0cf2019-09-03 18:11:48 -070040import static org.junit.Assert.assertEquals;
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -050041import static org.mockito.Mockito.atLeastOnce;
Matt Pietalf38e9d22019-02-15 10:01:03 -050042import static org.mockito.Mockito.mock;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090043import static org.mockito.Mockito.times;
44import static org.mockito.Mockito.verify;
45import static org.mockito.Mockito.when;
46
47import android.app.usage.UsageStatsManager;
Matt Pietal26038402019-01-08 07:29:34 -050048import android.content.ClipData;
Matt Pietal1fa7d802019-01-30 10:44:15 -050049import android.content.ClipDescription;
50import android.content.ClipboardManager;
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -040051import android.content.ComponentName;
Matt Pietal1fa7d802019-01-30 10:44:15 -050052import android.content.Context;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090053import android.content.Intent;
George Hodulik145b3a52019-03-27 11:18:43 -070054import android.content.pm.PackageManager;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090055import android.content.pm.ResolveInfo;
Mehdi Alizadeh707c0cf2019-09-03 18:11:48 -070056import android.content.pm.ShortcutInfo;
57import android.content.pm.ShortcutManager.ShareShortcutInfo;
Sergey Troshin40e979e2019-12-30 17:29:50 +010058import android.content.res.Configuration;
Matt Pietalf38e9d22019-02-15 10:01:03 -050059import android.database.Cursor;
Matt Pietal26038402019-01-08 07:29:34 -050060import android.graphics.Bitmap;
61import android.graphics.Canvas;
62import android.graphics.Color;
63import android.graphics.Paint;
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -040064import android.graphics.drawable.Icon;
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -050065import android.metrics.LogMaker;
Matt Pietal26038402019-01-08 07:29:34 -050066import android.net.Uri;
arangelovb4fc3972020-01-15 15:10:12 +000067import android.os.UserHandle;
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -040068import android.service.chooser.ChooserTarget;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090069
Matt Pietal26038402019-01-08 07:29:34 -050070import androidx.test.platform.app.InstrumentationRegistry;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090071import androidx.test.rule.ActivityTestRule;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090072
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -080073import com.android.internal.R;
74import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
arangelovb0802dc2019-10-18 18:03:44 +010075import com.android.internal.app.chooser.DisplayResolveInfo;
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -050076import com.android.internal.logging.MetricsLogger;
Susi Kharraz-Post0446fab2019-02-21 09:42:31 -050077import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -080078
79import org.junit.Before;
arangelovb4fc3972020-01-15 15:10:12 +000080import org.junit.Ignore;
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -080081import org.junit.Rule;
82import org.junit.Test;
83import org.junit.runner.RunWith;
George Hodulik145b3a52019-03-27 11:18:43 -070084import org.junit.runners.Parameterized;
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -050085import org.mockito.ArgumentCaptor;
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -080086import org.mockito.Mockito;
87
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -080088import java.util.ArrayList;
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -040089import java.util.Arrays;
90import java.util.Collection;
arangelov5fc9e7d2020-01-07 17:59:14 +000091import java.util.HashMap;
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -080092import java.util.List;
arangelov5fc9e7d2020-01-07 17:59:14 +000093import java.util.Map;
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -040094import java.util.function.Function;
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -080095
96/**
97 * Chooser activity instrumentation tests
98 */
George Hodulik145b3a52019-03-27 11:18:43 -070099@RunWith(Parameterized.class)
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800100public class ChooserActivityTest {
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500101
George Hodulik145b3a52019-03-27 11:18:43 -0700102 private static final Function<PackageManager, PackageManager> DEFAULT_PM = pm -> pm;
103 private static final Function<PackageManager, PackageManager> NO_APP_PREDICTION_SERVICE_PM =
104 pm -> {
105 PackageManager mock = Mockito.spy(pm);
106 when(mock.getAppPredictionServicePackageName()).thenReturn(null);
107 return mock;
108 };
109
110 @Parameterized.Parameters
111 public static Collection packageManagers() {
112 return Arrays.asList(new Object[][] {
113 {0, "Default PackageManager", DEFAULT_PM},
114 {1, "No App Prediction Service", NO_APP_PREDICTION_SERVICE_PM}
115 });
116 }
117
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500118 private static final int CONTENT_PREVIEW_IMAGE = 1;
119 private static final int CONTENT_PREVIEW_FILE = 2;
120 private static final int CONTENT_PREVIEW_TEXT = 3;
George Hodulik145b3a52019-03-27 11:18:43 -0700121 private Function<PackageManager, PackageManager> mPackageManagerOverride;
122 private int mTestNum;
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500123
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800124 @Rule
125 public ActivityTestRule<ChooserWrapperActivity> mActivityRule =
126 new ActivityTestRule<>(ChooserWrapperActivity.class, false,
127 false);
128
George Hodulik145b3a52019-03-27 11:18:43 -0700129 public ChooserActivityTest(
130 int testNum,
131 String testName,
132 Function<PackageManager, PackageManager> packageManagerOverride) {
133 mPackageManagerOverride = packageManagerOverride;
134 mTestNum = testNum;
135 }
136
Makoto Onuki99302b52017-03-29 12:42:26 -0700137 @Before
138 public void cleanOverrideData() {
139 sOverrides.reset();
George Hodulik145b3a52019-03-27 11:18:43 -0700140 sOverrides.createPackageManager = mPackageManagerOverride;
Makoto Onuki99302b52017-03-29 12:42:26 -0700141 }
142
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800143 @Test
144 public void customTitle() throws InterruptedException {
Matt Pietal26038402019-01-08 07:29:34 -0500145 Intent viewIntent = createViewTextIntent();
146 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
147
148 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
149 Mockito.anyBoolean(),
150 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
Matt Pietal95574b02019-03-13 08:12:25 -0400151 final ChooserWrapperActivity activity = mActivityRule.launchActivity(
152 Intent.createChooser(viewIntent, "chooser test"));
Matt Pietal26038402019-01-08 07:29:34 -0500153
154 waitForIdle();
Matt Pietal95574b02019-03-13 08:12:25 -0400155 assertThat(activity.getAdapter().getCount(), is(2));
156 assertThat(activity.getAdapter().getServiceTargetCount(), is(0));
Matt Pietal26038402019-01-08 07:29:34 -0500157 onView(withId(R.id.title)).check(matches(withText("chooser test")));
158 }
159
160 @Test
161 public void customTitleIgnoredForSendIntents() throws InterruptedException {
162 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglu79b69f02017-01-12 17:08:02 -0800163 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
164
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800165 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
166 Mockito.anyBoolean(),
Hakan Seyalioglu79b69f02017-01-12 17:08:02 -0800167 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800168 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "chooser test"));
169 waitForIdle();
Matt Pietal26038402019-01-08 07:29:34 -0500170 onView(withId(R.id.title)).check(matches(withText(R.string.whichSendApplication)));
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800171 }
172
173 @Test
174 public void emptyTitle() throws InterruptedException {
Matt Pietal26038402019-01-08 07:29:34 -0500175 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglu79b69f02017-01-12 17:08:02 -0800176 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
177
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800178 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
179 Mockito.anyBoolean(),
Hakan Seyalioglu79b69f02017-01-12 17:08:02 -0800180 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800181 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
182 waitForIdle();
183 onView(withId(R.id.title))
184 .check(matches(withText(R.string.whichSendApplication)));
185 }
186
187 @Test
Matt Pietal26038402019-01-08 07:29:34 -0500188 public void emptyPreviewTitleAndThumbnail() throws InterruptedException {
189 Intent sendIntent = createSendTextIntentWithPreview(null, null);
190 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
191
192 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
193 Mockito.anyBoolean(),
194 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
195 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
196 waitForIdle();
197 onView(withId(R.id.content_preview_title)).check(matches(not(isDisplayed())));
198 onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
199 }
200
201 @Test
202 public void visiblePreviewTitleWithoutThumbnail() throws InterruptedException {
203 String previewTitle = "My Content Preview Title";
204 Intent sendIntent = createSendTextIntentWithPreview(previewTitle, null);
205 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
206
207 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
208 Mockito.anyBoolean(),
209 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
210 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
211 waitForIdle();
212 onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
213 onView(withId(R.id.content_preview_title)).check(matches(withText(previewTitle)));
214 onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
215 }
216
217 @Test
218 public void visiblePreviewTitleWithInvalidThumbnail() throws InterruptedException {
219 String previewTitle = "My Content Preview Title";
220 Intent sendIntent = createSendTextIntentWithPreview(previewTitle,
221 Uri.parse("tel:(+49)12345789"));
222 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
223
224 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
225 Mockito.anyBoolean(),
226 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
227 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
228 waitForIdle();
229 onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
230 onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
231 }
232
233 @Test
234 public void visiblePreviewTitleAndThumbnail() throws InterruptedException {
235 String previewTitle = "My Content Preview Title";
236 Intent sendIntent = createSendTextIntentWithPreview(previewTitle,
237 Uri.parse("android.resource://com.android.frameworks.coretests/"
238 + com.android.frameworks.coretests.R.drawable.test320x240));
239 sOverrides.previewThumbnail = createBitmap();
240 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
241
242 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
243 Mockito.anyBoolean(),
244 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
245 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
246 waitForIdle();
247 onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
248 onView(withId(R.id.content_preview_thumbnail)).check(matches(isDisplayed()));
249 }
250
251 @Test
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800252 public void twoOptionsAndUserSelectsOne() throws InterruptedException {
Matt Pietal26038402019-01-08 07:29:34 -0500253 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800254 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
255
256 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
257 Mockito.anyBoolean(),
258 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
259
260 final ChooserWrapperActivity activity = mActivityRule
261 .launchActivity(Intent.createChooser(sendIntent, null));
262 waitForIdle();
263
264 assertThat(activity.getAdapter().getCount(), is(2));
Matt Pietal74c6ed02019-04-18 13:38:46 -0400265 onView(withId(R.id.profile_button)).check(doesNotExist());
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800266
267 ResolveInfo[] chosen = new ResolveInfo[1];
268 sOverrides.onSafelyStartCallback = targetInfo -> {
269 chosen[0] = targetInfo.getResolveInfo();
270 return true;
271 };
272
273 ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
274 onView(withText(toChoose.activityInfo.name))
275 .perform(click());
276 waitForIdle();
277 assertThat(chosen[0], is(toChoose));
278 }
279
280 @Test
Kang Li9fa2a2c2017-01-06 13:33:24 -0800281 public void updateChooserCountsAndModelAfterUserSelection() throws InterruptedException {
Matt Pietal26038402019-01-08 07:29:34 -0500282 Intent sendIntent = createSendTextIntent();
Kang Li64b018e2017-01-05 17:30:06 -0800283 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
284
285 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
286 Mockito.anyBoolean(),
287 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
288
289 final ChooserWrapperActivity activity = mActivityRule
290 .launchActivity(Intent.createChooser(sendIntent, null));
291 waitForIdle();
292 UsageStatsManager usm = activity.getUsageStatsManager();
293 verify(sOverrides.resolverListController, times(1))
Zhen Zhangaa458b12019-10-16 12:46:44 -0700294 .topK(Mockito.any(List.class), Mockito.anyInt());
Kang Li64b018e2017-01-05 17:30:06 -0800295 assertThat(activity.getIsSelected(), is(false));
296 sOverrides.onSafelyStartCallback = targetInfo -> {
297 return true;
298 };
Kang Li64b018e2017-01-05 17:30:06 -0800299 ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
Kang Li64b018e2017-01-05 17:30:06 -0800300 onView(withText(toChoose.activityInfo.name))
301 .perform(click());
302 waitForIdle();
303 verify(sOverrides.resolverListController, times(1))
Kang Li9fa2a2c2017-01-06 13:33:24 -0800304 .updateChooserCounts(Mockito.anyString(), Mockito.anyInt(), Mockito.anyString());
305 verify(sOverrides.resolverListController, times(1))
Kang Li64b018e2017-01-05 17:30:06 -0800306 .updateModel(toChoose.activityInfo.getComponentName());
307 assertThat(activity.getIsSelected(), is(true));
Kang Li64b018e2017-01-05 17:30:06 -0800308 }
309
arangelovb4fc3972020-01-15 15:10:12 +0000310 @Ignore // b/148158199
Kang Li64b018e2017-01-05 17:30:06 -0800311 @Test
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800312 public void noResultsFromPackageManager() {
313 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
314 Mockito.anyBoolean(),
315 Mockito.isA(List.class))).thenReturn(null);
Matt Pietal26038402019-01-08 07:29:34 -0500316 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800317 final ChooserWrapperActivity activity = mActivityRule
318 .launchActivity(Intent.createChooser(sendIntent, null));
319 waitForIdle();
320 assertThat(activity.isFinishing(), is(false));
321
322 onView(withId(R.id.empty)).check(matches(isDisplayed()));
arangelov2c1c37a2019-12-06 14:43:34 +0000323 onView(withId(R.id.profile_pager)).check(matches(not(isDisplayed())));
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800324 InstrumentationRegistry.getInstrumentation().runOnMainSync(
325 () -> activity.getAdapter().handlePackagesChanged()
326 );
327 // backward compatibility. looks like we finish when data is empty after package change
328 assertThat(activity.isFinishing(), is(true));
329 }
330
331 @Test
332 public void autoLaunchSingleResult() throws InterruptedException {
333 ResolveInfo[] chosen = new ResolveInfo[1];
334 sOverrides.onSafelyStartCallback = targetInfo -> {
335 chosen[0] = targetInfo.getResolveInfo();
336 return true;
337 };
338
339 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(1);
340 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
341 Mockito.anyBoolean(),
342 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
343
Matt Pietal26038402019-01-08 07:29:34 -0500344 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -0800345 final ChooserWrapperActivity activity = mActivityRule
346 .launchActivity(Intent.createChooser(sendIntent, null));
347 waitForIdle();
348
349 assertThat(chosen[0], is(resolvedComponentInfos.get(0).getResolveInfoAt(0)));
350 assertThat(activity.isFinishing(), is(true));
351 }
352
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800353 @Test
354 public void hasOtherProfileOneOption() throws Exception {
arangelovb4fc3972020-01-15 15:10:12 +0000355 // enable the work tab feature flag
356 ResolverActivity.ENABLE_TABBED_VIEW = true;
357
Matt Pietal26038402019-01-08 07:29:34 -0500358 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800359 List<ResolvedComponentInfo> resolvedComponentInfos =
360 createResolvedComponentsForTestWithOtherProfile(2);
361 ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
362
363 when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
364 Mockito.anyBoolean(),
365 Mockito.anyBoolean(),
366 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
367
368 final ChooserWrapperActivity activity = mActivityRule
369 .launchActivity(Intent.createChooser(sendIntent, null));
370 waitForIdle();
371
372 // The other entry is filtered to the other profile slot
373 assertThat(activity.getAdapter().getCount(), is(1));
374
375 ResolveInfo[] chosen = new ResolveInfo[1];
376 ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> {
377 chosen[0] = targetInfo.getResolveInfo();
378 return true;
379 };
Makoto Onuki99302b52017-03-29 12:42:26 -0700380
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800381 // Make a stable copy of the components as the original list may be modified
382 List<ResolvedComponentInfo> stableCopy =
383 createResolvedComponentsForTestWithOtherProfile(2);
arangelovb4fc3972020-01-15 15:10:12 +0000384 waitForIdle();
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800385 onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
386 .perform(click());
387 waitForIdle();
388 assertThat(chosen[0], is(toChoose));
389 }
390
391 @Test
392 public void hasOtherProfileTwoOptionsAndUserSelectsOne() throws Exception {
arangelovb4fc3972020-01-15 15:10:12 +0000393 // enable the work tab feature flag
394 ResolverActivity.ENABLE_TABBED_VIEW = true;
395
Matt Pietal26038402019-01-08 07:29:34 -0500396 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800397 List<ResolvedComponentInfo> resolvedComponentInfos =
398 createResolvedComponentsForTestWithOtherProfile(3);
399 ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
400
401 when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
402 Mockito.anyBoolean(),
403 Mockito.anyBoolean(),
404 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
405 when(ChooserWrapperActivity.sOverrides.resolverListController.getLastChosen())
406 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
407
408 final ChooserWrapperActivity activity = mActivityRule
409 .launchActivity(Intent.createChooser(sendIntent, null));
410 waitForIdle();
411
412 // The other entry is filtered to the other profile slot
413 assertThat(activity.getAdapter().getCount(), is(2));
414
415 ResolveInfo[] chosen = new ResolveInfo[1];
416 ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> {
417 chosen[0] = targetInfo.getResolveInfo();
418 return true;
419 };
420
421 // Make a stable copy of the components as the original list may be modified
422 List<ResolvedComponentInfo> stableCopy =
423 createResolvedComponentsForTestWithOtherProfile(3);
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800424 onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
425 .perform(click());
426 waitForIdle();
427 assertThat(chosen[0], is(toChoose));
428 }
429
430 @Test
431 public void hasLastChosenActivityAndOtherProfile() throws Exception {
arangelovb4fc3972020-01-15 15:10:12 +0000432 // enable the work tab feature flag
433 ResolverActivity.ENABLE_TABBED_VIEW = true;
434
Matt Pietal26038402019-01-08 07:29:34 -0500435 Intent sendIntent = createSendTextIntent();
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800436 List<ResolvedComponentInfo> resolvedComponentInfos =
437 createResolvedComponentsForTestWithOtherProfile(3);
438 ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
439
440 when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
441 Mockito.anyBoolean(),
442 Mockito.anyBoolean(),
443 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
444
445 final ChooserWrapperActivity activity = mActivityRule
446 .launchActivity(Intent.createChooser(sendIntent, null));
447 waitForIdle();
448
449 // The other entry is filtered to the last used slot
450 assertThat(activity.getAdapter().getCount(), is(2));
451
452 ResolveInfo[] chosen = new ResolveInfo[1];
453 ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> {
454 chosen[0] = targetInfo.getResolveInfo();
455 return true;
456 };
457
458 // Make a stable copy of the components as the original list may be modified
459 List<ResolvedComponentInfo> stableCopy =
460 createResolvedComponentsForTestWithOtherProfile(3);
Hakan Seyalioglu13405c52017-01-31 19:01:31 -0800461 onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
462 .perform(click());
463 waitForIdle();
464 assertThat(chosen[0], is(toChoose));
465 }
466
Matt Pietal1fa7d802019-01-30 10:44:15 -0500467 @Test
468 public void copyTextToClipboard() throws Exception {
469 Intent sendIntent = createSendTextIntent();
Matt Pietal46d828c2019-02-05 08:07:07 -0500470 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
Matt Pietal1fa7d802019-01-30 10:44:15 -0500471
472 when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500473 Mockito.anyBoolean(),
474 Mockito.anyBoolean(),
475 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
Matt Pietal1fa7d802019-01-30 10:44:15 -0500476
477 final ChooserWrapperActivity activity = mActivityRule
478 .launchActivity(Intent.createChooser(sendIntent, null));
479 waitForIdle();
480
Dan Sandlere3d19932019-11-22 11:58:58 -0500481 onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
482 onView(withId(R.id.chooser_copy_button)).perform(click());
Matt Pietal1fa7d802019-01-30 10:44:15 -0500483 ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(
484 Context.CLIPBOARD_SERVICE);
485 ClipData clipData = clipboard.getPrimaryClip();
486 assertThat("testing intent sending", is(clipData.getItemAt(0).getText()));
487
488 ClipDescription clipDescription = clipData.getDescription();
489 assertThat("text/plain", is(clipDescription.getMimeType(0)));
490 }
491
Matt Pietal0ea391b2019-01-30 10:44:15 -0500492 @Test
Susi Kharraz-Post9e913182019-09-19 11:20:01 -0400493 public void copyTextToClipboardLogging() throws Exception {
494 Intent sendIntent = createSendTextIntent();
495 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
496
497 when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
498 Mockito.anyBoolean(),
499 Mockito.anyBoolean(),
500 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
501
502 MetricsLogger mockLogger = sOverrides.metricsLogger;
503 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
504
505 final ChooserWrapperActivity activity = mActivityRule
506 .launchActivity(Intent.createChooser(sendIntent, null));
507 waitForIdle();
508
Dan Sandlere3d19932019-11-22 11:58:58 -0500509 onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
510 onView(withId(R.id.chooser_copy_button)).perform(click());
Susi Kharraz-Post9e913182019-09-19 11:20:01 -0400511
512 verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
513 // First is Activity shown, Second is "with preview"
514 assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
515 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET));
516 assertThat(logMakerCaptor
517 .getAllValues().get(2)
518 .getSubtype(),
519 is(1));
520 }
521
522 @Test
Matt Pietal0ea391b2019-01-30 10:44:15 -0500523 public void oneVisibleImagePreview() throws InterruptedException {
524 Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
525 + com.android.frameworks.coretests.R.drawable.test320x240);
526
527 ArrayList<Uri> uris = new ArrayList<>();
528 uris.add(uri);
529
Matt Pietal46d828c2019-02-05 08:07:07 -0500530 Intent sendIntent = createSendUriIntentWithPreview(uris);
Matt Pietal0ea391b2019-01-30 10:44:15 -0500531 sOverrides.previewThumbnail = createBitmap();
Matt Pietal46d828c2019-02-05 08:07:07 -0500532 sOverrides.isImageType = true;
Matt Pietal0ea391b2019-01-30 10:44:15 -0500533
534 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
535
536 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
537 Mockito.anyBoolean(),
538 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
539 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
540 waitForIdle();
541 onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
542 onView(withId(R.id.content_preview_image_2_large)).check(matches(not(isDisplayed())));
543 onView(withId(R.id.content_preview_image_2_small)).check(matches(not(isDisplayed())));
544 onView(withId(R.id.content_preview_image_3_small)).check(matches(not(isDisplayed())));
545 }
546
547 @Test
548 public void twoVisibleImagePreview() throws InterruptedException {
549 Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
550 + com.android.frameworks.coretests.R.drawable.test320x240);
551
552 ArrayList<Uri> uris = new ArrayList<>();
553 uris.add(uri);
554 uris.add(uri);
555
Matt Pietal46d828c2019-02-05 08:07:07 -0500556 Intent sendIntent = createSendUriIntentWithPreview(uris);
Matt Pietal0ea391b2019-01-30 10:44:15 -0500557 sOverrides.previewThumbnail = createBitmap();
Matt Pietal46d828c2019-02-05 08:07:07 -0500558 sOverrides.isImageType = true;
Matt Pietal0ea391b2019-01-30 10:44:15 -0500559
560 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
561
562 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
563 Mockito.anyBoolean(),
564 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
565 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
566 waitForIdle();
567 onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
568 onView(withId(R.id.content_preview_image_2_large)).check(matches(isDisplayed()));
569 onView(withId(R.id.content_preview_image_2_small)).check(matches(not(isDisplayed())));
570 onView(withId(R.id.content_preview_image_3_small)).check(matches(not(isDisplayed())));
571 }
572
573 @Test
574 public void threeOrMoreVisibleImagePreview() throws InterruptedException {
575 Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
576 + com.android.frameworks.coretests.R.drawable.test320x240);
577
578 ArrayList<Uri> uris = new ArrayList<>();
579 uris.add(uri);
580 uris.add(uri);
581 uris.add(uri);
582 uris.add(uri);
583 uris.add(uri);
584
Matt Pietal46d828c2019-02-05 08:07:07 -0500585 Intent sendIntent = createSendUriIntentWithPreview(uris);
Matt Pietal0ea391b2019-01-30 10:44:15 -0500586 sOverrides.previewThumbnail = createBitmap();
Matt Pietal46d828c2019-02-05 08:07:07 -0500587 sOverrides.isImageType = true;
Matt Pietal0ea391b2019-01-30 10:44:15 -0500588
589 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
590
591 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500592 Mockito.anyBoolean(),
593 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
Matt Pietal0ea391b2019-01-30 10:44:15 -0500594 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
595 waitForIdle();
596 onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
597 onView(withId(R.id.content_preview_image_2_large)).check(matches(not(isDisplayed())));
598 onView(withId(R.id.content_preview_image_2_small)).check(matches(isDisplayed()));
599 onView(withId(R.id.content_preview_image_3_small)).check(matches(isDisplayed()));
600 }
601
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500602 @Test
603 public void testOnCreateLogging() {
604 Intent sendIntent = createSendTextIntent();
605 sendIntent.setType("TestType");
606
607 MetricsLogger mockLogger = sOverrides.metricsLogger;
608 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
609 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
610 waitForIdle();
611 verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
612 assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
Susi Kharraz-Post0446fab2019-02-21 09:42:31 -0500613 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500614 assertThat(logMakerCaptor
615 .getAllValues().get(0)
Susi Kharraz-Post0446fab2019-02-21 09:42:31 -0500616 .getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500617 is(notNullValue()));
618 assertThat(logMakerCaptor
619 .getAllValues().get(0)
Susi Kharraz-Post0446fab2019-02-21 09:42:31 -0500620 .getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500621 is("TestType"));
Susi Kharraz-Post0446fab2019-02-21 09:42:31 -0500622 assertThat(logMakerCaptor
623 .getAllValues().get(0)
624 .getSubtype(),
625 is(MetricsEvent.PARENT_PROFILE));
626 }
627
628 @Test
629 public void testOnCreateLoggingFromWorkProfile() {
630 Intent sendIntent = createSendTextIntent();
631 sendIntent.setType("TestType");
632 sOverrides.alternateProfileSetting = MetricsEvent.MANAGED_PROFILE;
633 MetricsLogger mockLogger = sOverrides.metricsLogger;
634 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
635 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
636 waitForIdle();
637 verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
638 assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
639 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
640 assertThat(logMakerCaptor
641 .getAllValues().get(0)
642 .getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
643 is(notNullValue()));
644 assertThat(logMakerCaptor
645 .getAllValues().get(0)
646 .getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
647 is("TestType"));
648 assertThat(logMakerCaptor
649 .getAllValues().get(0)
650 .getSubtype(),
651 is(MetricsEvent.MANAGED_PROFILE));
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500652 }
653
654 @Test
655 public void testEmptyPreviewLogging() {
656 Intent sendIntent = createSendTextIntentWithPreview(null, null);
657
658 MetricsLogger mockLogger = sOverrides.metricsLogger;
659 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
660 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "empty preview logger test"));
661 waitForIdle();
Matt Pietal46d828c2019-02-05 08:07:07 -0500662
663 verify(mockLogger, Mockito.times(1)).write(logMakerCaptor.capture());
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500664 // First invocation is from onCreate
Matt Pietal46d828c2019-02-05 08:07:07 -0500665 assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
Susi Kharraz-Post0446fab2019-02-21 09:42:31 -0500666 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500667 }
668
669 @Test
670 public void testTitlePreviewLogging() {
671 Intent sendIntent = createSendTextIntentWithPreview("TestTitle", null);
672
673 MetricsLogger mockLogger = sOverrides.metricsLogger;
674 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
Matt Pietal46d828c2019-02-05 08:07:07 -0500675
676 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
677
678 when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
679 Mockito.anyBoolean(),
680 Mockito.anyBoolean(),
681 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
682
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500683 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
684 waitForIdle();
arangelov2c1c37a2019-12-06 14:43:34 +0000685 // Second invocation is from onCreate
Matt Pietalfe28f9a2019-03-22 07:59:58 -0400686 verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
arangelov2c1c37a2019-12-06 14:43:34 +0000687 assertThat(logMakerCaptor.getAllValues().get(0).getSubtype(),
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500688 is(CONTENT_PREVIEW_TEXT));
arangelov2c1c37a2019-12-06 14:43:34 +0000689 assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
690 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500691 }
692
693 @Test
694 public void testImagePreviewLogging() {
695 Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
696 + com.android.frameworks.coretests.R.drawable.test320x240);
697
698 ArrayList<Uri> uris = new ArrayList<>();
699 uris.add(uri);
700
Matt Pietal46d828c2019-02-05 08:07:07 -0500701 Intent sendIntent = createSendUriIntentWithPreview(uris);
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500702 sOverrides.previewThumbnail = createBitmap();
Matt Pietal46d828c2019-02-05 08:07:07 -0500703 sOverrides.isImageType = true;
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500704
705 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
706
707 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
708 Mockito.anyBoolean(),
709 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
710
711 MetricsLogger mockLogger = sOverrides.metricsLogger;
712 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
713 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
714 waitForIdle();
Matt Pietalfe28f9a2019-03-22 07:59:58 -0400715 verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500716 // First invocation is from onCreate
arangelov2c1c37a2019-12-06 14:43:34 +0000717 assertThat(logMakerCaptor.getAllValues().get(0).getSubtype(),
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500718 is(CONTENT_PREVIEW_IMAGE));
arangelov2c1c37a2019-12-06 14:43:34 +0000719 assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
720 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
Susi Kharraz-Post7e2115d2019-02-01 16:51:22 -0500721 }
722
Matt Pietal46d828c2019-02-05 08:07:07 -0500723 @Test
724 public void oneVisibleFilePreview() throws InterruptedException {
725 Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
726
727 ArrayList<Uri> uris = new ArrayList<>();
728 uris.add(uri);
729
730 Intent sendIntent = createSendUriIntentWithPreview(uris);
731
732 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
733
734 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
735 Mockito.anyBoolean(),
736 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
737 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
738 waitForIdle();
739 onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
740 onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf")));
741 onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
742 }
743
744
745 @Test
746 public void moreThanOneVisibleFilePreview() throws InterruptedException {
747 Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
748
749 ArrayList<Uri> uris = new ArrayList<>();
750 uris.add(uri);
751 uris.add(uri);
752 uris.add(uri);
753
754 Intent sendIntent = createSendUriIntentWithPreview(uris);
755
756 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
757
758 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
759 Mockito.anyBoolean(),
760 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
761 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
762 waitForIdle();
763 onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
764 onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf + 2 files")));
765 onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
766 }
767
Matt Pietalf38e9d22019-02-15 10:01:03 -0500768 @Test
769 public void contentProviderThrowSecurityException() throws InterruptedException {
770 Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
771
772 ArrayList<Uri> uris = new ArrayList<>();
773 uris.add(uri);
774
775 Intent sendIntent = createSendUriIntentWithPreview(uris);
776
777 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
778 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
779 Mockito.anyBoolean(),
780 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
781
782 sOverrides.resolverForceException = true;
783
784 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
785 waitForIdle();
786 onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
787 onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf")));
788 onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
789 }
790
791 @Test
792 public void contentProviderReturnsNoColumns() throws InterruptedException {
793 Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf");
794
795 ArrayList<Uri> uris = new ArrayList<>();
796 uris.add(uri);
797 uris.add(uri);
798
799 Intent sendIntent = createSendUriIntentWithPreview(uris);
800
801 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
802 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
803 Mockito.anyBoolean(),
804 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
805
806 Cursor cursor = mock(Cursor.class);
807 when(cursor.getCount()).thenReturn(1);
808 Mockito.doNothing().when(cursor).close();
809 when(cursor.moveToFirst()).thenReturn(true);
810 when(cursor.getColumnIndex(Mockito.anyString())).thenReturn(-1);
811
812 sOverrides.resolverCursor = cursor;
813
814 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
815 waitForIdle();
816 onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed()));
817 onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf + 1 file")));
818 onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
819 }
820
Mehdi Alizadeh06955f62019-09-11 17:23:10 -0700821 @Test
822 public void testGetBaseScore() {
823 final float testBaseScore = 0.89f;
824
825 Intent sendIntent = createSendTextIntent();
826 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
827
828 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
829 Mockito.anyBoolean(),
830 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
arangelovb0802dc2019-10-18 18:03:44 +0100831 when(sOverrides.resolverListController.getScore(Mockito.isA(DisplayResolveInfo.class)))
832 .thenReturn(testBaseScore);
Mehdi Alizadeh06955f62019-09-11 17:23:10 -0700833
834 final ChooserWrapperActivity activity = mActivityRule
835 .launchActivity(Intent.createChooser(sendIntent, null));
836 waitForIdle();
837
arangelovb0802dc2019-10-18 18:03:44 +0100838 final DisplayResolveInfo testDri =
Mehdi Alizadeh06955f62019-09-11 17:23:10 -0700839 activity.createTestDisplayResolveInfo(sendIntent,
arangelovb0802dc2019-10-18 18:03:44 +0100840 ResolverDataProvider.createResolveInfo(3, 0), "testLabel", "testInfo", sendIntent,
841 /* resolveInfoPresentationGetter */ null);
842 final ChooserListAdapter adapter = activity.getAdapter();
Mehdi Alizadeh06955f62019-09-11 17:23:10 -0700843
844 assertThat(adapter.getBaseScore(null, 0), is(CALLER_TARGET_SCORE_BOOST));
845 assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_DEFAULT), is(testBaseScore));
846 assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_CHOOSER_TARGET), is(testBaseScore));
847 assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE),
848 is(SHORTCUT_TARGET_SCORE_BOOST));
849 assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER),
850 is(testBaseScore * SHORTCUT_TARGET_SCORE_BOOST));
851 }
852
Mehdi Alizadehe870e972019-09-11 17:54:15 -0700853 /**
854 * The case when AppPrediction service is not defined in PackageManager is already covered
855 * as a test parameter {@link ChooserActivityTest#packageManagers}. This test is checking the
856 * case when the prediction service is defined but the component is not available on the device.
857 */
858 @Test
859 public void testIsAppPredictionServiceAvailable() {
860 Intent sendIntent = createSendTextIntent();
861 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
862 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
863 Mockito.anyBoolean(),
864 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
865
866 final ChooserWrapperActivity activity = mActivityRule
867 .launchActivity(Intent.createChooser(sendIntent, null));
868 waitForIdle();
869
870 if (activity.getPackageManager().getAppPredictionServicePackageName() == null) {
871 assertThat(activity.isAppPredictionServiceAvailable(), is(false));
872 } else {
873 assertThat(activity.isAppPredictionServiceAvailable(), is(true));
874
875 sOverrides.resources = Mockito.spy(activity.getResources());
876 when(sOverrides.resources.getString(R.string.config_defaultAppPredictionService))
877 .thenReturn("ComponentNameThatDoesNotExist");
878
879 assertThat(activity.isAppPredictionServiceAvailable(), is(false));
880 }
881 }
882
Mehdi Alizadeh707c0cf2019-09-03 18:11:48 -0700883 @Test
884 public void testConvertToChooserTarget_predictionService() {
885 Intent sendIntent = createSendTextIntent();
886 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
887 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
888 Mockito.anyBoolean(),
889 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
890
891 final ChooserWrapperActivity activity = mActivityRule
892 .launchActivity(Intent.createChooser(sendIntent, null));
893 waitForIdle();
894
895 List<ShareShortcutInfo> shortcuts = createShortcuts(activity);
896
897 int[] expectedOrderAllShortcuts = {0, 1, 2, 3};
898 float[] expectedScoreAllShortcuts = {1.0f, 0.99f, 0.98f, 0.97f};
899
900 List<ChooserTarget> chooserTargets = activity.convertToChooserTarget(shortcuts, shortcuts,
901 null, TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
902 assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
903 expectedOrderAllShortcuts, expectedScoreAllShortcuts);
904
905 List<ShareShortcutInfo> subset = new ArrayList<>();
906 subset.add(shortcuts.get(1));
907 subset.add(shortcuts.get(2));
908 subset.add(shortcuts.get(3));
909
910 int[] expectedOrderSubset = {1, 2, 3};
911 float[] expectedScoreSubset = {0.99f, 0.98f, 0.97f};
912
913 chooserTargets = activity.convertToChooserTarget(subset, shortcuts, null,
914 TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
915 assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
916 expectedOrderSubset, expectedScoreSubset);
917 }
918
919 @Test
920 public void testConvertToChooserTarget_shortcutManager() {
921 Intent sendIntent = createSendTextIntent();
922 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
923 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
924 Mockito.anyBoolean(),
925 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
926
927 final ChooserWrapperActivity activity = mActivityRule
928 .launchActivity(Intent.createChooser(sendIntent, null));
929 waitForIdle();
930
931 List<ShareShortcutInfo> shortcuts = createShortcuts(activity);
932
933 int[] expectedOrderAllShortcuts = {2, 0, 3, 1};
934 float[] expectedScoreAllShortcuts = {1.0f, 0.99f, 0.99f, 0.98f};
935
936 List<ChooserTarget> chooserTargets = activity.convertToChooserTarget(shortcuts, shortcuts,
937 null, TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER);
938 assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
939 expectedOrderAllShortcuts, expectedScoreAllShortcuts);
940
941 List<ShareShortcutInfo> subset = new ArrayList<>();
942 subset.add(shortcuts.get(1));
943 subset.add(shortcuts.get(2));
944 subset.add(shortcuts.get(3));
945
946 int[] expectedOrderSubset = {2, 3, 1};
947 float[] expectedScoreSubset = {1.0f, 0.99f, 0.98f};
948
949 chooserTargets = activity.convertToChooserTarget(subset, shortcuts, null,
950 TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER);
951 assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
952 expectedOrderSubset, expectedScoreSubset);
953 }
954
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400955 // This test is too long and too slow and should not be taken as an example for future tests.
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400956 @Test
957 public void testDirectTargetSelectionLogging() throws InterruptedException {
958 Intent sendIntent = createSendTextIntent();
959 // We need app targets for direct targets to get displayed
960 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
961 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
962 Mockito.anyBoolean(),
963 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
964
965 // Set up resources
966 MetricsLogger mockLogger = sOverrides.metricsLogger;
967 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
968 // Create direct share target
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -0400969 List<ChooserTarget> serviceTargets = createDirectShareTargets(1, "");
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400970 ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
971
972 // Start activity
973 final ChooserWrapperActivity activity = mActivityRule
974 .launchActivity(Intent.createChooser(sendIntent, null));
975
976 // Insert the direct share target
arangelov5fc9e7d2020-01-07 17:59:14 +0000977 Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
978 directShareToShortcutInfos.put(serviceTargets.get(0), null);
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400979 InstrumentationRegistry.getInstrumentation().runOnMainSync(
980 () -> activity.getAdapter().addServiceResults(
981 activity.createTestDisplayResolveInfo(sendIntent,
982 ri,
983 "testLabel",
984 "testInfo",
arangelovb0802dc2019-10-18 18:03:44 +0100985 sendIntent,
986 /* resolveInfoPresentationGetter */ null),
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400987 serviceTargets,
arangelov5fc9e7d2020-01-07 17:59:14 +0000988 TARGET_TYPE_CHOOSER_TARGET,
989 directShareToShortcutInfos)
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400990 );
Sergey Troshin40e979e2019-12-30 17:29:50 +0100991
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400992 // Thread.sleep shouldn't be a thing in an integration test but it's
993 // necessary here because of the way the code is structured
994 // TODO: restructure the tests b/129870719
995 Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
996
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -0400997 assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -0400998 activity.getAdapter().getCount(), is(3));
999 assertThat("Chooser should have exactly one selectable direct target",
1000 activity.getAdapter().getSelectableServiceTargetCount(), is(1));
1001 assertThat("The resolver info must match the resolver info used to create the target",
1002 activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
1003
1004 // Click on the direct target
1005 String name = serviceTargets.get(0).getTitle().toString();
1006 onView(withText(name))
1007 .perform(click());
1008 waitForIdle();
1009
1010 // Currently we're seeing 3 invocations
1011 // 1. ChooserActivity.onCreate()
1012 // 2. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
1013 // 3. ChooserActivity.startSelected -- which is the one we're after
1014 verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
1015 assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
1016 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
1017 String hashedName = (String) logMakerCaptor
1018 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_HASHED_TARGET_NAME);
1019 assertThat("Hash is not predictable but must be obfuscated",
1020 hashedName, is(not(name)));
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001021 assertThat("The packages shouldn't match for app target and direct target", logMakerCaptor
1022 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(-1));
1023 }
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001024
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001025 // This test is too long and too slow and should not be taken as an example for future tests.
1026 @Test
1027 public void testDirectTargetLoggingWithRankedAppTarget() throws InterruptedException {
1028 Intent sendIntent = createSendTextIntent();
1029 // We need app targets for direct targets to get displayed
1030 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
1031 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1032 Mockito.anyBoolean(),
1033 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001034
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001035 // Set up resources
1036 MetricsLogger mockLogger = sOverrides.metricsLogger;
1037 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
1038 // Create direct share target
1039 List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
1040 resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
1041 ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001042
1043 // Start activity
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001044 final ChooserWrapperActivity activity = mActivityRule
1045 .launchActivity(Intent.createChooser(sendIntent, null));
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001046
1047 // Insert the direct share target
arangelov5fc9e7d2020-01-07 17:59:14 +00001048 Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
1049 directShareToShortcutInfos.put(serviceTargets.get(0), null);
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001050 InstrumentationRegistry.getInstrumentation().runOnMainSync(
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001051 () -> activity.getAdapter().addServiceResults(
1052 activity.createTestDisplayResolveInfo(sendIntent,
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001053 ri,
1054 "testLabel",
1055 "testInfo",
arangelovb0802dc2019-10-18 18:03:44 +01001056 sendIntent,
1057 /* resolveInfoPresentationGetter */ null),
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001058 serviceTargets,
arangelov5fc9e7d2020-01-07 17:59:14 +00001059 TARGET_TYPE_CHOOSER_TARGET,
1060 directShareToShortcutInfos)
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001061 );
1062 // Thread.sleep shouldn't be a thing in an integration test but it's
1063 // necessary here because of the way the code is structured
1064 // TODO: restructure the tests b/129870719
1065 Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1066
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001067 assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
1068 activity.getAdapter().getCount(), is(3));
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001069 assertThat("Chooser should have exactly one selectable direct target",
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001070 activity.getAdapter().getSelectableServiceTargetCount(), is(1));
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001071 assertThat("The resolver info must match the resolver info used to create the target",
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001072 activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001073
1074 // Click on the direct target
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001075 String name = serviceTargets.get(0).getTitle().toString();
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001076 onView(withText(name))
1077 .perform(click());
1078 waitForIdle();
1079
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001080 // Currently we're seeing 3 invocations
1081 // 1. ChooserActivity.onCreate()
1082 // 2. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
1083 // 3. ChooserActivity.startSelected -- which is the one we're after
1084 verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
1085 assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001086 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001087 assertThat("The packages should match for app target and direct target", logMakerCaptor
1088 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(0));
1089 }
1090
1091 // This test is too long and too slow and should not be taken as an example for future tests.
1092 @Test
Sergey Troshin40e979e2019-12-30 17:29:50 +01001093 public void testDirectTargetLoggingWithAppTargetNotRankedPortrait()
1094 throws InterruptedException {
1095 testDirectTargetLoggingWithAppTargetNotRanked(Configuration.ORIENTATION_PORTRAIT, 4);
1096 }
1097
1098 @Test
1099 public void testDirectTargetLoggingWithAppTargetNotRankedLandscape()
1100 throws InterruptedException {
1101 testDirectTargetLoggingWithAppTargetNotRanked(Configuration.ORIENTATION_LANDSCAPE, 8);
1102 }
1103
1104 private void testDirectTargetLoggingWithAppTargetNotRanked(
1105 int orientation, int appTargetsExpected
1106 ) throws InterruptedException {
1107 Configuration configuration =
1108 new Configuration(InstrumentationRegistry.getInstrumentation().getContext()
1109 .getResources().getConfiguration());
1110 configuration.orientation = orientation;
1111
1112 sOverrides.resources = Mockito.spy(
1113 InstrumentationRegistry.getInstrumentation().getContext().getResources());
1114 when(sOverrides.resources.getConfiguration()).thenReturn(configuration);
1115
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001116 Intent sendIntent = createSendTextIntent();
1117 // We need app targets for direct targets to get displayed
1118 List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(15);
1119 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1120 Mockito.anyBoolean(),
1121 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
1122
1123 // Set up resources
1124 MetricsLogger mockLogger = sOverrides.metricsLogger;
1125 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
1126 // Create direct share target
1127 List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
1128 resolvedComponentInfos.get(14).getResolveInfoAt(0).activityInfo.packageName);
1129 ResolveInfo ri = ResolverDataProvider.createResolveInfo(16, 0);
1130
1131 // Start activity
1132 final ChooserWrapperActivity activity = mActivityRule
1133 .launchActivity(Intent.createChooser(sendIntent, null));
1134 // Insert the direct share target
arangelov5fc9e7d2020-01-07 17:59:14 +00001135 Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
1136 directShareToShortcutInfos.put(serviceTargets.get(0), null);
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001137 InstrumentationRegistry.getInstrumentation().runOnMainSync(
1138 () -> activity.getAdapter().addServiceResults(
1139 activity.createTestDisplayResolveInfo(sendIntent,
1140 ri,
1141 "testLabel",
1142 "testInfo",
arangelovb0802dc2019-10-18 18:03:44 +01001143 sendIntent,
1144 /* resolveInfoPresentationGetter */ null),
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001145 serviceTargets,
arangelov5fc9e7d2020-01-07 17:59:14 +00001146 TARGET_TYPE_CHOOSER_TARGET,
1147 directShareToShortcutInfos)
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001148 );
1149 // Thread.sleep shouldn't be a thing in an integration test but it's
1150 // necessary here because of the way the code is structured
1151 // TODO: restructure the tests b/129870719
1152 Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1153
Sergey Troshin40e979e2019-12-30 17:29:50 +01001154 assertThat(
1155 String.format("Chooser should have %d targets (%d apps, 1 direct, 15 A-Z)",
1156 appTargetsExpected + 16, appTargetsExpected),
1157 activity.getAdapter().getCount(), is(appTargetsExpected + 16));
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001158 assertThat("Chooser should have exactly one selectable direct target",
1159 activity.getAdapter().getSelectableServiceTargetCount(), is(1));
1160 assertThat("The resolver info must match the resolver info used to create the target",
1161 activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
1162
1163 // Click on the direct target
1164 String name = serviceTargets.get(0).getTitle().toString();
1165 onView(withText(name))
1166 .perform(click());
1167 waitForIdle();
1168
1169 // Currently we're seeing 3 invocations
1170 // 1. ChooserActivity.onCreate()
1171 // 2. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
1172 // 3. ChooserActivity.startSelected -- which is the one we're after
1173 verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
1174 assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
1175 is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
1176 assertThat("The packages shouldn't match for app target and direct target", logMakerCaptor
1177 .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(-1));
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001178 }
1179
arangelovb4fc3972020-01-15 15:10:12 +00001180 @Test
1181 public void testWorkTab_displayedWhenWorkProfileUserAvailable() {
1182 // enable the work tab feature flag
1183 ResolverActivity.ENABLE_TABBED_VIEW = true;
1184 Intent sendIntent = createSendTextIntent();
1185 sendIntent.setType("TestType");
1186 markWorkProfileUserAvailable();
1187
1188 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1189 waitForIdle();
1190
1191 onView(withId(R.id.tabs)).check(matches(isDisplayed()));
1192 }
1193
1194 @Test
1195 public void testWorkTab_hiddenWhenWorkProfileUserNotAvailable() {
1196 // enable the work tab feature flag
1197 ResolverActivity.ENABLE_TABBED_VIEW = true;
1198 Intent sendIntent = createSendTextIntent();
1199 sendIntent.setType("TestType");
1200
1201 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1202 waitForIdle();
1203
1204 onView(withId(R.id.tabs)).check(matches(not(isDisplayed())));
1205 }
1206
1207 @Test
1208 public void testWorkTab_eachTabUsesExpectedAdapter() {
1209 // enable the work tab feature flag
1210 ResolverActivity.ENABLE_TABBED_VIEW = true;
1211 int personalProfileTargets = 3;
1212 List<ResolvedComponentInfo> personalResolvedComponentInfos =
1213 createResolvedComponentsForTest(personalProfileTargets);
1214 int workProfileTargets = 4;
1215 List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(
1216 workProfileTargets);
1217 when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
1218 Mockito.anyBoolean(),
1219 Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos);
1220 when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
1221 Mockito.anyBoolean(),
1222 Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
1223 Intent sendIntent = createSendTextIntent();
1224 sendIntent.setType("TestType");
1225 markWorkProfileUserAvailable();
1226
1227 final ChooserWrapperActivity activity =
1228 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1229 waitForIdle();
1230
1231 assertThat(activity.getCurrentUserHandle().getIdentifier(), is(0));
1232 // The work list adapter must only be filled when we open the work tab
1233 assertThat(activity.getWorkListAdapter().getCount(), is(0));
1234 onView(withText(R.string.resolver_work_tab)).perform(click());
1235 assertThat(activity.getCurrentUserHandle().getIdentifier(), is(10));
1236 assertThat(activity.getPersonalListAdapter().getCount(), is(personalProfileTargets));
1237 assertThat(activity.getWorkListAdapter().getCount(), is(workProfileTargets));
1238 }
1239
1240 @Test
1241 public void testWorkTab_workProfileHasExpectedNumberOfTargets() {
1242 // enable the work tab feature flag
1243 ResolverActivity.ENABLE_TABBED_VIEW = true;
1244 markWorkProfileUserAvailable();
1245 int workProfileTargets = 4;
1246 List<ResolvedComponentInfo> workResolvedComponentInfos =
1247 createResolvedComponentsForTest(workProfileTargets);
1248 when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
1249 Mockito.anyBoolean(),
1250 Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
1251 Intent sendIntent = createSendTextIntent();
1252 sendIntent.setType("TestType");
1253
1254 final ChooserWrapperActivity activity =
1255 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1256 waitForIdle();
1257 onView(withText(R.string.resolver_work_tab)).perform(click());
1258 waitForIdle();
1259
1260 assertThat(activity.getWorkListAdapter().getCount(), is(workProfileTargets));
1261 }
1262
1263 @Ignore // b/148156663
1264 @Test
1265 public void testWorkTab_selectingWorkTabAppOpensAppInWorkProfile() throws InterruptedException {
1266 // enable the work tab feature flag
1267 ResolverActivity.ENABLE_TABBED_VIEW = true;
1268 markWorkProfileUserAvailable();
1269 int workProfileTargets = 4;
1270 List<ResolvedComponentInfo> workResolvedComponentInfos =
1271 createResolvedComponentsForTest(workProfileTargets);
1272 when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
1273 Mockito.anyBoolean(),
1274 Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
1275 Intent sendIntent = createSendTextIntent();
1276 sendIntent.setType("TestType");
1277 ResolveInfo[] chosen = new ResolveInfo[1];
1278 sOverrides.onSafelyStartCallback = targetInfo -> {
1279 chosen[0] = targetInfo.getResolveInfo();
1280 return true;
1281 };
1282
1283 mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
1284 waitForIdle();
1285 onView(withText(R.string.resolver_work_tab)).perform(click());
1286 waitForIdle();
1287 // wait for the share sheet to expand
1288 Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
1289
1290 onView(first(withText(workResolvedComponentInfos.get(0)
1291 .getResolveInfoAt(0).activityInfo.applicationInfo.name)))
1292 .perform(click());
1293 waitForIdle();
1294 assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0)));
1295 }
1296
Matt Pietal26038402019-01-08 07:29:34 -05001297 private Intent createSendTextIntent() {
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -08001298 Intent sendIntent = new Intent();
1299 sendIntent.setAction(Intent.ACTION_SEND);
1300 sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
Matt Pietalcdfcd9a2019-03-05 08:31:47 -05001301 sendIntent.setType("text/plain");
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -08001302 return sendIntent;
1303 }
1304
Matt Pietal26038402019-01-08 07:29:34 -05001305 private Intent createSendTextIntentWithPreview(String title, Uri imageThumbnail) {
1306 Intent sendIntent = new Intent();
1307 sendIntent.setAction(Intent.ACTION_SEND);
1308 sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
1309 sendIntent.putExtra(Intent.EXTRA_TITLE, title);
1310 if (imageThumbnail != null) {
1311 ClipData.Item clipItem = new ClipData.Item(imageThumbnail);
1312 sendIntent.setClipData(new ClipData("Clip Label", new String[]{"image/png"}, clipItem));
1313 }
1314
1315 return sendIntent;
1316 }
1317
Matt Pietal46d828c2019-02-05 08:07:07 -05001318 private Intent createSendUriIntentWithPreview(ArrayList<Uri> uris) {
Matt Pietal0ea391b2019-01-30 10:44:15 -05001319 Intent sendIntent = new Intent();
1320
1321 if (uris.size() > 1) {
1322 sendIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
1323 sendIntent.putExtra(Intent.EXTRA_STREAM, uris);
1324 } else {
1325 sendIntent.setAction(Intent.ACTION_SEND);
1326 sendIntent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
1327 }
1328
1329 return sendIntent;
1330 }
1331
Matt Pietal26038402019-01-08 07:29:34 -05001332 private Intent createViewTextIntent() {
1333 Intent viewIntent = new Intent();
1334 viewIntent.setAction(Intent.ACTION_VIEW);
1335 viewIntent.putExtra(Intent.EXTRA_TEXT, "testing intent viewing");
1336 return viewIntent;
1337 }
1338
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -08001339 private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
1340 List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
1341 for (int i = 0; i < numberOfResults; i++) {
Hakan Seyalioglu9149dca2017-01-17 12:20:01 -08001342 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -08001343 }
1344 return infoList;
1345 }
1346
Hakan Seyalioglu13405c52017-01-31 19:01:31 -08001347 private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
1348 int numberOfResults) {
1349 List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
1350 for (int i = 0; i < numberOfResults; i++) {
1351 if (i == 0) {
1352 infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i));
1353 } else {
1354 infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
1355 }
1356 }
1357 return infoList;
1358 }
1359
arangelovb4fc3972020-01-15 15:10:12 +00001360 private List<ResolvedComponentInfo> createResolvedComponentsForTestWithUserId(
1361 int numberOfResults, int userId) {
1362 List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
1363 for (int i = 0; i < numberOfResults; i++) {
1364 infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
1365 }
1366 return infoList;
1367 }
1368
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001369 private List<ChooserTarget> createDirectShareTargets(int numberOfResults, String packageName) {
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001370 Icon icon = Icon.createWithBitmap(createBitmap());
1371 String testTitle = "testTitle";
1372 List<ChooserTarget> targets = new ArrayList<>();
1373 for (int i = 0; i < numberOfResults; i++) {
Susi Kharraz-Post8c14f772019-04-17 16:33:41 -04001374 ComponentName componentName;
1375 if (packageName.isEmpty()) {
1376 componentName = ResolverDataProvider.createComponentName(i);
1377 } else {
1378 componentName = new ComponentName(packageName, packageName + ".class");
1379 }
Susi Kharraz-Post14cbfcd2019-04-01 11:07:59 -04001380 ChooserTarget tempTarget = new ChooserTarget(
1381 testTitle + i,
1382 icon,
1383 (float) (1 - ((i + 1) / 10.0)),
1384 componentName,
1385 null);
1386 targets.add(tempTarget);
1387 }
1388 return targets;
1389 }
1390
Hakan Seyalioglue1276bf2016-12-07 16:38:57 -08001391 private void waitForIdle() {
1392 InstrumentationRegistry.getInstrumentation().waitForIdleSync();
1393 }
Matt Pietal26038402019-01-08 07:29:34 -05001394
1395 private Bitmap createBitmap() {
1396 int width = 200;
1397 int height = 200;
1398 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
1399 Canvas canvas = new Canvas(bitmap);
1400
1401 Paint paint = new Paint();
1402 paint.setColor(Color.RED);
1403 paint.setStyle(Paint.Style.FILL);
1404 canvas.drawPaint(paint);
1405
1406 paint.setColor(Color.WHITE);
1407 paint.setAntiAlias(true);
1408 paint.setTextSize(14.f);
1409 paint.setTextAlign(Paint.Align.CENTER);
1410 canvas.drawText("Hi!", (width / 2.f), (height / 2.f), paint);
1411
1412 return bitmap;
1413 }
Mehdi Alizadeh707c0cf2019-09-03 18:11:48 -07001414
1415 private List<ShareShortcutInfo> createShortcuts(Context context) {
1416 Intent testIntent = new Intent("TestIntent");
1417
1418 List<ShareShortcutInfo> shortcuts = new ArrayList<>();
1419 shortcuts.add(new ShareShortcutInfo(
1420 new ShortcutInfo.Builder(context, "shortcut1")
1421 .setIntent(testIntent).setShortLabel("label1").setRank(3).build(), // 0 2
1422 new ComponentName("package1", "class1")));
1423 shortcuts.add(new ShareShortcutInfo(
1424 new ShortcutInfo.Builder(context, "shortcut2")
1425 .setIntent(testIntent).setShortLabel("label2").setRank(7).build(), // 1 3
1426 new ComponentName("package2", "class2")));
1427 shortcuts.add(new ShareShortcutInfo(
1428 new ShortcutInfo.Builder(context, "shortcut3")
1429 .setIntent(testIntent).setShortLabel("label3").setRank(1).build(), // 2 0
1430 new ComponentName("package3", "class3")));
1431 shortcuts.add(new ShareShortcutInfo(
1432 new ShortcutInfo.Builder(context, "shortcut4")
1433 .setIntent(testIntent).setShortLabel("label4").setRank(3).build(), // 3 2
1434 new ComponentName("package4", "class4")));
1435
1436 return shortcuts;
1437 }
1438
1439 private void assertCorrectShortcutToChooserTargetConversion(List<ShareShortcutInfo> shortcuts,
1440 List<ChooserTarget> chooserTargets, int[] expectedOrder, float[] expectedScores) {
1441 assertEquals(expectedOrder.length, chooserTargets.size());
1442 for (int i = 0; i < chooserTargets.size(); i++) {
1443 ChooserTarget ct = chooserTargets.get(i);
1444 ShortcutInfo si = shortcuts.get(expectedOrder[i]).getShortcutInfo();
1445 ComponentName cn = shortcuts.get(expectedOrder[i]).getTargetComponent();
1446
1447 assertEquals(si.getId(), ct.getIntentExtras().getString(Intent.EXTRA_SHORTCUT_ID));
1448 assertEquals(si.getShortLabel(), ct.getTitle());
1449 assertThat(Math.abs(expectedScores[i] - ct.getScore()) < 0.000001, is(true));
1450 assertEquals(cn.flattenToString(), ct.getComponentName().flattenToString());
1451 }
1452 }
arangelovb4fc3972020-01-15 15:10:12 +00001453
1454 private void markWorkProfileUserAvailable() {
1455 sOverrides.workProfileUserHandle = UserHandle.of(10);
1456 }
Matt Pietal26038402019-01-08 07:29:34 -05001457}