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 package com.android.server.pm;
17 
18 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
19 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
20 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
21 
22 import android.content.ComponentName;
23 import android.content.pm.ShortcutInfo;
24 import android.platform.test.annotations.Presubmit;
25 
26 import androidx.test.filters.SmallTest;
27 
28 import com.android.frameworks.servicestests.R;
29 import com.android.server.pm.ShortcutService.ConfigConstants;
30 
31 import java.util.Set;
32 
33 /**
34  * Tests related to shortcut rank auto-adjustment.
35  */
36 @Presubmit
37 @SmallTest
38 public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
39 
40     private static final String CALLING_PACKAGE = CALLING_PACKAGE_1;
41 
42     private static final ComponentName A1 = new ComponentName(CALLING_PACKAGE,
43             ShortcutActivity.class.getName());
44 
45     private static final ComponentName A2 = new ComponentName(CALLING_PACKAGE,
46             ShortcutActivity2.class.getName());
47 
48     private static final ComponentName A3 = new ComponentName(CALLING_PACKAGE,
49             ShortcutActivity3.class.getName());
50 
shortcut(String id, ComponentName activity, int rank)51     private ShortcutInfo shortcut(String id, ComponentName activity, int rank) {
52         return makeShortcutWithActivityAndRank(id, activity, rank);
53     }
54 
shortcut(String id, ComponentName activity)55     private ShortcutInfo shortcut(String id, ComponentName activity) {
56         return makeShortcutWithActivityAndRank(id, activity, ShortcutInfo.RANK_NOT_SET);
57     }
58 
shortcut(String id, Set<String> categories)59     private ShortcutInfo shortcut(String id, Set<String> categories) {
60         return makeShortcutWithCategory(id, categories);
61     }
62 
63     @Override
setUp()64     protected void setUp() throws Exception {
65         super.setUp();
66 
67         // We don't need throttling during this test class, and also relax the max cap.
68         mService.updateConfigurationLocked(
69                 ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
70                 + ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
71         );
72 
73         setCaller(CALLING_PACKAGE, USER_0);
74     }
75 
publishManifestShortcuts(ComponentName activity, int resId)76     private void publishManifestShortcuts(ComponentName activity, int resId) {
77         addManifestShortcutResource(activity, resId);
78         updatePackageVersion(CALLING_PACKAGE, 1);
79         mService.mPackageMonitor.onReceive(getTestContext(),
80                 genPackageAddIntent(CALLING_PACKAGE, USER_0));
81     }
82 
testSetDynamicShortcuts_noManifestShortcuts()83     public void testSetDynamicShortcuts_noManifestShortcuts() {
84         mManager.setDynamicShortcuts(list(
85                 shortcut("s1", A1)
86         ));
87 
88         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
89                 .haveRanksInOrder("s1");
90 
91         assertTrue(mManager.setDynamicShortcuts(list(
92                 shortcut("s5", A1),
93                 shortcut("s4", A1),
94                 shortcut("s3", A1)
95         )));
96         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
97                 .haveRanksInOrder("s5", "s4", "s3");
98 
99         // RANK_NOT_SET is always the last.
100         assertTrue(mManager.setDynamicShortcuts(list(
101                 shortcut("s5", A1),
102                 shortcut("s4", A1, 5),
103                 shortcut("s3", A1, 3),
104                 shortcut("s2", A1)
105         )));
106         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
107                 .haveRanksInOrder("s3", "s4", "s5", "s2");
108 
109         // Same rank, preserve the argument order.
110         assertTrue(mManager.setDynamicShortcuts(list(
111                 shortcut("s5", A1, 5),
112                 shortcut("s4", A1, 0),
113                 shortcut("s3", A1, 5)
114         )));
115         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
116                 .haveRanksInOrder("s4", "s5", "s3");
117 
118         // Multiple activities.
119         assertTrue(mManager.setDynamicShortcuts(list(
120                 shortcut("s5", A1),
121                 shortcut("s4", A2),
122                 shortcut("s3", A3)
123         )));
124         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
125                 .haveRanksInOrder("s5");
126         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
127                 .haveRanksInOrder("s4");
128         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
129                 .haveRanksInOrder("s3");
130 
131         assertTrue(mManager.setDynamicShortcuts(list(
132                 shortcut("s5", A1, 5),
133                 shortcut("s4", A1),
134                 shortcut("s3", A1, 5),
135                 shortcut("x5", A2, 5),
136                 shortcut("x4", A2),
137                 shortcut("x3", A2, 1)
138         )));
139         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
140                 .haveRanksInOrder("s5", "s3", "s4");
141         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
142                 .haveRanksInOrder("x3", "x5", "x4");
143 
144         // Clear.  Make sure it wouldn't lead to invalid internals state.
145         // (ShortcutService.verifyStates() will do so internally.)
146         assertTrue(mManager.setDynamicShortcuts(list()));
147         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1).isEmpty();
148         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2).isEmpty();
149     }
150 
runTestWithManifestShortcuts(Runnable r)151     private void runTestWithManifestShortcuts(Runnable r) {
152         publishManifestShortcuts(A1, R.xml.shortcut_5_alt);
153         publishManifestShortcuts(A2, R.xml.shortcut_1);
154 
155         assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
156                 .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
157 
158         assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
159                 .haveRanksInOrder("ms1");
160 
161         // Existence of manifest shortcuts shouldn't affect dynamic shortcut ranks,
162         // so running another test here should pass.
163         r.run();
164 
165         // And dynamic shortcut tests shouldn't affect manifest shortcuts, so repeat the
166         // same check.
167         assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
168                 .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
169 
170         assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
171                 .haveRanksInOrder("ms1");
172     }
173 
testSetDynamicShortcuts_withManifestShortcuts()174     public void testSetDynamicShortcuts_withManifestShortcuts() {
175         runTestWithManifestShortcuts(() -> testSetDynamicShortcuts_noManifestShortcuts());
176     }
177 
testAddDynamicShortcuts_noManifestShortcuts()178     public void testAddDynamicShortcuts_noManifestShortcuts() {
179         mManager.addDynamicShortcuts(list(
180                 shortcut("s1", A1)
181         ));
182         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
183                 .haveRanksInOrder("s1");
184 
185         //------------------------------------------------------
186         long lastApiTime = ++mInjectedCurrentTimeMillis;
187 
188         mManager.addDynamicShortcuts(list(
189                 shortcut("s5", A1, 0),
190                 shortcut("s4", A1),
191                 shortcut("s2", A1, 3),
192                 shortcut("x1", A2),
193                 shortcut("x3", A2, 2),
194                 shortcut("x2", A2, 2),
195                 shortcut("s3", A1, 0)
196         ));
197         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
198                 .haveRanksInOrder("s5", "s3", "s1", "s2", "s4");
199 
200         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
201                 .haveRanksInOrder("x3", "x2", "x1");
202 
203         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
204                 .haveIds("s5", "s3", "s1", "s2", "s4", "x3", "x2", "x1");
205 
206         //------------------------------------------------------
207         lastApiTime = ++mInjectedCurrentTimeMillis;
208 
209         mManager.addDynamicShortcuts(list(
210                 shortcut("s1", A1, 1)
211         ));
212         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
213                 .haveRanksInOrder("s5", "s1", "s3", "s2", "s4");
214 
215         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
216                 .haveRanksInOrder("x3", "x2", "x1");
217 
218         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
219                 .haveIds("s1", "s3");
220 
221         //------------------------------------------------------
222         lastApiTime = ++mInjectedCurrentTimeMillis;
223 
224         mManager.addDynamicShortcuts(list(
225                 shortcut("s1", A1, 1),
226 
227                 // This is add, not update, so the following means s5 will have NO_RANK,
228                 // which puts it at the end.
229                 shortcut("s5", A1),
230                 shortcut("s3", A1, 0),
231 
232                 // s10 also has NO_RANK, so it'll be put at the end, even after "s5" as we preserve
233                 // the argument order.
234                 shortcut("s10", A1),
235 
236                 // Note we're changing the activity for x2.
237                 shortcut("x2", A1, 0),
238                 shortcut("x10", A2)
239         ));
240         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
241                 .haveRanksInOrder("s3", "x2", "s1", "s2", "s4", "s5", "s10");
242 
243         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
244                 .haveRanksInOrder("x3", "x1", "x10");
245 
246         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
247                 .haveIds("s3", "x2", "s1", "s5", "s10", "x1", "x10");
248 
249         //------------------------------------------------------
250         lastApiTime = ++mInjectedCurrentTimeMillis;
251 
252         // Change the activities again.
253         mManager.addDynamicShortcuts(list(
254                 shortcut("s1", A2),
255                 shortcut("s2", A2, 999)
256         ));
257         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
258                 .haveRanksInOrder("s3", "x2", "s4", "s5", "s10");
259 
260         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
261                 .haveRanksInOrder("x3", "x1", "x10", "s2", "s1");
262 
263         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
264                 .haveIds("s1", "s2", "s4", "s5", "s10");
265     }
266 
testAddDynamicShortcuts_withManifestShortcuts()267     public void testAddDynamicShortcuts_withManifestShortcuts() {
268         runTestWithManifestShortcuts(() -> testAddDynamicShortcuts_noManifestShortcuts());
269     }
270 
testUpdateShortcuts_noManifestShortcuts()271     public void testUpdateShortcuts_noManifestShortcuts() {
272         mManager.addDynamicShortcuts(list(
273                 shortcut("s5", A1, 0),
274                 shortcut("s4", A1),
275                 shortcut("s2", A1, 3),
276                 shortcut("x1", A2),
277                 shortcut("x3", A2, 2),
278                 shortcut("x2", A2, 2),
279                 shortcut("s3", A1, 0)
280         ));
281         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
282                 .haveRanksInOrder("s5", "s3", "s2", "s4");
283 
284         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
285                 .haveRanksInOrder("x3", "x2", "x1");
286 
287         //------------------------------------------------------
288         long lastApiTime = ++mInjectedCurrentTimeMillis;
289 
290         mManager.updateShortcuts(list());
291         // Same order.
292         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
293                 .haveRanksInOrder("s5", "s3", "s2", "s4");
294 
295         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
296                 .haveRanksInOrder("x3", "x2", "x1");
297 
298         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
299                 .isEmpty();
300 
301 
302         runWithCaller(LAUNCHER_1, USER_0, () -> {
303             mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
304         });
305         // Still same order.
306         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
307                 .haveRanksInOrder("s5", "s3", "s2", "s4");
308 
309         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
310                 .haveRanksInOrder("x3", "x2", "x1");
311 
312         //------------------------------------------------------
313         lastApiTime = ++mInjectedCurrentTimeMillis;
314 
315         mManager.updateShortcuts(list(
316                 shortcut("s4", A1, 1),
317 
318                 // Rank not changing, should keep the same positions.
319                 // c.f. in case of addDynamicShortcuts, this means "put them at the end".
320                 shortcut("s3", A1),
321                 shortcut("x2", A2)
322         ));
323         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
324                 .haveRanksInOrder("s5", "s4", "s3", "s2");
325 
326         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
327                 .haveRanksInOrder("x3", "x2", "x1");
328 
329         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
330                 .haveIds("s4", "s3", "s2", "x2");
331 
332         //------------------------------------------------------
333         lastApiTime = ++mInjectedCurrentTimeMillis;
334 
335         mManager.updateShortcuts(list(
336                 shortcut("s4", A1, 0),
337 
338                 // Change the activity without specifying a rank -> keep the same rank.
339                 shortcut("s5", A2),
340 
341                 // Change the activity without specifying a rank -> assign a new rank.
342                 shortcut("x2", A1, 2),
343 
344                 // "xx" doesn't exist, so it'll be ignored.
345                 shortcut("xx", A1, 0)
346         ));
347         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
348                 .haveRanksInOrder("s4", "x2", "s3", "s2");
349 
350         // Interesting case: both x3 and s5 originally had rank=0, and in this case s5 has moved
351         // to A2 without changing the rank.  So they're tie for the new rank, as well as
352         // the "rank changed" bit.  Also in this case, "s5" won't have an implicit order, since
353         // its rank isn't changing.  So we sort them by ID, thus s5 comes before x3.
354         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
355                 .haveRanksInOrder("s5", "x3", "x1");
356 
357         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
358                 .haveIds("s4", "x2", "s5", "x3");
359 
360         //------------------------------------------------------
361         lastApiTime = ++mInjectedCurrentTimeMillis;
362 
363         mManager.updateShortcuts(list(
364                 shortcut("s3", A3)));
365 
366         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
367                 .haveRanksInOrder("s4", "x2", "s2");
368         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
369                 .haveRanksInOrder("s5", "x3", "x1");
370         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
371                 .haveRanksInOrder("s3");
372 
373         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
374                 .haveIds("s3", "s2");
375     }
376 
testUpdateShortcuts_withManifestShortcuts()377     public void testUpdateShortcuts_withManifestShortcuts() {
378         runTestWithManifestShortcuts(() -> testUpdateShortcuts_noManifestShortcuts());
379     }
380 
testDeleteDynamicShortcuts_noManifestShortcuts()381     public void testDeleteDynamicShortcuts_noManifestShortcuts() {
382         mManager.addDynamicShortcuts(list(
383                 shortcut("s5", A1, 0),
384                 shortcut("s4", A1),
385                 shortcut("s2", A1, 3),
386                 shortcut("x1", A2),
387                 shortcut("x3", A2, 2),
388                 shortcut("x2", A2, 2),
389                 shortcut("s3", A1, 0)
390         ));
391         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
392                 .haveRanksInOrder("s5", "s3", "s2", "s4");
393 
394         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
395                 .haveRanksInOrder("x3", "x2", "x1");
396 
397         //------------------------------------------------------
398         long lastApiTime = ++mInjectedCurrentTimeMillis;
399 
400         mManager.removeDynamicShortcuts(list());
401 
402         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
403                 .haveRanksInOrder("s5", "s3", "s2", "s4");
404 
405         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
406                 .haveRanksInOrder("x3", "x2", "x1");
407 
408         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
409                 .isEmpty();
410 
411         runWithCaller(LAUNCHER_1, USER_0, () -> {
412             mLauncherApps.pinShortcuts(
413                     CALLING_PACKAGE, list("s2", "s4", "x1", "x2"), HANDLE_USER_0);
414         });
415         // Still same order.
416 
417         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
418                 .haveRanksInOrder("s5", "s3", "s2", "s4");
419 
420         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
421                 .haveRanksInOrder("x3", "x2", "x1");
422 
423         //------------------------------------------------------
424         lastApiTime = ++mInjectedCurrentTimeMillis;
425 
426         mManager.removeDynamicShortcuts(list("s3", "x1", "xxxx"));
427 
428         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
429                 .haveRanksInOrder("s5", "s2", "s4");
430 
431         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
432                 .haveRanksInOrder("x3", "x2");
433 
434         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
435                 .haveIds("s2", "s4");
436     }
437 
testDeleteDynamicShortcuts_withManifestShortcuts()438     public void testDeleteDynamicShortcuts_withManifestShortcuts() {
439         runTestWithManifestShortcuts(() -> testDeleteDynamicShortcuts_noManifestShortcuts());
440     }
441 
testDisableShortcuts_noManifestShortcuts()442     public void testDisableShortcuts_noManifestShortcuts() {
443         mManager.addDynamicShortcuts(list(
444                 shortcut("s5", A1, 0),
445                 shortcut("s4", A1),
446                 shortcut("s2", A1, 3),
447                 shortcut("x1", A2),
448                 shortcut("x3", A2, 2),
449                 shortcut("x2", A2, 2),
450                 shortcut("s3", A1, 0)
451         ));
452         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
453                 .haveRanksInOrder("s5", "s3", "s2", "s4");
454 
455         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
456                 .haveRanksInOrder("x3", "x2", "x1");
457 
458         //------------------------------------------------------
459         long lastApiTime = ++mInjectedCurrentTimeMillis;
460 
461         mManager.disableShortcuts(list());
462 
463         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
464                 .haveRanksInOrder("s5", "s3", "s2", "s4");
465 
466         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
467                 .haveRanksInOrder("x3", "x2", "x1");
468 
469         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
470                 .isEmpty();
471 
472         //------------------------------------------------------
473         lastApiTime = ++mInjectedCurrentTimeMillis;
474 
475         mManager.disableShortcuts(list("s3", "x1", "xxxx"));
476 
477         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
478                 .haveRanksInOrder("s5", "s2", "s4");
479 
480         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
481                 .haveRanksInOrder("x3", "x2");
482 
483         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
484                 .haveIds("s2", "s4");
485 
486         runWithCaller(LAUNCHER_1, USER_0, () -> {
487             mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
488         });
489         // Still same order.
490         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
491                 .haveRanksInOrder("s5", "s2", "s4");
492 
493         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
494                 .haveRanksInOrder("x3", "x2");
495 
496         //------------------------------------------------------
497         lastApiTime = ++mInjectedCurrentTimeMillis;
498 
499         mManager.disableShortcuts(list("s2", "x3"));
500 
501         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
502                 .haveRanksInOrder("s5", "s4");
503 
504         assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
505                 .haveRanksInOrder("x2");
506 
507         assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
508                 .haveIds("s4", "x2");
509     }
510 
testDisableShortcuts_withManifestShortcuts()511     public void testDisableShortcuts_withManifestShortcuts() {
512         runTestWithManifestShortcuts(() -> testDisableShortcuts_noManifestShortcuts());
513     }
514 
testGetSharingShortcutCount()515     public void testGetSharingShortcutCount() {
516         addManifestShortcutResource(
517                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
518                 R.xml.shortcut_share_targets);
519         updatePackageVersion(CALLING_PACKAGE_1, 1);
520         mService.mPackageMonitor.onReceive(getTestContext(),
521                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
522 
523         // There are two valid <share-target> definitions in the test manifest with two different
524         // categories: {"com.test.category.CATEGORY1", "com.test.category.CATEGORY2"} and
525         // {"com.test.category.CATEGORY5", "com.test.category.CATEGORY6"}.
526         //
527         // Note that a shortcut is a match, only if it has ALL of the categories of at least one
528         // of the share-target definitions from the manifest.
529 
530         mManager.addDynamicShortcuts(list(
531                 shortcut("s1", set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2")),
532                 shortcut("s2", set("com.test.category.CATEGORY5")),
533                 shortcut("s3", set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6")),
534                 shortcut("s4", set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2",
535                         "com.test.category.CATEGORY5", "com.test.category.CATEGORY6")),
536                 shortcut("s5", A1)
537         ));
538 
539         assertEquals(3, getCallerSharingShortcutCount());
540     }
541 }
542