• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.pm;
17 
18 import static android.content.pm.ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED;
19 import static android.content.pm.ShortcutInfo.DISABLED_REASON_NOT_DISABLED;
20 import static android.content.pm.ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH;
21 import static android.content.pm.ShortcutInfo.DISABLED_REASON_VERSION_LOWER;
22 
23 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
24 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyStringOrNull;
25 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDisabled;
26 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamic;
27 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamicOrPinned;
28 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllEnabled;
29 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIntents;
30 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveTitle;
31 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllImmutable;
32 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllKeyFieldsOnly;
33 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllManifest;
34 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotHaveIntents;
35 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotHaveTitle;
36 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotKeyFieldsOnly;
37 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotManifest;
38 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllPinned;
39 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllUnique;
40 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBitmapSize;
41 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBundleEmpty;
42 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackNotReceived;
43 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackReceived;
44 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCannotUpdateImmutable;
45 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicAndPinned;
46 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicOnly;
47 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicShortcutCountExceeded;
48 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertEmpty;
49 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
50 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertForLauncherCallback;
51 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertShortcutIds;
52 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
53 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.filterByActivity;
54 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.findShortcut;
55 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
56 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
57 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makeBundle;
58 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.pfdToBitmap;
59 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetAll;
60 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
61 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.waitOnMainThread;
62 
63 import static org.mockito.Matchers.any;
64 import static org.mockito.Matchers.anyInt;
65 import static org.mockito.Matchers.anyString;
66 import static org.mockito.Matchers.eq;
67 import static org.mockito.Mockito.doReturn;
68 import static org.mockito.Mockito.mock;
69 import static org.mockito.Mockito.reset;
70 import static org.mockito.Mockito.times;
71 import static org.mockito.Mockito.verify;
72 
73 import android.Manifest.permission;
74 import android.app.ActivityManager;
75 import android.content.ActivityNotFoundException;
76 import android.content.ComponentName;
77 import android.content.Intent;
78 import android.content.IntentFilter;
79 import android.content.pm.ApplicationInfo;
80 import android.content.pm.LauncherApps;
81 import android.content.pm.LauncherApps.PinItemRequest;
82 import android.content.pm.LauncherApps.ShortcutQuery;
83 import android.content.pm.PackageInfo;
84 import android.content.pm.ShortcutInfo;
85 import android.content.pm.ShortcutManager;
86 import android.graphics.Bitmap;
87 import android.graphics.Bitmap.CompressFormat;
88 import android.graphics.BitmapFactory;
89 import android.graphics.drawable.AdaptiveIconDrawable;
90 import android.graphics.drawable.Drawable;
91 import android.graphics.drawable.Icon;
92 import android.net.Uri;
93 import android.os.Bundle;
94 import android.os.Handler;
95 import android.os.Looper;
96 import android.os.Process;
97 import android.os.UserHandle;
98 import android.test.suitebuilder.annotation.SmallTest;
99 import android.util.Log;
100 import android.util.SparseArray;
101 import android.util.TypedXmlPullParser;
102 import android.util.TypedXmlSerializer;
103 import android.util.Xml;
104 
105 import com.android.frameworks.servicestests.R;
106 import com.android.server.pm.ShortcutService.ConfigConstants;
107 import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
108 import com.android.server.pm.ShortcutUser.PackageWithUser;
109 
110 import org.mockito.ArgumentCaptor;
111 import org.mockito.Mockito;
112 import org.xmlpull.v1.XmlPullParser;
113 import org.xmlpull.v1.XmlPullParserException;
114 
115 import java.io.ByteArrayInputStream;
116 import java.io.ByteArrayOutputStream;
117 import java.io.File;
118 import java.io.FileOutputStream;
119 import java.io.IOException;
120 import java.io.InputStream;
121 import java.io.InputStreamReader;
122 import java.io.OutputStream;
123 import java.nio.charset.StandardCharsets;
124 import java.util.ArrayList;
125 import java.util.List;
126 import java.util.Locale;
127 import java.util.function.BiConsumer;
128 
129 /**
130  * Tests for ShortcutService and ShortcutManager.
131  *
132  m FrameworksServicesTests &&
133  adb install \
134  -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
135  adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 \
136  -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
137  */
138 @SmallTest
139 public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
140 
141     private static final int CACHE_OWNER_0 = LauncherApps.FLAG_CACHE_NOTIFICATION_SHORTCUTS;
142     private static final int CACHE_OWNER_1 = LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS;
143     private static final int CACHE_OWNER_2 = LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS;
144 
145     @Override
tearDown()146     protected void tearDown() throws Exception {
147         deleteUriFile("file32x32.jpg");
148         deleteUriFile("file64x64.jpg");
149         deleteUriFile("file512x512.jpg");
150 
151         super.tearDown();
152     }
153 
154     /**
155      * Test for the first launch path, no settings file available.
156      */
testFirstInitialize()157     public void testFirstInitialize() {
158         assertResetTimes(START_TIME, START_TIME + INTERVAL);
159     }
160 
161     /**
162      * Test for {@link ShortcutService#getLastResetTimeLocked()} and
163      * {@link ShortcutService#getNextResetTimeLocked()}.
164      */
testUpdateAndGetNextResetTimeLocked()165     public void testUpdateAndGetNextResetTimeLocked() {
166         assertResetTimes(START_TIME, START_TIME + INTERVAL);
167 
168         // Advance clock.
169         mInjectedCurrentTimeMillis += 100;
170 
171         // Shouldn't have changed.
172         assertResetTimes(START_TIME, START_TIME + INTERVAL);
173 
174         // Advance clock, almost the reset time.
175         mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
176 
177         // Shouldn't have changed.
178         assertResetTimes(START_TIME, START_TIME + INTERVAL);
179 
180         // Advance clock.
181         mInjectedCurrentTimeMillis += 1;
182 
183         assertResetTimes(START_TIME + INTERVAL, START_TIME + 2 * INTERVAL);
184 
185         // Advance further; 4 hours since start.
186         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
187 
188         assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
189     }
190 
191     /**
192      * Test for the restoration from saved file.
193      */
testInitializeFromSavedFile()194     public void testInitializeFromSavedFile() {
195 
196         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
197         assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
198 
199         mService.saveBaseStateLocked();
200 
201         dumpBaseStateFile();
202 
203         mService.saveDirtyInfo();
204 
205         // Restore.
206         initService();
207 
208         assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
209     }
210 
211     /**
212      * Test for the restoration from restored file.
213      */
testLoadFromBrokenFile()214     public void testLoadFromBrokenFile() {
215         // TODO Add various broken cases.
216     }
217 
testLoadConfig()218     public void testLoadConfig() {
219         mService.updateConfigurationLocked(
220                 ConfigConstants.KEY_RESET_INTERVAL_SEC + "=123,"
221                         + ConfigConstants.KEY_MAX_SHORTCUTS + "=4,"
222                         + ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=5,"
223                         + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=100,"
224                         + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "=50,"
225                         + ConfigConstants.KEY_ICON_FORMAT + "=WEBP,"
226                         + ConfigConstants.KEY_ICON_QUALITY + "=75");
227         assertEquals(123000, mService.getResetIntervalForTest());
228         assertEquals(4, mService.getMaxShortcutsForTest());
229         assertEquals(5, mService.getMaxUpdatesPerIntervalForTest());
230         assertEquals(100, mService.getMaxIconDimensionForTest());
231         assertEquals(CompressFormat.WEBP, mService.getIconPersistFormatForTest());
232         assertEquals(75, mService.getIconPersistQualityForTest());
233 
234         mInjectedIsLowRamDevice = true;
235         mService.updateConfigurationLocked(
236                 ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=100,"
237                         + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "=50,"
238                         + ConfigConstants.KEY_ICON_FORMAT + "=JPEG");
239         assertEquals(ShortcutService.DEFAULT_RESET_INTERVAL_SEC * 1000,
240                 mService.getResetIntervalForTest());
241 
242         assertEquals(ShortcutService.DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY,
243                 mService.getMaxShortcutsForTest());
244 
245         assertEquals(ShortcutService.DEFAULT_MAX_UPDATES_PER_INTERVAL,
246                 mService.getMaxUpdatesPerIntervalForTest());
247 
248         assertEquals(50, mService.getMaxIconDimensionForTest());
249 
250         assertEquals(CompressFormat.JPEG, mService.getIconPersistFormatForTest());
251 
252         assertEquals(ShortcutService.DEFAULT_ICON_PERSIST_QUALITY,
253                 mService.getIconPersistQualityForTest());
254     }
255 
256     // === Test for app side APIs ===
257 
258     /** Test for {@link android.content.pm.ShortcutManager#getMaxShortcutCountForActivity()} */
testGetMaxDynamicShortcutCount()259     public void testGetMaxDynamicShortcutCount() {
260         assertEquals(MAX_SHORTCUTS, mManager.getMaxShortcutCountForActivity());
261     }
262 
263     /** Test for {@link android.content.pm.ShortcutManager#getRemainingCallCount()} */
testGetRemainingCallCount()264     public void testGetRemainingCallCount() {
265         assertEquals(MAX_UPDATES_PER_INTERVAL, mManager.getRemainingCallCount());
266     }
267 
testGetIconMaxDimensions()268     public void testGetIconMaxDimensions() {
269         assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxWidth());
270         assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxHeight());
271     }
272 
273     /** Test for {@link android.content.pm.ShortcutManager#getRateLimitResetTime()} */
testGetRateLimitResetTime()274     public void testGetRateLimitResetTime() {
275         assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
276 
277         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
278 
279         assertEquals(START_TIME + 5 * INTERVAL, mManager.getRateLimitResetTime());
280     }
281 
testSetDynamicShortcuts()282     public void testSetDynamicShortcuts() {
283         setCaller(CALLING_PACKAGE_1, USER_0);
284 
285         final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
286         final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
287                 getTestContext().getResources(), R.drawable.icon2));
288         final Icon icon3 = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
289                 getTestContext().getResources(), R.drawable.icon2));
290 
291         final ShortcutInfo si1 = makeShortcut(
292                 "shortcut1",
293                 "Title 1",
294                 makeComponent(ShortcutActivity.class),
295                 icon1,
296                 makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
297                         "key1", "val1", "nest", makeBundle("key", 123)),
298                 /* weight */ 10);
299 
300         final ShortcutInfo si2 = makeShortcut(
301                 "shortcut2",
302                 "Title 2",
303                 /* activity */ null,
304                 icon2,
305                 makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
306                 /* weight */ 12);
307         final ShortcutInfo si3 = makeShortcut(
308                 "shortcut3",
309                 "Title 3",
310                 /* activity */ null,
311                 icon3,
312                 makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
313                 /* weight */ 13);
314 
315         assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
316         assertShortcutIds(assertAllNotKeyFieldsOnly(
317                 mManager.getDynamicShortcuts()),
318                 "shortcut1", "shortcut2", "shortcut3");
319         assertEquals(2, mManager.getRemainingCallCount());
320 
321         // TODO: Check fields
322 
323         assertTrue(mManager.setDynamicShortcuts(list(si1)));
324         assertShortcutIds(assertAllNotKeyFieldsOnly(
325                 mManager.getDynamicShortcuts()),
326                 "shortcut1");
327         assertEquals(1, mManager.getRemainingCallCount());
328 
329         assertTrue(mManager.setDynamicShortcuts(list()));
330         assertEquals(0, mManager.getDynamicShortcuts().size());
331         assertEquals(0, mManager.getRemainingCallCount());
332 
333         dumpsysOnLogcat();
334 
335         mInjectedCurrentTimeMillis++; // Need to advance the clock for reset to work.
336         mService.resetThrottlingInner(UserHandle.USER_SYSTEM);
337 
338         dumpsysOnLogcat();
339 
340         assertTrue(mManager.setDynamicShortcuts(list(si2, si3)));
341         assertEquals(2, mManager.getDynamicShortcuts().size());
342 
343         // TODO Check max number
344 
345         mRunningUsers.put(USER_10, true);
346 
347         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
348             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
349         });
350     }
351 
testAddDynamicShortcuts()352     public void testAddDynamicShortcuts() {
353         setCaller(CALLING_PACKAGE_1, USER_0);
354 
355         final ShortcutInfo si1 = makeShortcut("shortcut1");
356         final ShortcutInfo si2 = makeShortcut("shortcut2");
357         final ShortcutInfo si3 = makeShortcut("shortcut3");
358 
359         assertEquals(3, mManager.getRemainingCallCount());
360 
361         assertTrue(mManager.setDynamicShortcuts(list(si1)));
362         assertEquals(2, mManager.getRemainingCallCount());
363         assertShortcutIds(assertAllNotKeyFieldsOnly(
364                 mManager.getDynamicShortcuts()),
365                 "shortcut1");
366 
367         assertTrue(mManager.addDynamicShortcuts(list(si2, si3)));
368         assertEquals(1, mManager.getRemainingCallCount());
369         assertShortcutIds(assertAllNotKeyFieldsOnly(
370                 mManager.getDynamicShortcuts()),
371                 "shortcut1", "shortcut2", "shortcut3");
372 
373         // This should not crash.  It'll still consume the quota.
374         assertTrue(mManager.addDynamicShortcuts(list()));
375         assertEquals(0, mManager.getRemainingCallCount());
376         assertShortcutIds(assertAllNotKeyFieldsOnly(
377                 mManager.getDynamicShortcuts()),
378                 "shortcut1", "shortcut2", "shortcut3");
379 
380         mInjectedCurrentTimeMillis += INTERVAL; // reset
381 
382         // Add with the same ID
383         assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("shortcut1"))));
384         assertEquals(2, mManager.getRemainingCallCount());
385         assertShortcutIds(assertAllNotKeyFieldsOnly(
386                 mManager.getDynamicShortcuts()),
387                 "shortcut1", "shortcut2", "shortcut3");
388 
389         // TODO Check max number
390 
391         // TODO Check fields.
392 
393         mRunningUsers.put(USER_10, true);
394 
395         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
396             assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
397         });
398     }
399 
testPushDynamicShortcut()400     public void testPushDynamicShortcut() {
401         // Change the max number of shortcuts.
402         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5");
403 
404         setCaller(CALLING_PACKAGE_1, USER_0);
405 
406         final ShortcutInfo s1 = makeShortcut("s1");
407         final ShortcutInfo s2 = makeShortcut("s2");
408         final ShortcutInfo s3 = makeShortcut("s3");
409         final ShortcutInfo s4 = makeShortcut("s4");
410         final ShortcutInfo s5 = makeShortcut("s5");
411         final ShortcutInfo s6 = makeShortcut("s6");
412         final ShortcutInfo s7 = makeShortcut("s7");
413         final ShortcutInfo s8 = makeShortcut("s8");
414         final ShortcutInfo s9 = makeShortcut("s9");
415 
416         // Test push as first shortcut
417         mManager.pushDynamicShortcut(s1);
418         assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()), "s1");
419         assertEquals(0, getCallerShortcut("s1").getRank());
420         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
421                 eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_0));
422 
423         // Test push when other shortcuts exist
424         Mockito.reset(mMockUsageStatsManagerInternal);
425         assertTrue(mManager.setDynamicShortcuts(list(s1, s2)));
426         assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()), "s1", "s2");
427         mManager.pushDynamicShortcut(s3);
428         assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
429                 "s1", "s2", "s3");
430         assertEquals(0, getCallerShortcut("s3").getRank());
431         assertEquals(1, getCallerShortcut("s1").getRank());
432         assertEquals(2, getCallerShortcut("s2").getRank());
433         verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
434                 eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_0));
435         verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
436                 eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_0));
437         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
438                 eq(CALLING_PACKAGE_1), eq("s3"), eq(USER_0));
439 
440         mInjectedCurrentTimeMillis += INTERVAL; // reset
441 
442         // Push with set rank
443         Mockito.reset(mMockUsageStatsManagerInternal);
444         s4.setRank(2);
445         mManager.pushDynamicShortcut(s4);
446         assertEquals(2, getCallerShortcut("s4").getRank());
447         assertEquals(3, getCallerShortcut("s2").getRank());
448         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
449                 eq(CALLING_PACKAGE_1), eq("s4"), eq(USER_0));
450 
451         // Push existing shortcut with set rank
452         Mockito.reset(mMockUsageStatsManagerInternal);
453         final ShortcutInfo s4_2 = makeShortcut("s4");
454         s4_2.setRank(4);
455         mManager.pushDynamicShortcut(s4_2);
456         assertEquals(2, getCallerShortcut("s2").getRank());
457         assertEquals(3, getCallerShortcut("s4").getRank());
458         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
459                 eq(CALLING_PACKAGE_1), eq("s4"), eq(USER_0));
460 
461         mInjectedCurrentTimeMillis += INTERVAL; // reset
462 
463         // Test push as last
464         Mockito.reset(mMockUsageStatsManagerInternal);
465         mManager.pushDynamicShortcut(s5);
466         assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
467                 "s1", "s2", "s3", "s4", "s5");
468         assertEquals(0, getCallerShortcut("s5").getRank());
469         assertEquals(1, getCallerShortcut("s3").getRank());
470         assertEquals(2, getCallerShortcut("s1").getRank());
471         assertEquals(3, getCallerShortcut("s2").getRank());
472         assertEquals(4, getCallerShortcut("s4").getRank());
473         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
474                 eq(CALLING_PACKAGE_1), eq("s5"), eq(USER_0));
475 
476         // Push when max has already reached
477         Mockito.reset(mMockUsageStatsManagerInternal);
478         mManager.pushDynamicShortcut(s6);
479         assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
480                 "s1", "s2", "s3", "s5", "s6");
481         assertEquals(0, getCallerShortcut("s6").getRank());
482         assertEquals(1, getCallerShortcut("s5").getRank());
483         assertEquals(4, getCallerShortcut("s2").getRank());
484         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
485                 eq(CALLING_PACKAGE_1), eq("s6"), eq(USER_0));
486 
487         mInjectedCurrentTimeMillis += INTERVAL; // reset
488 
489         // Push with different activity
490         Mockito.reset(mMockUsageStatsManagerInternal);
491         s7.setActivity(makeComponent(ShortcutActivity2.class));
492         mManager.pushDynamicShortcut(s7);
493         assertEquals(makeComponent(ShortcutActivity2.class),
494                 getCallerShortcut("s7").getActivity());
495         assertEquals(0, getCallerShortcut("s7").getRank());
496         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
497                 eq(CALLING_PACKAGE_1), eq("s7"), eq(USER_0));
498 
499         // Push to update shortcut with different activity
500         Mockito.reset(mMockUsageStatsManagerInternal);
501         final ShortcutInfo s1_2 = makeShortcut("s1");
502         s1_2.setActivity(makeComponent(ShortcutActivity2.class));
503         s1_2.setRank(1);
504         mManager.pushDynamicShortcut(s1_2);
505         assertEquals(0, getCallerShortcut("s7").getRank());
506         assertEquals(1, getCallerShortcut("s1").getRank());
507         assertEquals(0, getCallerShortcut("s6").getRank());
508         assertEquals(1, getCallerShortcut("s5").getRank());
509         assertEquals(2, getCallerShortcut("s3").getRank());
510         assertEquals(3, getCallerShortcut("s2").getRank());
511         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
512                 eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_0));
513 
514         mInjectedCurrentTimeMillis += INTERVAL; // reset
515 
516         // Test push when dropped shortcut is cached
517         Mockito.reset(mMockUsageStatsManagerInternal);
518         s8.setLongLived();
519         s8.setRank(100);
520         mManager.pushDynamicShortcut(s8);
521         assertEquals(4, getCallerShortcut("s8").getRank());
522         runWithCaller(LAUNCHER_1, USER_0, () -> {
523             mInjectCheckAccessShortcutsPermission = true;
524             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s8"), HANDLE_USER_0,
525                     CACHE_OWNER_0);
526             verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
527                     eq(CALLING_PACKAGE_1), eq("s8"), eq(USER_0));
528         });
529 
530         Mockito.reset(mMockUsageStatsManagerInternal);
531         mManager.pushDynamicShortcut(s9);
532         assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
533                 "s1", "s2", "s3", "s5", "s6", "s7", "s9");
534         // Verify s13 stayed as cached
535         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
536                 "s8");
537         verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
538                 eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_0));
539     }
540 
testUnlimitedCalls()541     public void testUnlimitedCalls() {
542         setCaller(CALLING_PACKAGE_1, USER_0);
543 
544         final ShortcutInfo si1 = makeShortcut("shortcut1");
545 
546         assertEquals(3, mManager.getRemainingCallCount());
547 
548         assertTrue(mManager.setDynamicShortcuts(list(si1)));
549         assertEquals(2, mManager.getRemainingCallCount());
550 
551         assertTrue(mManager.addDynamicShortcuts(list(si1)));
552         assertEquals(1, mManager.getRemainingCallCount());
553 
554         assertTrue(mManager.updateShortcuts(list(si1)));
555         assertEquals(0, mManager.getRemainingCallCount());
556 
557         // Unlimited now.
558         mInjectHasUnlimitedShortcutsApiCallsPermission = true;
559 
560         assertEquals(3, mManager.getRemainingCallCount());
561 
562         assertTrue(mManager.setDynamicShortcuts(list(si1)));
563         assertEquals(3, mManager.getRemainingCallCount());
564 
565         assertTrue(mManager.addDynamicShortcuts(list(si1)));
566         assertEquals(3, mManager.getRemainingCallCount());
567 
568         assertTrue(mManager.updateShortcuts(list(si1)));
569         assertEquals(3, mManager.getRemainingCallCount());
570     }
571 
testPublishWithNoActivity()572     public void testPublishWithNoActivity() {
573         // If activity is not explicitly set, use the default one.
574 
575         mRunningUsers.put(USER_10, true);
576 
577         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
578             // s1 and s3 has no activities.
579             final ShortcutInfo si1 = new ShortcutInfo.Builder(mClientContext, "si1")
580                     .setShortLabel("label1")
581                     .setIntent(new Intent("action1"))
582                     .build();
583             final ShortcutInfo si2 = new ShortcutInfo.Builder(mClientContext, "si2")
584                     .setShortLabel("label2")
585                     .setActivity(new ComponentName(getCallingPackage(), "abc"))
586                     .setIntent(new Intent("action2"))
587                     .build();
588             final ShortcutInfo si3 = new ShortcutInfo.Builder(mClientContext, "si3")
589                     .setShortLabel("label3")
590                     .setIntent(new Intent("action3"))
591                     .build();
592 
593             // Set test 1
594             assertTrue(mManager.setDynamicShortcuts(list(si1)));
595 
596             assertWith(getCallerShortcuts())
597                     .haveIds("si1")
598                     .forShortcutWithId("si1", si -> {
599                         assertEquals(new ComponentName(getCallingPackage(),
600                                 MAIN_ACTIVITY_CLASS), si.getActivity());
601                     });
602 
603             // Set test 2
604             assertTrue(mManager.setDynamicShortcuts(list(si2, si1)));
605 
606             assertWith(getCallerShortcuts())
607                     .haveIds("si1", "si2")
608                     .forShortcutWithId("si1", si -> {
609                         assertEquals(new ComponentName(getCallingPackage(),
610                                 MAIN_ACTIVITY_CLASS), si.getActivity());
611                     })
612                     .forShortcutWithId("si2", si -> {
613                         assertEquals(new ComponentName(getCallingPackage(),
614                                 "abc"), si.getActivity());
615                     });
616 
617 
618             // Set test 3
619             assertTrue(mManager.setDynamicShortcuts(list(si3, si1)));
620 
621             assertWith(getCallerShortcuts())
622                     .haveIds("si1", "si3")
623                     .forShortcutWithId("si1", si -> {
624                         assertEquals(new ComponentName(getCallingPackage(),
625                                 MAIN_ACTIVITY_CLASS), si.getActivity());
626                     })
627                     .forShortcutWithId("si3", si -> {
628                         assertEquals(new ComponentName(getCallingPackage(),
629                                 MAIN_ACTIVITY_CLASS), si.getActivity());
630                     });
631 
632             mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
633 
634             // Add test 1
635             mManager.removeAllDynamicShortcuts();
636             assertTrue(mManager.addDynamicShortcuts(list(si1)));
637 
638             assertWith(getCallerShortcuts())
639                     .haveIds("si1")
640                     .forShortcutWithId("si1", si -> {
641                         assertEquals(new ComponentName(getCallingPackage(),
642                                 MAIN_ACTIVITY_CLASS), si.getActivity());
643                     });
644 
645             // Add test 2
646             mManager.removeAllDynamicShortcuts();
647             assertTrue(mManager.addDynamicShortcuts(list(si2, si1)));
648 
649             assertWith(getCallerShortcuts())
650                     .haveIds("si1", "si2")
651                     .forShortcutWithId("si1", si -> {
652                         assertEquals(new ComponentName(getCallingPackage(),
653                                 MAIN_ACTIVITY_CLASS), si.getActivity());
654                     })
655                     .forShortcutWithId("si2", si -> {
656                         assertEquals(new ComponentName(getCallingPackage(),
657                                 "abc"), si.getActivity());
658                     });
659 
660 
661             // Add test 3
662             mManager.removeAllDynamicShortcuts();
663             assertTrue(mManager.addDynamicShortcuts(list(si3, si1)));
664 
665             assertWith(getCallerShortcuts())
666                     .haveIds("si1", "si3")
667                     .forShortcutWithId("si1", si -> {
668                         assertEquals(new ComponentName(getCallingPackage(),
669                                 MAIN_ACTIVITY_CLASS), si.getActivity());
670                     })
671                     .forShortcutWithId("si3", si -> {
672                         assertEquals(new ComponentName(getCallingPackage(),
673                                 MAIN_ACTIVITY_CLASS), si.getActivity());
674                     });
675         });
676     }
677 
testPublishWithNoActivity_noMainActivityInPackage()678     public void testPublishWithNoActivity_noMainActivityInPackage() {
679         mRunningUsers.put(USER_10, true);
680 
681         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
682             final ShortcutInfo si1 = new ShortcutInfo.Builder(mClientContext, "si1")
683                     .setShortLabel("label1")
684                     .setIntent(new Intent("action1"))
685                     .build();
686 
687             // Returning null means there's no main activity in this package.
688             mMainActivityFetcher = (packageName, userId) -> null;
689 
690             assertExpectException(
691                     RuntimeException.class, "Launcher activity not found for", () -> {
692                         assertTrue(mManager.setDynamicShortcuts(list(si1)));
693                     });
694         });
695     }
696 
testDeleteDynamicShortcuts()697     public void testDeleteDynamicShortcuts() {
698         final ShortcutInfo si1 = makeShortcut("shortcut1");
699         final ShortcutInfo si2 = makeShortcut("shortcut2");
700         final ShortcutInfo si3 = makeShortcut("shortcut3");
701         final ShortcutInfo si4 = makeShortcut("shortcut4");
702 
703         assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3, si4)));
704         assertShortcutIds(assertAllNotKeyFieldsOnly(
705                 mManager.getDynamicShortcuts()),
706                 "shortcut1", "shortcut2", "shortcut3", "shortcut4");
707 
708         assertEquals(2, mManager.getRemainingCallCount());
709 
710         mManager.removeDynamicShortcuts(list("shortcut1"));
711         assertShortcutIds(assertAllNotKeyFieldsOnly(
712                 mManager.getDynamicShortcuts()),
713                 "shortcut2", "shortcut3", "shortcut4");
714 
715         mManager.removeDynamicShortcuts(list("shortcut1"));
716         assertShortcutIds(assertAllNotKeyFieldsOnly(
717                 mManager.getDynamicShortcuts()),
718                 "shortcut2", "shortcut3", "shortcut4");
719 
720         mManager.removeDynamicShortcuts(list("shortcutXXX"));
721         assertShortcutIds(assertAllNotKeyFieldsOnly(
722                 mManager.getDynamicShortcuts()),
723                 "shortcut2", "shortcut3", "shortcut4");
724 
725         mManager.removeDynamicShortcuts(list("shortcut2", "shortcut4"));
726         assertShortcutIds(assertAllNotKeyFieldsOnly(
727                 mManager.getDynamicShortcuts()),
728                 "shortcut3");
729 
730         mManager.removeDynamicShortcuts(list("shortcut3"));
731         assertShortcutIds(assertAllNotKeyFieldsOnly(
732                 mManager.getDynamicShortcuts()));
733 
734         // Still 2 calls left.
735         assertEquals(2, mManager.getRemainingCallCount());
736     }
737 
testDeleteAllDynamicShortcuts()738     public void testDeleteAllDynamicShortcuts() {
739         final ShortcutInfo si1 = makeShortcut("shortcut1");
740         final ShortcutInfo si2 = makeShortcut("shortcut2");
741         final ShortcutInfo si3 = makeShortcut("shortcut3");
742 
743         assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
744         assertShortcutIds(assertAllNotKeyFieldsOnly(
745                 mManager.getDynamicShortcuts()),
746                 "shortcut1", "shortcut2", "shortcut3");
747 
748         assertEquals(2, mManager.getRemainingCallCount());
749 
750         mManager.removeAllDynamicShortcuts();
751         assertEquals(0, mManager.getDynamicShortcuts().size());
752         assertEquals(2, mManager.getRemainingCallCount());
753 
754         // Note delete shouldn't affect throttling, so...
755         assertEquals(0, mManager.getDynamicShortcuts().size());
756         assertEquals(0, mManager.getDynamicShortcuts().size());
757         assertEquals(0, mManager.getDynamicShortcuts().size());
758 
759         // This should still work.
760         assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
761         assertEquals(3, mManager.getDynamicShortcuts().size());
762 
763         // Still 1 call left
764         assertEquals(1, mManager.getRemainingCallCount());
765     }
766 
testIcons()767     public void testIcons() throws IOException {
768         final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
769         final Icon res64x64 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
770         final Icon res512x512 = Icon.createWithResource(getTestContext(), R.drawable.black_512x512);
771 
772         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
773                 getTestContext().getResources(), R.drawable.black_32x32));
774         final Icon bmp64x64_maskable = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
775                 getTestContext().getResources(), R.drawable.black_64x64));
776         final Icon bmp512x512 = Icon.createWithBitmap(BitmapFactory.decodeResource(
777                 getTestContext().getResources(), R.drawable.black_512x512));
778 
779         // The corresponding files will be deleted in tearDown()
780         final Icon uri32x32 = Icon.createWithContentUri(
781                 getFileUriFromResource("file32x32.jpg", R.drawable.black_32x32));
782         final Icon uri64x64_maskable = Icon.createWithAdaptiveBitmapContentUri(
783                 getFileUriFromResource("file64x64.jpg", R.drawable.black_64x64));
784         final Icon uri512x512 = Icon.createWithContentUri(
785                 getFileUriFromResource("file512x512.jpg", R.drawable.black_512x512));
786 
787         doReturn(mUriPermissionOwner.getExternalToken())
788                 .when(mMockUriGrantsManagerInternal).newUriPermissionOwner(anyString());
789 
790         // Set from package 1
791         setCaller(CALLING_PACKAGE_1);
792         assertTrue(mManager.setDynamicShortcuts(list(
793                 makeShortcutWithIcon("res32x32", res32x32),
794                 makeShortcutWithIcon("res64x64", res64x64),
795                 makeShortcutWithIcon("bmp32x32", bmp32x32),
796                 makeShortcutWithIcon("bmp64x64", bmp64x64_maskable),
797                 makeShortcutWithIcon("bmp512x512", bmp512x512),
798                 makeShortcutWithIcon("uri32x32", uri32x32),
799                 makeShortcutWithIcon("uri64x64", uri64x64_maskable),
800                 makeShortcutWithIcon("uri512x512", uri512x512),
801                 makeShortcut("none")
802         )));
803 
804         // getDynamicShortcuts() shouldn't return icons, thus assertAllNotHaveIcon().
805         assertShortcutIds(assertAllNotHaveIcon(mManager.getDynamicShortcuts()),
806                 "res32x32",
807                 "res64x64",
808                 "bmp32x32",
809                 "bmp64x64",
810                 "bmp512x512",
811                 "uri32x32",
812                 "uri64x64",
813                 "uri512x512",
814                 "none");
815 
816         // Call from another caller with the same ID, just to make sure storage is per-package.
817         setCaller(CALLING_PACKAGE_2);
818         assertTrue(mManager.setDynamicShortcuts(list(
819                 makeShortcutWithIcon("res32x32", res512x512),
820                 makeShortcutWithIcon("res64x64", res512x512),
821                 makeShortcutWithIcon("uri32x32", uri512x512),
822                 makeShortcutWithIcon("uri64x64", uri512x512),
823                 makeShortcutWithIcon("none", res512x512)
824         )));
825         assertShortcutIds(assertAllNotHaveIcon(mManager.getDynamicShortcuts()),
826                 "res32x32",
827                 "res64x64",
828                 "uri32x32",
829                 "uri64x64",
830                 "none");
831 
832         // Different profile.  Note the names and the contents don't match.
833         setCaller(CALLING_PACKAGE_1, USER_P0);
834         assertTrue(mManager.setDynamicShortcuts(list(
835                 makeShortcutWithIcon("res32x32", res512x512),
836                 makeShortcutWithIcon("bmp32x32", bmp512x512)
837         )));
838         assertShortcutIds(assertAllNotHaveIcon(mManager.getDynamicShortcuts()),
839                 "res32x32",
840                 "bmp32x32");
841 
842         // Re-initialize and load from the files.
843         mService.saveDirtyInfo();
844         initService();
845 
846         // Load from launcher.
847         Bitmap bmp;
848 
849         setCaller(LAUNCHER_1);
850         // Check hasIconResource()/hasIconFile().
851         assertShortcutIds(assertAllHaveIconResId(
852                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_0))),
853                 "res32x32");
854 
855         assertShortcutIds(assertAllHaveIconResId(
856                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res64x64", USER_0))),
857                 "res64x64");
858 
859         assertShortcutIds(assertAllHaveIconFile(
860                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_0))),
861                 "bmp32x32");
862 
863         assertShortcutIds(assertAllHaveIconFile(
864                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_0))),
865                 "bmp64x64");
866 
867         assertShortcutIds(assertAllHaveIconFile(
868                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0))),
869                 "bmp512x512");
870 
871         assertShortcutIds(assertAllHaveIconUri(
872                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_0))),
873                 "uri32x32");
874 
875         assertShortcutIds(assertAllHaveIconUri(
876                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_0))),
877                 "uri64x64");
878 
879         assertShortcutIds(assertAllHaveIconUri(
880                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_0))),
881                 "uri512x512");
882 
883         assertShortcutIds(assertAllHaveIconResId(
884                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_P0))),
885                 "res32x32");
886         assertShortcutIds(assertAllHaveIconFile(
887                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_P0))),
888                 "bmp32x32");
889 
890         // Check
891         assertEquals(
892                 R.drawable.black_32x32,
893                 mLauncherApps.getShortcutIconResId(
894                         getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_0)));
895 
896         assertEquals(
897                 R.drawable.black_64x64,
898                 mLauncherApps.getShortcutIconResId(
899                         getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res64x64", USER_0)));
900 
901         assertEquals(
902                 0, // because it's not a resource
903                 mLauncherApps.getShortcutIconResId(
904                         getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_0)));
905         assertEquals(
906                 0, // because it's not a resource
907                 mLauncherApps.getShortcutIconResId(
908                         getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_0)));
909         assertEquals(
910                 0, // because it's not a resource
911                 mLauncherApps.getShortcutIconResId(
912                         getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0)));
913 
914         bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd(
915                 getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_0)));
916         assertBitmapSize(32, 32, bmp);
917 
918         bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd(
919                 getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_0)));
920         assertBitmapSize(64, 64, bmp);
921 
922         bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd(
923                 getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0)));
924         assertBitmapSize(128, 128, bmp);
925 
926         assertEquals(
927                 R.drawable.black_512x512,
928                 mLauncherApps.getShortcutIconResId(
929                         getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_P0)));
930         // Should be 512x512, so shrunk.
931         bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd(
932                 getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_P0)));
933         assertBitmapSize(128, 128, bmp);
934 
935         // Also check the overload APIs too.
936         assertEquals(
937                 R.drawable.black_32x32,
938                 mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res32x32", HANDLE_USER_0));
939         assertEquals(
940                 R.drawable.black_64x64,
941                 mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res64x64", HANDLE_USER_0));
942         assertEquals(
943                 R.drawable.black_512x512,
944                 mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res32x32", HANDLE_USER_P0));
945         bmp = pfdToBitmap(
946                 mLauncherApps.getShortcutIconFd(CALLING_PACKAGE_1, "bmp32x32", HANDLE_USER_P0));
947         assertBitmapSize(128, 128, bmp);
948 /*
949         bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
950                 getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_0)));
951         assertBitmapSize(32, 32, bmp);
952 
953         bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
954                 getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_0)));
955         assertBitmapSize(64, 64, bmp);
956 
957         bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
958                 getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_0)));
959         assertBitmapSize(512, 512, bmp);
960 */
961 
962         Drawable dr_bmp = mLauncherApps.getShortcutIconDrawable(
963                 makeShortcutWithIcon("bmp64x64", bmp64x64_maskable), 0);
964         assertTrue(dr_bmp instanceof AdaptiveIconDrawable);
965         float viewportPercentage = 1 / (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction());
966         assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
967                 dr_bmp.getIntrinsicWidth());
968         assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
969                 dr_bmp.getIntrinsicHeight());
970 /*
971         Drawable dr_uri = mLauncherApps.getShortcutIconDrawable(
972                 makeShortcutWithIcon("uri64x64", uri64x64_maskable), 0);
973         assertTrue(dr_uri instanceof AdaptiveIconDrawable);
974         assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
975                 dr_uri.getIntrinsicWidth());
976         assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
977                 dr_uri.getIntrinsicHeight());
978 */
979     }
980 
testCleanupDanglingBitmaps()981     public void testCleanupDanglingBitmaps() throws Exception {
982         assertBitmapDirectories(USER_0, EMPTY_STRINGS);
983         assertBitmapDirectories(USER_10, EMPTY_STRINGS);
984 
985         // Make some shortcuts with bitmap icons.
986         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
987                 getTestContext().getResources(), R.drawable.black_32x32));
988 
989         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
990             mManager.setDynamicShortcuts(list(
991                     makeShortcutWithIcon("s1", bmp32x32),
992                     makeShortcutWithIcon("s2", bmp32x32),
993                     makeShortcutWithIcon("s3", bmp32x32)
994             ));
995         });
996 
997         // Increment the time (which actually we don't have to), which is used for filenames.
998         mInjectedCurrentTimeMillis++;
999 
1000         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1001             mManager.setDynamicShortcuts(list(
1002                     makeShortcutWithIcon("s4", bmp32x32),
1003                     makeShortcutWithIcon("s5", bmp32x32),
1004                     makeShortcutWithIcon("s6", bmp32x32)
1005             ));
1006         });
1007 
1008         // Increment the time, which is used for filenames.
1009         mInjectedCurrentTimeMillis++;
1010 
1011         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1012             mManager.setDynamicShortcuts(list(
1013             ));
1014         });
1015 
1016         // For USER-10, let's try without updating the times.
1017         mRunningUsers.put(USER_10, true);
1018 
1019         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1020             mManager.setDynamicShortcuts(list(
1021                     makeShortcutWithIcon("10s1", bmp32x32),
1022                     makeShortcutWithIcon("10s2", bmp32x32),
1023                     makeShortcutWithIcon("10s3", bmp32x32)
1024             ));
1025         });
1026         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
1027             mManager.setDynamicShortcuts(list(
1028                     makeShortcutWithIcon("10s4", bmp32x32),
1029                     makeShortcutWithIcon("10s5", bmp32x32),
1030                     makeShortcutWithIcon("10s6", bmp32x32)
1031             ));
1032         });
1033         runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
1034             mManager.setDynamicShortcuts(list(
1035             ));
1036         });
1037 
1038         dumpsysOnLogcat();
1039 
1040         mService.waitForBitmapSavesForTest();
1041         // Check files and directories.
1042         // Package 3 has no bitmaps, so we don't create a directory.
1043         assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
1044         assertBitmapDirectories(USER_10, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
1045 
1046         assertBitmapFiles(USER_0, CALLING_PACKAGE_1,
1047                 getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s1"),
1048                 getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s2"),
1049                 getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s3")
1050         );
1051         assertBitmapFiles(USER_0, CALLING_PACKAGE_2,
1052                 getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s4"),
1053                 getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s5"),
1054                 getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s6")
1055         );
1056         assertBitmapFiles(USER_0, CALLING_PACKAGE_3,
1057                 EMPTY_STRINGS
1058         );
1059         assertBitmapFiles(USER_10, CALLING_PACKAGE_1,
1060                 getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s1"),
1061                 getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s2"),
1062                 getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s3")
1063         );
1064         assertBitmapFiles(USER_10, CALLING_PACKAGE_2,
1065                 getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s4"),
1066                 getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s5"),
1067                 getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s6")
1068         );
1069         assertBitmapFiles(USER_10, CALLING_PACKAGE_3,
1070                 EMPTY_STRINGS
1071         );
1072 
1073         // Then create random directories and files.
1074         makeFile(mService.getUserBitmapFilePath(USER_0), "a.b.c").mkdir();
1075         makeFile(mService.getUserBitmapFilePath(USER_0), "d.e.f").mkdir();
1076         makeFile(mService.getUserBitmapFilePath(USER_0), "d.e.f", "123").createNewFile();
1077         makeFile(mService.getUserBitmapFilePath(USER_0), "d.e.f", "456").createNewFile();
1078 
1079         makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_3).mkdir();
1080 
1081         makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "1").createNewFile();
1082         makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "2").createNewFile();
1083         makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "3").createNewFile();
1084         makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "4").createNewFile();
1085 
1086         makeFile(mService.getUserBitmapFilePath(USER_10), "10a.b.c").mkdir();
1087         makeFile(mService.getUserBitmapFilePath(USER_10), "10d.e.f").mkdir();
1088         makeFile(mService.getUserBitmapFilePath(USER_10), "10d.e.f", "123").createNewFile();
1089         makeFile(mService.getUserBitmapFilePath(USER_10), "10d.e.f", "456").createNewFile();
1090 
1091         makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "1").createNewFile();
1092         makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "2").createNewFile();
1093         makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "3").createNewFile();
1094         makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "4").createNewFile();
1095 
1096         mService.waitForBitmapSavesForTest();
1097         assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
1098                 "a.b.c", "d.e.f");
1099 
1100         // Save and load.  When a user is loaded, we do the cleanup.
1101         mService.saveDirtyInfo();
1102         initService();
1103 
1104         mService.handleUnlockUser(USER_0);
1105         mService.handleUnlockUser(USER_10);
1106         mService.handleUnlockUser(20); // Make sure the logic will still work for nonexistent user.
1107 
1108         // The below check is the same as above, except this time USER_0 use the CALLING_PACKAGE_3
1109         // directory.
1110 
1111         mService.waitForBitmapSavesForTest();
1112         assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3);
1113         assertBitmapDirectories(USER_10, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
1114 
1115         assertBitmapFiles(USER_0, CALLING_PACKAGE_1,
1116                 getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s1"),
1117                 getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s2"),
1118                 getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s3")
1119         );
1120         assertBitmapFiles(USER_0, CALLING_PACKAGE_2,
1121                 getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s4"),
1122                 getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s5"),
1123                 getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s6")
1124         );
1125         assertBitmapFiles(USER_0, CALLING_PACKAGE_3,
1126                 EMPTY_STRINGS
1127         );
1128         assertBitmapFiles(USER_10, CALLING_PACKAGE_1,
1129                 getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s1"),
1130                 getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s2"),
1131                 getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s3")
1132         );
1133         assertBitmapFiles(USER_10, CALLING_PACKAGE_2,
1134                 getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s4"),
1135                 getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s5"),
1136                 getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s6")
1137         );
1138         assertBitmapFiles(USER_10, CALLING_PACKAGE_3,
1139                 EMPTY_STRINGS
1140         );
1141     }
1142 
checkShrinkBitmap(int expectedWidth, int expectedHeight, int resId, int maxSize)1143     protected void checkShrinkBitmap(int expectedWidth, int expectedHeight, int resId, int maxSize) {
1144         assertBitmapSize(expectedWidth, expectedHeight,
1145                 ShortcutService.shrinkBitmap(BitmapFactory.decodeResource(
1146                         getTestContext().getResources(), resId),
1147                         maxSize));
1148     }
1149 
testShrinkBitmap()1150     public void testShrinkBitmap() {
1151         checkShrinkBitmap(32, 32, R.drawable.black_512x512, 32);
1152         checkShrinkBitmap(511, 511, R.drawable.black_512x512, 511);
1153         checkShrinkBitmap(512, 512, R.drawable.black_512x512, 512);
1154 
1155         checkShrinkBitmap(1024, 4096, R.drawable.black_1024x4096, 4096);
1156         checkShrinkBitmap(1024, 4096, R.drawable.black_1024x4096, 4100);
1157         checkShrinkBitmap(512, 2048, R.drawable.black_1024x4096, 2048);
1158 
1159         checkShrinkBitmap(4096, 1024, R.drawable.black_4096x1024, 4096);
1160         checkShrinkBitmap(4096, 1024, R.drawable.black_4096x1024, 4100);
1161         checkShrinkBitmap(2048, 512, R.drawable.black_4096x1024, 2048);
1162     }
1163 
openIconFileForWriteAndGetPath(int userId, String packageName)1164     protected File openIconFileForWriteAndGetPath(int userId, String packageName)
1165             throws IOException {
1166         // Shortcut IDs aren't used in the path, so just pass the same ID.
1167         final FileOutputStreamWithPath out =
1168                 mService.openIconFileForWrite(userId, makePackageShortcut(packageName, "id"));
1169         out.close();
1170         return out.getFile();
1171     }
1172 
testOpenIconFileForWrite()1173     public void testOpenIconFileForWrite() throws IOException {
1174         mInjectedCurrentTimeMillis = 1000;
1175 
1176         final File p10_1_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
1177         final File p10_1_2 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
1178 
1179         final File p10_2_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_2);
1180         final File p10_2_2 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_2);
1181 
1182         final File p11_1_1 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1);
1183         final File p11_1_2 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1);
1184 
1185         mInjectedCurrentTimeMillis++;
1186 
1187         final File p10_1_3 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
1188         final File p10_1_4 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
1189         final File p10_1_5 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
1190 
1191         final File p10_2_3 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_2);
1192         final File p11_1_3 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1);
1193 
1194         // Make sure their paths are all unique
1195         assertAllUnique(list(
1196                 p10_1_1,
1197                 p10_1_2,
1198                 p10_1_3,
1199                 p10_1_4,
1200                 p10_1_5,
1201 
1202                 p10_2_1,
1203                 p10_2_2,
1204                 p10_2_3,
1205 
1206                 p11_1_1,
1207                 p11_1_2,
1208                 p11_1_3
1209         ));
1210 
1211         // Check each set has the same parent.
1212         assertEquals(p10_1_1.getParent(), p10_1_2.getParent());
1213         assertEquals(p10_1_1.getParent(), p10_1_3.getParent());
1214         assertEquals(p10_1_1.getParent(), p10_1_4.getParent());
1215         assertEquals(p10_1_1.getParent(), p10_1_5.getParent());
1216 
1217         assertEquals(p10_2_1.getParent(), p10_2_2.getParent());
1218         assertEquals(p10_2_1.getParent(), p10_2_3.getParent());
1219 
1220         assertEquals(p11_1_1.getParent(), p11_1_2.getParent());
1221         assertEquals(p11_1_1.getParent(), p11_1_3.getParent());
1222 
1223         // Check the parents are still unique.
1224         assertAllUnique(list(
1225                 p10_1_1.getParent(),
1226                 p10_2_1.getParent(),
1227                 p11_1_1.getParent()
1228         ));
1229 
1230         // All files created at the same time for the same package/user, expcet for the first ones,
1231         // will have "_" in the path.
1232         assertFalse(p10_1_1.getName().contains("_"));
1233         assertTrue(p10_1_2.getName().contains("_"));
1234         assertFalse(p10_1_3.getName().contains("_"));
1235         assertTrue(p10_1_4.getName().contains("_"));
1236         assertTrue(p10_1_5.getName().contains("_"));
1237 
1238         assertFalse(p10_2_1.getName().contains("_"));
1239         assertTrue(p10_2_2.getName().contains("_"));
1240         assertFalse(p10_2_3.getName().contains("_"));
1241 
1242         assertFalse(p11_1_1.getName().contains("_"));
1243         assertTrue(p11_1_2.getName().contains("_"));
1244         assertFalse(p11_1_3.getName().contains("_"));
1245     }
1246 
testUpdateShortcuts()1247     public void testUpdateShortcuts() {
1248         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
1249             assertTrue(mManager.setDynamicShortcuts(list(
1250                     makeShortcut("s1"),
1251                     makeShortcut("s2"),
1252                     makeShortcut("s3"),
1253                     makeShortcut("s4"),
1254                     makeShortcut("s5")
1255             )));
1256         });
1257         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
1258             assertTrue(mManager.setDynamicShortcuts(list(
1259                     makeShortcut("s1"),
1260                     makeShortcut("s2"),
1261                     makeShortcut("s3"),
1262                     makeShortcut("s4"),
1263                     makeShortcut("s5")
1264             )));
1265         });
1266         runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> {
1267             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"),
1268                     getCallingUser());
1269             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s4", "s5"),
1270                     getCallingUser());
1271         });
1272         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
1273             mManager.removeDynamicShortcuts(list("s1"));
1274             mManager.removeDynamicShortcuts(list("s2"));
1275         });
1276         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
1277             mManager.removeDynamicShortcuts(list("s1"));
1278             mManager.removeDynamicShortcuts(list("s3"));
1279             mManager.removeDynamicShortcuts(list("s5"));
1280         });
1281         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
1282             assertShortcutIds(assertAllDynamic(
1283                     mManager.getDynamicShortcuts()),
1284                     "s3", "s4", "s5");
1285             assertShortcutIds(assertAllPinned(
1286                     mManager.getPinnedShortcuts()),
1287                     "s2", "s3");
1288         });
1289         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
1290             assertShortcutIds(assertAllDynamic(
1291                     mManager.getDynamicShortcuts()),
1292                     "s2", "s4");
1293             assertShortcutIds(assertAllPinned(
1294                     mManager.getPinnedShortcuts()),
1295                     "s4", "s5");
1296         });
1297 
1298         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
1299             ShortcutInfo s2 = makeShortcutBuilder()
1300                     .setId("s2")
1301                     .setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
1302                     .build();
1303 
1304             ShortcutInfo s4 = makeShortcutBuilder()
1305                     .setId("s4")
1306                     .setTitle("new title")
1307                     .build();
1308 
1309             mManager.updateShortcuts(list(s2, s4));
1310         });
1311         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
1312             ShortcutInfo s2 = makeShortcutBuilder()
1313                     .setId("s2")
1314                     .setIntent(makeIntent(Intent.ACTION_ANSWER, ShortcutActivity.class,
1315                             "key1", "val1"))
1316                     .build();
1317 
1318             ShortcutInfo s4 = makeShortcutBuilder()
1319                     .setId("s4")
1320                     .setIntent(new Intent(Intent.ACTION_ALL_APPS))
1321                     .build();
1322 
1323             mManager.updateShortcuts(list(s2, s4));
1324         });
1325 
1326         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
1327             assertShortcutIds(assertAllDynamic(
1328                     mManager.getDynamicShortcuts()),
1329                     "s3", "s4", "s5");
1330             assertShortcutIds(assertAllPinned(
1331                     mManager.getPinnedShortcuts()),
1332                     "s2", "s3");
1333 
1334             ShortcutInfo s = getCallerShortcut("s2");
1335             assertTrue(s.hasIconResource());
1336             assertEquals(R.drawable.black_32x32, s.getIconResourceId());
1337             assertEquals("string/r" + R.drawable.black_32x32, s.getIconResName());
1338             assertEquals("Title-s2", s.getTitle());
1339 
1340             s = getCallerShortcut("s4");
1341             assertFalse(s.hasIconResource());
1342             assertEquals(0, s.getIconResourceId());
1343             assertEquals("new title", s.getTitle());
1344         });
1345         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
1346             assertShortcutIds(assertAllDynamic(
1347                     mManager.getDynamicShortcuts()),
1348                     "s2", "s4");
1349             assertShortcutIds(assertAllPinned(
1350                     mManager.getPinnedShortcuts()),
1351                     "s4", "s5");
1352 
1353             ShortcutInfo s = getCallerShortcut("s2");
1354             assertFalse(s.hasIconResource());
1355             assertEquals(0, s.getIconResourceId());
1356             assertEquals("Title-s2", s.getTitle());
1357             assertEquals(Intent.ACTION_ANSWER, s.getIntent().getAction());
1358             assertEquals(1, s.getIntent().getExtras().size());
1359 
1360             s = getCallerShortcut("s4");
1361             assertFalse(s.hasIconResource());
1362             assertEquals(0, s.getIconResourceId());
1363             assertEquals("Title-s4", s.getTitle());
1364             assertEquals(Intent.ACTION_ALL_APPS, s.getIntent().getAction());
1365             assertBundleEmpty(s.getIntent().getExtras());
1366         });
1367         // TODO Check with other fields too.
1368 
1369         // TODO Check bitmap removal too.
1370 
1371         mRunningUsers.put(USER_11, true);
1372 
1373         runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
1374             mManager.updateShortcuts(list());
1375         });
1376     }
1377 
testUpdateShortcuts_icons()1378     public void testUpdateShortcuts_icons() {
1379         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
1380             assertTrue(mManager.setDynamicShortcuts(list(
1381                     makeShortcut("s1")
1382             )));
1383 
1384             // Set uri icon
1385             assertTrue(mManager.updateShortcuts(list(
1386                     new ShortcutInfo.Builder(mClientContext, "s1")
1387                             .setIcon(Icon.createWithContentUri("test_uri"))
1388                             .build()
1389             )));
1390             mService.waitForBitmapSavesForTest();
1391             assertWith(getCallerShortcuts())
1392                     .forShortcutWithId("s1", si -> {
1393                         assertTrue(si.hasIconUri());
1394                         assertEquals("test_uri", si.getIconUri());
1395                     });
1396             // Set resource icon
1397             assertTrue(mManager.updateShortcuts(list(
1398                     new ShortcutInfo.Builder(mClientContext, "s1")
1399                             .setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
1400                             .build()
1401             )));
1402             mService.waitForBitmapSavesForTest();
1403             assertWith(getCallerShortcuts())
1404                     .forShortcutWithId("s1", si -> {
1405                         assertTrue(si.hasIconResource());
1406                         assertEquals(R.drawable.black_32x32, si.getIconResourceId());
1407                     });
1408             mService.waitForBitmapSavesForTest();
1409 
1410             mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
1411 
1412             // Set bitmap icon
1413             assertTrue(mManager.updateShortcuts(list(
1414                     new ShortcutInfo.Builder(mClientContext, "s1")
1415                             .setIcon(Icon.createWithBitmap(BitmapFactory.decodeResource(
1416                                     getTestContext().getResources(), R.drawable.black_64x64)))
1417                             .build()
1418             )));
1419             mService.waitForBitmapSavesForTest();
1420             assertWith(getCallerShortcuts())
1421                     .forShortcutWithId("s1", si -> {
1422                         assertTrue(si.hasIconFile());
1423                     });
1424 
1425             // Do it again, with the reverse order (bitmap -> resource -> uri)
1426             assertTrue(mManager.setDynamicShortcuts(list(
1427                     makeShortcut("s1")
1428             )));
1429 
1430             // Set bitmap icon
1431             assertTrue(mManager.updateShortcuts(list(
1432                     new ShortcutInfo.Builder(mClientContext, "s1")
1433                             .setIcon(Icon.createWithBitmap(BitmapFactory.decodeResource(
1434                                     getTestContext().getResources(), R.drawable.black_64x64)))
1435                             .build()
1436             )));
1437             mService.waitForBitmapSavesForTest();
1438             assertWith(getCallerShortcuts())
1439                     .forShortcutWithId("s1", si -> {
1440                         assertTrue(si.hasIconFile());
1441                     });
1442 
1443             mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
1444 
1445             // Set resource icon
1446             assertTrue(mManager.updateShortcuts(list(
1447                     new ShortcutInfo.Builder(mClientContext, "s1")
1448                             .setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
1449                             .build()
1450             )));
1451             mService.waitForBitmapSavesForTest();
1452             assertWith(getCallerShortcuts())
1453                     .forShortcutWithId("s1", si -> {
1454                         assertTrue(si.hasIconResource());
1455                         assertEquals(R.drawable.black_32x32, si.getIconResourceId());
1456                     });
1457             // Set uri icon
1458             assertTrue(mManager.updateShortcuts(list(
1459                     new ShortcutInfo.Builder(mClientContext, "s1")
1460                             .setIcon(Icon.createWithContentUri("test_uri"))
1461                             .build()
1462             )));
1463             mService.waitForBitmapSavesForTest();
1464             assertWith(getCallerShortcuts())
1465                     .forShortcutWithId("s1", si -> {
1466                         assertTrue(si.hasIconUri());
1467                         assertEquals("test_uri", si.getIconUri());
1468                     });
1469         });
1470     }
1471 
testShortcutManagerGetShortcuts_shortcutTypes()1472     public void testShortcutManagerGetShortcuts_shortcutTypes() {
1473 
1474         // Create 3 manifest and 3 dynamic shortcuts
1475         addManifestShortcutResource(
1476                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
1477                 R.xml.shortcut_3);
1478         updatePackageVersion(CALLING_PACKAGE_1, 1);
1479         mService.mPackageMonitor.onReceive(getTestContext(),
1480                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
1481 
1482         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1483             assertTrue(mManager.setDynamicShortcuts(list(
1484                     makeLongLivedShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
1485         });
1486 
1487         // Pin 2 and 3
1488         runWithCaller(LAUNCHER_1, USER_0, () -> {
1489             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "ms3", "s2", "s3"),
1490                     HANDLE_USER_0);
1491         });
1492 
1493         // Cache 1 and 2
1494         runWithCaller(LAUNCHER_1, USER_0, () -> {
1495             mInjectCheckAccessShortcutsPermission = true;
1496             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1"),
1497                     HANDLE_USER_0, CACHE_OWNER_0);
1498             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"),
1499                     HANDLE_USER_0, CACHE_OWNER_1);
1500         });
1501 
1502         setCaller(CALLING_PACKAGE_1);
1503 
1504         // Get manifest shortcuts
1505         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_MANIFEST),
1506                 "ms1", "ms2", "ms3");
1507 
1508         // Get dynamic shortcuts
1509         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC),
1510                 "s1", "s2", "s3");
1511 
1512         // Get pinned shortcuts
1513         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_PINNED),
1514                 "ms2", "ms3", "s2", "s3");
1515 
1516         // Get cached shortcuts
1517         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1518                 "s1", "s2");
1519 
1520         // Get manifest and dynamic shortcuts
1521         assertShortcutIds(mManager.getShortcuts(
1522                 ShortcutManager.FLAG_MATCH_MANIFEST | ShortcutManager.FLAG_MATCH_DYNAMIC),
1523                 "ms1", "ms2", "ms3", "s1", "s2", "s3");
1524 
1525         // Get manifest and pinned shortcuts
1526         assertShortcutIds(mManager.getShortcuts(
1527                 ShortcutManager.FLAG_MATCH_MANIFEST | ShortcutManager.FLAG_MATCH_PINNED),
1528                 "ms1", "ms2", "ms3", "s2", "s3");
1529 
1530         // Get manifest and cached shortcuts
1531         assertShortcutIds(mManager.getShortcuts(
1532                 ShortcutManager.FLAG_MATCH_MANIFEST | ShortcutManager.FLAG_MATCH_CACHED),
1533                 "ms1", "ms2", "ms3", "s1", "s2");
1534 
1535         // Get dynamic and pinned shortcuts
1536         assertShortcutIds(mManager.getShortcuts(
1537                 ShortcutManager.FLAG_MATCH_DYNAMIC | ShortcutManager.FLAG_MATCH_PINNED),
1538                 "ms2", "ms3", "s1", "s2", "s3");
1539 
1540         // Get dynamic and cached shortcuts
1541         assertShortcutIds(mManager.getShortcuts(
1542                 ShortcutManager.FLAG_MATCH_DYNAMIC | ShortcutManager.FLAG_MATCH_CACHED),
1543                 "s1", "s2", "s3");
1544 
1545         // Get pinned and cached shortcuts
1546         assertShortcutIds(mManager.getShortcuts(
1547                 ShortcutManager.FLAG_MATCH_PINNED | ShortcutManager.FLAG_MATCH_CACHED),
1548                 "ms2", "ms3", "s1", "s2", "s3");
1549 
1550         // Remove a dynamic cached shortcut
1551         mManager.removeDynamicShortcuts(list("s1"));
1552         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC), "s2", "s3");
1553         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s1", "s2");
1554 
1555         // Remove a dynamic cached and pinned shortcut
1556         mManager.removeDynamicShortcuts(list("s2"));
1557         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC), "s3");
1558         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_PINNED),
1559                 "ms2", "ms3", "s2", "s3");
1560         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s1", "s2");
1561     }
1562 
testCachedShortcuts()1563     public void testCachedShortcuts() {
1564         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1565             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
1566                     makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
1567                     makeLongLivedShortcut("s4"), makeLongLivedShortcut("s5"),
1568                     makeLongLivedShortcut("s6"))));
1569         });
1570 
1571         // Pin s2
1572         runWithCaller(LAUNCHER_1, USER_0, () -> {
1573             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"),
1574                     HANDLE_USER_0);
1575         });
1576 
1577         // Cache some, but non long lived shortcuts will be ignored.
1578         runWithCaller(LAUNCHER_1, USER_0, () -> {
1579             mInjectCheckAccessShortcutsPermission = true;
1580             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"),
1581                     HANDLE_USER_0, CACHE_OWNER_0);
1582             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4", "s5"),
1583                     HANDLE_USER_0, CACHE_OWNER_1);
1584             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s5", "s6"),
1585                     HANDLE_USER_0, CACHE_OWNER_2);
1586         });
1587 
1588         setCaller(CALLING_PACKAGE_1);
1589 
1590         // Get dynamic shortcuts
1591         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC),
1592                 "s1", "s2", "s3", "s4", "s5", "s6");
1593         // Get pinned shortcuts
1594         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_PINNED),
1595                 "s2");
1596         // Get cached shortcuts
1597         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1598                 "s2", "s4", "s5", "s6");
1599 
1600         // Remove a dynamic cached shortcut
1601         mManager.removeDynamicShortcuts(list("s4", "s5"));
1602         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC),
1603                 "s1", "s2", "s3", "s6");
1604         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1605                 "s2", "s4", "s5", "s6");
1606 
1607         runWithCaller(LAUNCHER_1, USER_0, () -> {
1608             mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4"),
1609                     HANDLE_USER_0, CACHE_OWNER_0);
1610         });
1611         // s2 still cached by owner1. s4 wasn't cached by owner0 so didn't get removed.
1612         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1613                 "s2", "s4", "s5", "s6");
1614 
1615         // uncache a non-dynamic shortcut. Should be removed.
1616         runWithCaller(LAUNCHER_1, USER_0, () -> {
1617             mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s4"),
1618                     HANDLE_USER_0, CACHE_OWNER_1);
1619         });
1620 
1621         // uncache s6 by its only owner. s5 still cached by owner1
1622         runWithCaller(LAUNCHER_1, USER_0, () -> {
1623             mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s5", "s6"),
1624                     HANDLE_USER_0, CACHE_OWNER_2);
1625         });
1626         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1627                 "s2", "s5");
1628 
1629         // Cache another shortcut
1630         runWithCaller(LAUNCHER_1, USER_0, () -> {
1631             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s3"),
1632                     HANDLE_USER_0, CACHE_OWNER_0);
1633         });
1634         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1635                 "s2", "s3", "s5");
1636 
1637         // Remove a dynamic cached pinned long lived shortcut
1638         mManager.removeLongLivedShortcuts(list("s2"));
1639         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC),
1640                 "s1", "s3", "s6");
1641         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1642                 "s3", "s5");
1643         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_PINNED),
1644                 "s2");
1645     }
1646 
testCachedShortcuts_accessShortcutsPermission()1647     public void testCachedShortcuts_accessShortcutsPermission() {
1648         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1649             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
1650                     makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
1651                     makeLongLivedShortcut("s4"))));
1652         });
1653 
1654         // s1 is not long lived and will be ignored.
1655         runWithCaller(LAUNCHER_1, USER_0, () -> {
1656             mInjectCheckAccessShortcutsPermission = false;
1657             assertExpectException(
1658                     SecurityException.class, "Caller can't access shortcut information", () -> {
1659                         mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"),
1660                                 HANDLE_USER_0, CACHE_OWNER_0);
1661                     });
1662             // Give ACCESS_SHORTCUTS permission to LAUNCHER_1
1663             mInjectCheckAccessShortcutsPermission = true;
1664             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"),
1665                     HANDLE_USER_0, CACHE_OWNER_0);
1666         });
1667 
1668         setCaller(CALLING_PACKAGE_1);
1669 
1670         // Get cached shortcuts
1671         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s2", "s3");
1672 
1673         runWithCaller(LAUNCHER_1, USER_0, () -> {
1674             mInjectCheckAccessShortcutsPermission = false;
1675             assertExpectException(
1676                     SecurityException.class, "Caller can't access shortcut information", () -> {
1677                         mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4"),
1678                                 HANDLE_USER_0, CACHE_OWNER_0);
1679                     });
1680             // Give ACCESS_SHORTCUTS permission to LAUNCHER_1
1681             mInjectCheckAccessShortcutsPermission = true;
1682             mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4"),
1683                     HANDLE_USER_0, CACHE_OWNER_0);
1684         });
1685 
1686         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s3");
1687     }
1688 
testCachedShortcuts_canPassShortcutLimit()1689     public void testCachedShortcuts_canPassShortcutLimit() {
1690         // Change the max number of shortcuts.
1691         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=4");
1692 
1693         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1694             assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
1695                     makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
1696                     makeLongLivedShortcut("s4"))));
1697         });
1698 
1699         // Cache All
1700         runWithCaller(LAUNCHER_1, USER_0, () -> {
1701             mInjectCheckAccessShortcutsPermission = true;
1702             mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
1703                     HANDLE_USER_0, CACHE_OWNER_0);
1704         });
1705 
1706         setCaller(CALLING_PACKAGE_1);
1707 
1708         // Get dynamic shortcuts
1709         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC),
1710                 "s1", "s2", "s3", "s4");
1711         // Get cached shortcuts
1712         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1713                 "s1", "s2", "s3", "s4");
1714 
1715         assertTrue(mManager.setDynamicShortcuts(makeShortcuts("sx1", "sx2", "sx3", "sx4")));
1716 
1717         // Get dynamic shortcuts
1718         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_DYNAMIC),
1719                 "sx1", "sx2", "sx3", "sx4");
1720         // Get cached shortcuts
1721         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
1722                 "s1", "s2", "s3", "s4");
1723     }
1724 
1725     // === Test for launcher side APIs ===
1726 
testGetShortcuts()1727     public void testGetShortcuts() {
1728 
1729         // Set up shortcuts.
1730 
1731         setCaller(CALLING_PACKAGE_1);
1732         final ShortcutInfo s1_1 = makeLongLivedShortcut("s1");
1733         final ShortcutInfo s1_2 = makeShortcutWithLocusId("s2", makeLocusId("l1"));
1734 
1735         assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
1736 
1737         // Because setDynamicShortcuts will update the timestamps when ranks are changing,
1738         // we explicitly set timestamps here.
1739         updateCallerShortcut("s1", si -> si.setTimestamp(5000));
1740         updateCallerShortcut("s2", si -> si.setTimestamp(1000));
1741 
1742         setCaller(CALLING_PACKAGE_2);
1743         final ShortcutInfo s2_2 = makeShortcut("s2");
1744         final ShortcutInfo s2_3 = makeShortcutWithActivity("s3",
1745                 makeComponent(ShortcutActivity2.class));
1746         final ShortcutInfo s2_4 = makeShortcutWithActivity("s4",
1747                 makeComponent(ShortcutActivity.class));
1748         assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
1749 
1750         updateCallerShortcut("s2", si -> si.setTimestamp(1500));
1751         updateCallerShortcut("s3", si -> si.setTimestamp(3000));
1752         updateCallerShortcut("s4", si -> si.setTimestamp(500));
1753 
1754         setCaller(CALLING_PACKAGE_3);
1755         final ShortcutInfo s3_2 = makeShortcutWithLocusId("s3", makeLocusId("l2"));
1756         s3_2.setLongLived();
1757 
1758         assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
1759 
1760         updateCallerShortcut("s3", si -> si.setTimestamp(START_TIME + 5000));
1761 
1762         setCaller(LAUNCHER_1);
1763 
1764         // Get dynamic
1765         assertAllDynamic(assertAllHaveTitle(assertAllNotHaveIntents(assertAllStringsResolved(
1766                 assertShortcutIds(
1767                         assertAllNotKeyFieldsOnly(
1768                                 mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
1769                         /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
1770                         "s1", "s2")))));
1771 
1772         // Get pinned
1773         assertShortcutIds(
1774                 mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
1775                         /* activity =*/ null,
1776                         ShortcutQuery.FLAG_GET_PINNED), getCallingUser())
1777                 /* none */);
1778 
1779         // Get both, with timestamp
1780         assertAllDynamic(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1781                 assertAllNotKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1782                         /* time =*/ 1000, CALLING_PACKAGE_2,
1783                         /* activity =*/ null,
1784                         ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC),
1785                         getCallingUser())),
1786                 "s2", "s3"))));
1787 
1788         // FLAG_GET_KEY_FIELDS_ONLY
1789         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1790                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1791                         /* time =*/ 1000, CALLING_PACKAGE_2,
1792                         /* activity =*/ null,
1793                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1794                         getCallingUser())),
1795                 "s2", "s3"))));
1796 
1797         // Filter by activity
1798         assertAllDynamic(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1799                 assertAllNotKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1800                         /* time =*/ 0, CALLING_PACKAGE_2,
1801                         new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
1802                         ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC),
1803                         getCallingUser())),
1804                 "s4"))));
1805 
1806         // With ID.
1807         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1808                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1809                         /* time =*/ 1000, CALLING_PACKAGE_2, list("s3"), /* locusIds =*/ null,
1810                         /* activity =*/ null,
1811                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1812                         getCallingUser())),
1813                 "s3"))));
1814         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1815                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1816                         /* time =*/ 1000, CALLING_PACKAGE_2, list("s3", "s2", "ss"),
1817                         /* locusIds =*/ null, /* activity =*/ null,
1818                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1819                         getCallingUser())),
1820                 "s2", "s3"))));
1821         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1822                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1823                         /* time =*/ 1000, CALLING_PACKAGE_2, list("s3x", "s2x"),
1824                         /* locusIds =*/ null, /* activity =*/ null,
1825                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1826                         getCallingUser()))
1827                 /* empty */))));
1828         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1829                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1830                         /* time =*/ 1000, CALLING_PACKAGE_2, list(), /* locusIds =*/ null,
1831                         /* activity =*/ null,
1832                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1833                         getCallingUser()))
1834                 /* empty */))));
1835 
1836         // With locus ID.
1837         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1838                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1839                         /* time =*/ 1000, CALLING_PACKAGE_3, /* shortcutIds =*/ null,
1840                         list(makeLocusId("l2")), /* activity =*/ null,
1841                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1842                         getCallingUser())),
1843                 "s3"))));
1844         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1845                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1846                         /* time =*/ 1000, CALLING_PACKAGE_1, /* shortcutIds =*/ null,
1847                         list(makeLocusId("l1"), makeLocusId("l2"), makeLocusId("l3")),
1848                         /* activity =*/ null,
1849                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1850                         getCallingUser())),
1851                 "s2"))));
1852         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1853                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1854                         /* time =*/ 1000, CALLING_PACKAGE_1, /* shortcutIds =*/ null,
1855                         list(makeLocusId("lx1"), makeLocusId("lx2")), /* activity =*/ null,
1856                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1857                         getCallingUser()))
1858                 /* empty */))));
1859         assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1860                 assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1861                         /* time =*/ 1000, CALLING_PACKAGE_3, /* shortcutIds =*/ null, list(),
1862                         /* activity =*/ null,
1863                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
1864                         getCallingUser()))
1865                 /* empty */))));
1866 
1867         // Pin some shortcuts.
1868         mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
1869                 list("s3", "s4"), getCallingUser());
1870 
1871         // Pinned ones only
1872         assertAllPinned(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
1873                 assertAllNotKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
1874                         /* time =*/ 1000, CALLING_PACKAGE_2,
1875                         /* activity =*/ null,
1876                         ShortcutQuery.FLAG_GET_PINNED),
1877                         getCallingUser())),
1878                 "s3"))));
1879 
1880         // All packages.
1881         assertShortcutIds(assertAllNotKeyFieldsOnly(
1882                 mLauncherApps.getShortcuts(buildQuery(
1883                         /* time =*/ 5000, /* package= */ null,
1884                         /* activity =*/ null,
1885                         ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED),
1886                         getCallingUser())),
1887                 "s1", "s3");
1888 
1889         assertExpectException(
1890                 IllegalArgumentException.class, "package name must also be set", () -> {
1891                     mLauncherApps.getShortcuts(buildQuery(
1892                     /* time =*/ 0, /* package= */ null, list("id"), /* locusIds =*/ null,
1893                     /* activity =*/ null, /* flags */ 0), getCallingUser());
1894                 });
1895 
1896         // TODO More tests: pinned but dynamic.
1897 
1898         setCaller(LAUNCHER_1);
1899 
1900         // Cache some shortcuts. Only long lived shortcuts can get cached.
1901         mInjectCheckAccessShortcutsPermission = true;
1902         mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1"), getCallingUser(),
1903                 CACHE_OWNER_0);
1904         mLauncherApps.cacheShortcuts(CALLING_PACKAGE_3, list("s3"), getCallingUser(),
1905                 CACHE_OWNER_0);
1906 
1907         // Cached ones only
1908         assertShortcutIds(assertAllNotKeyFieldsOnly(
1909                 mLauncherApps.getShortcuts(buildQuery(
1910                         /* time =*/ 0, CALLING_PACKAGE_3,
1911                         /* activity =*/ null,
1912                         ShortcutQuery.FLAG_MATCH_CACHED),
1913                         getCallingUser())),
1914                 "s3");
1915 
1916         // All packages.
1917         assertShortcutIds(assertAllNotKeyFieldsOnly(
1918                 mLauncherApps.getShortcuts(buildQuery(
1919                         /* time =*/ 0, /* package= */ null,
1920                         /* activity =*/ null,
1921                         ShortcutQuery.FLAG_MATCH_CACHED),
1922                         getCallingUser())),
1923                 "s1", "s3");
1924 
1925         assertExpectException(
1926                 IllegalArgumentException.class, "package name must also be set", () -> {
1927                     mLauncherApps.getShortcuts(buildQuery(
1928                             /* time =*/ 0, /* package= */ null, list("id"), /* locusIds= */ null,
1929                             /* activity =*/ null, /* flags */ 0), getCallingUser());
1930                 });
1931 
1932         // Change Launcher. Cached shortcuts are the same for all launchers.
1933         setCaller(LAUNCHER_2);
1934         // All packages.
1935         assertShortcutIds(assertAllNotKeyFieldsOnly(
1936                 mLauncherApps.getShortcuts(buildQuery(
1937                         /* time =*/ 0, /* package= */ null,
1938                         /* activity =*/ null,
1939                         ShortcutQuery.FLAG_MATCH_CACHED),
1940                         getCallingUser())),
1941                 "s1", "s3");
1942     }
1943 
testGetShortcuts_shortcutKinds()1944     public void testGetShortcuts_shortcutKinds() throws Exception {
1945         // Create 3 manifest and 3 dynamic shortcuts
1946         addManifestShortcutResource(
1947                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
1948                 R.xml.shortcut_3);
1949         updatePackageVersion(CALLING_PACKAGE_1, 1);
1950         mService.mPackageMonitor.onReceive(getTestContext(),
1951                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
1952 
1953         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1954             assertTrue(mManager.setDynamicShortcuts(list(
1955                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
1956         });
1957 
1958         // Pin 2 and 3
1959         runWithCaller(LAUNCHER_1, USER_0, () -> {
1960             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "ms3", "s2", "s3"),
1961                     HANDLE_USER_0);
1962         });
1963 
1964         // Remove ms3 and s3
1965         addManifestShortcutResource(
1966                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
1967                 R.xml.shortcut_2);
1968         updatePackageVersion(CALLING_PACKAGE_1, 1);
1969         mService.mPackageMonitor.onReceive(getTestContext(),
1970                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
1971 
1972         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1973             assertTrue(mManager.setDynamicShortcuts(list(
1974                     makeShortcut("s1"), makeShortcut("s2"))));
1975         });
1976 
1977         // Check their status.
1978         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1979             assertWith(getCallerShortcuts())
1980                     .haveIds("ms1", "ms2", "ms3", "s1", "s2", "s3")
1981 
1982                     .selectByIds("ms1", "ms2")
1983                     .areAllManifest()
1984                     .areAllImmutable()
1985                     .areAllNotDynamic()
1986 
1987                     .revertToOriginalList()
1988                     .selectByIds("ms3")
1989                     .areAllNotManifest()
1990                     .areAllImmutable()
1991                     .areAllDisabled()
1992                     .areAllNotDynamic()
1993 
1994                     .revertToOriginalList()
1995                     .selectByIds("s1", "s2")
1996                     .areAllNotManifest()
1997                     .areAllMutable()
1998                     .areAllDynamic()
1999 
2000                     .revertToOriginalList()
2001                     .selectByIds("s3")
2002                     .areAllNotManifest()
2003                     .areAllMutable()
2004                     .areAllEnabled()
2005                     .areAllNotDynamic()
2006 
2007                     .revertToOriginalList()
2008                     .selectByIds("s1", "ms1")
2009                     .areAllNotPinned()
2010 
2011                     .revertToOriginalList()
2012                     .selectByIds("s2", "s3", "ms2", "ms3")
2013                     .areAllPinned()
2014             ;
2015         });
2016 
2017         // Finally, actual tests.
2018         runWithCaller(LAUNCHER_1, USER_0, () -> {
2019             assertWith(mLauncherApps.getShortcuts(
2020                     buildQueryWithFlags(ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0))
2021                     .haveIds("s1", "s2");
2022             assertWith(mLauncherApps.getShortcuts(
2023                     buildQueryWithFlags(ShortcutQuery.FLAG_GET_MANIFEST), HANDLE_USER_0))
2024                     .haveIds("ms1", "ms2");
2025             assertWith(mLauncherApps.getShortcuts(
2026                     buildQueryWithFlags(ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0))
2027                     .haveIds("s2", "s3", "ms2", "ms3");
2028 
2029             assertWith(mLauncherApps.getShortcuts(
2030                     buildQueryWithFlags(
2031                             ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED
2032                     ), HANDLE_USER_0))
2033                     .haveIds("s1", "s2", "s3", "ms2", "ms3");
2034 
2035             assertWith(mLauncherApps.getShortcuts(
2036                     buildQueryWithFlags(
2037                             ShortcutQuery.FLAG_GET_MANIFEST | ShortcutQuery.FLAG_GET_PINNED
2038                     ), HANDLE_USER_0))
2039                     .haveIds("ms1", "s2", "s3", "ms2", "ms3");
2040 
2041             assertWith(mLauncherApps.getShortcuts(
2042                     buildQueryWithFlags(
2043                             ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_MANIFEST
2044                     ), HANDLE_USER_0))
2045                     .haveIds("ms1", "ms2", "s1", "s2");
2046 
2047             assertWith(mLauncherApps.getShortcuts(
2048                     buildQueryWithFlags(
2049                             ShortcutQuery.FLAG_GET_ALL_KINDS
2050                     ), HANDLE_USER_0))
2051                     .haveIds("ms1", "ms2", "ms3", "s1", "s2", "s3");
2052         });
2053     }
2054 
testGetShortcuts_resolveStrings()2055     public void testGetShortcuts_resolveStrings() throws Exception {
2056         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2057             ShortcutInfo si = new ShortcutInfo.Builder(mClientContext)
2058                     .setId("id")
2059                     .setActivity(new ComponentName(mClientContext, "dummy"))
2060                     .setTitleResId(10)
2061                     .setTextResId(11)
2062                     .setDisabledMessageResId(12)
2063                     .setIntent(makeIntent("action", ShortcutActivity.class))
2064                     .build();
2065             mManager.setDynamicShortcuts(list(si));
2066         });
2067         runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
2068             ShortcutInfo si = new ShortcutInfo.Builder(mClientContext)
2069                     .setId("id")
2070                     .setActivity(new ComponentName(mClientContext, "dummy"))
2071                     .setTitleResId(10)
2072                     .setTextResId(11)
2073                     .setDisabledMessageResId(12)
2074                     .setIntent(makeIntent("action", ShortcutActivity.class))
2075                     .build();
2076             mManager.setDynamicShortcuts(list(si));
2077         });
2078 
2079         runWithCaller(LAUNCHER_1, USER_0, () -> {
2080             final ShortcutQuery q = new ShortcutQuery();
2081             q.setQueryFlags(ShortcutQuery.FLAG_GET_DYNAMIC);
2082 
2083             // USER 0
2084             List<ShortcutInfo> ret = assertShortcutIds(
2085                     assertAllStringsResolved(mLauncherApps.getShortcuts(q, HANDLE_USER_0)),
2086                     "id");
2087             assertEquals("string-com.android.test.1-user:0-res:10/en", ret.get(0).getTitle());
2088             assertEquals("string-com.android.test.1-user:0-res:11/en", ret.get(0).getText());
2089             assertEquals("string-com.android.test.1-user:0-res:12/en",
2090                     ret.get(0).getDisabledMessage());
2091 
2092             // USER P0
2093             ret = assertShortcutIds(
2094                     assertAllStringsResolved(mLauncherApps.getShortcuts(q, HANDLE_USER_P0)),
2095                     "id");
2096             assertEquals("string-com.android.test.1-user:20-res:10/en", ret.get(0).getTitle());
2097             assertEquals("string-com.android.test.1-user:20-res:11/en", ret.get(0).getText());
2098             assertEquals("string-com.android.test.1-user:20-res:12/en",
2099                     ret.get(0).getDisabledMessage());
2100         });
2101     }
2102 
testGetShortcuts_personsFlag()2103     public void testGetShortcuts_personsFlag() {
2104         ShortcutInfo s = new ShortcutInfo.Builder(mClientContext, "id")
2105                 .setShortLabel("label")
2106                 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
2107                 .setPerson(makePerson("person", "personKey", "personUri"))
2108                 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
2109                 .build();
2110 
2111         setCaller(CALLING_PACKAGE_1);
2112         assertTrue(mManager.setDynamicShortcuts(list(s)));
2113 
2114         setCaller(LAUNCHER_1);
2115 
2116         assertNull(mLauncherApps.getShortcuts(buildQuery(
2117                 /* time =*/ 0, CALLING_PACKAGE_1, /* activity =*/ null,
2118                 ShortcutQuery.FLAG_MATCH_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
2119                 getCallingUser()).get(0).getPersons());
2120 
2121         assertNull(mLauncherApps.getShortcuts(buildQuery(
2122                 /* time =*/ 0, CALLING_PACKAGE_1, /* activity =*/ null,
2123                 ShortcutQuery.FLAG_MATCH_DYNAMIC),
2124                 getCallingUser()).get(0).getPersons());
2125 
2126         // Using FLAG_GET_PERSONS_DATA should fail without permission
2127         mInjectCheckAccessShortcutsPermission = false;
2128         assertExpectException(
2129                 SecurityException.class, "Caller can't access shortcut information", () -> {
2130                     mLauncherApps.getShortcuts(buildQuery(
2131                             /* time =*/ 0, CALLING_PACKAGE_1, /* activity =*/ null,
2132                             ShortcutQuery.FLAG_MATCH_DYNAMIC
2133                                     | ShortcutQuery.FLAG_GET_PERSONS_DATA),
2134                             getCallingUser());
2135                 });
2136 
2137         mInjectCheckAccessShortcutsPermission = true;
2138         assertEquals("person", mLauncherApps.getShortcuts(buildQuery(
2139                 /* time =*/ 0, CALLING_PACKAGE_1, /* activity =*/ null,
2140                 ShortcutQuery.FLAG_MATCH_DYNAMIC | ShortcutQuery.FLAG_GET_PERSONS_DATA),
2141                 getCallingUser()).get(0).getPersons()[0].getName());
2142 
2143         assertNull(mLauncherApps.getShortcuts(buildQuery(
2144                 /* time =*/ 0, CALLING_PACKAGE_1, /* activity =*/ null,
2145                 ShortcutQuery.FLAG_MATCH_DYNAMIC | ShortcutQuery.FLAG_GET_PERSONS_DATA
2146                         | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
2147                 getCallingUser()).get(0).getPersons());
2148     }
2149 
2150     // TODO resource
testGetShortcutInfo()2151     public void testGetShortcutInfo() {
2152         // Create shortcuts.
2153         setCaller(CALLING_PACKAGE_1);
2154         final ShortcutInfo s1_1 = makeShortcut(
2155                 "s1",
2156                 "Title 1",
2157                 makeComponent(ShortcutActivity.class),
2158                 /* icon =*/ null,
2159                 makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
2160                         "key1", "val1", "nest", makeBundle("key", 123)),
2161                 /* weight */ 10);
2162 
2163         final ShortcutInfo s1_2 = makeShortcut(
2164                 "s2",
2165                 "Title 2",
2166                 /* activity */ null,
2167                 /* icon =*/ null,
2168                 makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
2169                 /* weight */ 12);
2170 
2171         assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
2172         dumpsysOnLogcat();
2173 
2174         setCaller(CALLING_PACKAGE_2);
2175         final ShortcutInfo s2_1 = makeShortcut(
2176                 "s1",
2177                 "ABC",
2178                 makeComponent(ShortcutActivity2.class),
2179                 /* icon =*/ null,
2180                 makeIntent(Intent.ACTION_ANSWER, ShortcutActivity2.class,
2181                         "key1", "val1", "nest", makeBundle("key", 123)),
2182                 /* weight */ 10);
2183         assertTrue(mManager.setDynamicShortcuts(list(s2_1)));
2184         dumpsysOnLogcat();
2185 
2186         // Pin some.
2187         setCaller(LAUNCHER_1);
2188 
2189         mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2190                 list("s2"), getCallingUser());
2191 
2192         dumpsysOnLogcat();
2193 
2194         // Delete some.
2195         setCaller(CALLING_PACKAGE_1);
2196         assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
2197         mManager.removeDynamicShortcuts(list("s2"));
2198         assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
2199 
2200         dumpsysOnLogcat();
2201 
2202         setCaller(LAUNCHER_1);
2203         List<ShortcutInfo> list;
2204 
2205         // Note we don't guarantee the orders.
2206         list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents(
2207                 assertAllNotKeyFieldsOnly(
2208                         mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1,
2209                                 list("s2", "s1", "s3", null), getCallingUser())))),
2210                 "s1", "s2");
2211         assertEquals("Title 1", findById(list, "s1").getTitle());
2212         assertEquals("Title 2", findById(list, "s2").getTitle());
2213 
2214         assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents(
2215                 mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1,
2216                         list("s3"), getCallingUser())))
2217                 /* none */);
2218 
2219         list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents(
2220                 mLauncherApps.getShortcutInfo(CALLING_PACKAGE_2,
2221                         list("s1", "s2", "s3"), getCallingUser()))),
2222                 "s1");
2223         assertEquals("ABC", findById(list, "s1").getTitle());
2224     }
2225 
testPinShortcutAndGetPinnedShortcuts()2226     public void testPinShortcutAndGetPinnedShortcuts() {
2227         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2228             final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
2229             final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
2230 
2231             assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
2232         });
2233 
2234         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2235             final ShortcutInfo s2_2 = makeShortcutWithTimestamp("s2", 1500);
2236             final ShortcutInfo s2_3 = makeShortcutWithTimestamp("s3", 3000);
2237             final ShortcutInfo s2_4 = makeShortcutWithTimestamp("s4", 500);
2238             assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
2239         });
2240 
2241         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
2242             final ShortcutInfo s3_2 = makeShortcutWithTimestamp("s2", 1000);
2243             assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
2244         });
2245 
2246         // Pin some.
2247         runWithCaller(LAUNCHER_1, USER_0, () -> {
2248             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2249                     list("s2", "s3"), getCallingUser());
2250 
2251             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2252                     list("s3", "s4", "s5"), getCallingUser());
2253 
2254             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3,
2255                     list("s3"), getCallingUser());  // Note ID doesn't exist
2256         });
2257 
2258         // Delete some.
2259         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2260             assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
2261             mManager.removeDynamicShortcuts(list("s2"));
2262             assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
2263 
2264             assertShortcutIds(mManager.getDynamicShortcuts(), "s1");
2265         });
2266 
2267         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2268             assertShortcutIds(mManager.getPinnedShortcuts(), "s3", "s4");
2269             mManager.removeDynamicShortcuts(list("s3"));
2270             assertShortcutIds(mManager.getPinnedShortcuts(), "s3", "s4");
2271 
2272             assertShortcutIds(mManager.getDynamicShortcuts(), "s2", "s4");
2273         });
2274 
2275         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
2276             assertShortcutIds(mManager.getPinnedShortcuts() /* none */);
2277             mManager.removeDynamicShortcuts(list("s2"));
2278             assertShortcutIds(mManager.getPinnedShortcuts() /* none */);
2279 
2280             assertEmpty(mManager.getDynamicShortcuts());
2281         });
2282 
2283         // Get pinned shortcuts from launcher
2284         runWithCaller(LAUNCHER_1, USER_0, () -> {
2285             // CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists.
2286             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
2287                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2288                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser())))),
2289                     "s2");
2290 
2291             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
2292                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2293                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser())))),
2294                     "s3", "s4");
2295 
2296             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
2297                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_3,
2298                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))))
2299                     /* none */);
2300         });
2301     }
2302 
2303     /**
2304      * This is similar to the above test, except it used "disable" instead of "remove".  It also
2305      * does "enable".
2306      */
testDisableAndEnableShortcuts()2307     public void testDisableAndEnableShortcuts() {
2308         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2309             final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
2310             final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
2311 
2312             assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
2313         });
2314 
2315         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2316             final ShortcutInfo s2_2 = makeShortcutWithTimestamp("s2", 1500);
2317             final ShortcutInfo s2_3 = makeShortcutWithTimestamp("s3", 3000);
2318             final ShortcutInfo s2_4 = makeShortcutWithTimestamp("s4", 500);
2319             assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
2320         });
2321 
2322         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
2323             final ShortcutInfo s3_2 = makeShortcutWithTimestamp("s2", 1000);
2324             assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
2325         });
2326 
2327         // Pin some.
2328         runWithCaller(LAUNCHER_1, USER_0, () -> {
2329             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2330                     list("s2", "s3"), getCallingUser());
2331 
2332             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2333                     list("s3", "s4", "s5"), getCallingUser());
2334 
2335             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3,
2336                     list("s3"), getCallingUser());  // Note ID doesn't exist
2337         });
2338 
2339         // Disable some.
2340         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2341             assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
2342 
2343             mManager.updateShortcuts(list(
2344                     new ShortcutInfo.Builder(mClientContext, "s2").setDisabledMessage("xyz")
2345                             .build()));
2346 
2347             mManager.disableShortcuts(list("s2"));
2348 
2349             assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
2350             assertShortcutIds(mManager.getDynamicShortcuts(), "s1");
2351         });
2352 
2353         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2354             assertShortcutIds(mManager.getPinnedShortcuts(), "s3", "s4");
2355 
2356             // disable should work even if a shortcut is not dynamic, so try calling "remove" first
2357             // here.
2358             mManager.removeDynamicShortcuts(list("s3"));
2359             mManager.disableShortcuts(list("s3"));
2360 
2361             assertShortcutIds(mManager.getPinnedShortcuts(), "s3", "s4");
2362             assertShortcutIds(mManager.getDynamicShortcuts(), "s2", "s4");
2363         });
2364 
2365         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
2366             assertShortcutIds(mManager.getPinnedShortcuts() /* none */);
2367 
2368             mManager.disableShortcuts(list("s2"));
2369 
2370             assertShortcutIds(mManager.getPinnedShortcuts() /* none */);
2371 
2372             assertEmpty(mManager.getDynamicShortcuts());
2373             assertEmpty(getCallerShortcuts());
2374         });
2375 
2376         // Get pinned shortcuts from launcher
2377         runWithCaller(LAUNCHER_1, USER_0, () -> {
2378             // CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists, and disabled.
2379             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2380                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))
2381                     .haveIds("s2")
2382                     .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BY_APP)
2383                     .forAllShortcuts(si -> {
2384                         assertEquals("xyz", si.getDisabledMessage());
2385                     })
2386                     .areAllPinned()
2387                     .areAllNotWithKeyFieldsOnly()
2388                     .areAllDisabled();
2389             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
2390                     ActivityNotFoundException.class);
2391 
2392             // Here, s4 is still enabled and launchable, but s3 is disabled.
2393             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2394                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))
2395                     .haveIds("s3", "s4")
2396                     .areAllPinned()
2397                     .areAllNotWithKeyFieldsOnly()
2398 
2399                     .selectByIds("s3")
2400                     .areAllDisabled()
2401 
2402                     .revertToOriginalList()
2403                     .selectByIds("s4")
2404                     .areAllEnabled();
2405 
2406             assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s3", USER_0,
2407                     ActivityNotFoundException.class);
2408             assertShortcutLaunchable(CALLING_PACKAGE_2, "s4", USER_0);
2409 
2410             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
2411                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_3,
2412                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))))
2413                     /* none */);
2414         });
2415 
2416         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2417             mManager.enableShortcuts(list("s2"));
2418 
2419             assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
2420             assertShortcutIds(mManager.getDynamicShortcuts(), "s1");
2421         });
2422         runWithCaller(LAUNCHER_1, USER_0, () -> {
2423             // CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists.
2424             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
2425                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2426                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser())))),
2427                     "s2");
2428             assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2429         });
2430     }
2431 
testDisableShortcuts_thenRepublish()2432     public void testDisableShortcuts_thenRepublish() {
2433         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2434             assertTrue(mManager.setDynamicShortcuts(list(
2435                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2436 
2437             runWithCaller(LAUNCHER_1, USER_0, () -> {
2438                 mLauncherApps.pinShortcuts(
2439                         CALLING_PACKAGE_1, list("s1", "s2", "s3"), HANDLE_USER_0);
2440             });
2441 
2442             mManager.disableShortcuts(list("s1", "s2", "s3"));
2443 
2444             assertWith(getCallerShortcuts())
2445                     .haveIds("s1", "s2", "s3")
2446                     .areAllNotDynamic()
2447                     .areAllPinned()
2448                     .areAllDisabled();
2449 
2450             // Make sure updateShortcuts() will not re-enable them.
2451             assertTrue(mManager.updateShortcuts(list(
2452                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2453 
2454             assertWith(getCallerShortcuts())
2455                     .haveIds("s1", "s2", "s3")
2456                     .areAllNotDynamic()
2457                     .areAllPinned()
2458                     .areAllDisabled();
2459 
2460             // Re-publish s1 with setDynamicShortcuts.
2461             mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
2462 
2463             assertTrue(mManager.setDynamicShortcuts(list(
2464                     makeShortcut("s1"))));
2465 
2466             assertWith(getCallerShortcuts())
2467                     .haveIds("s1", "s2", "s3")
2468 
2469                     .selectByIds("s1")
2470                     .areAllDynamic()
2471                     .areAllPinned()
2472                     .areAllEnabled()
2473 
2474                     .revertToOriginalList()
2475                     .selectByIds("s2", "s3")
2476                     .areAllNotDynamic()
2477                     .areAllPinned()
2478                     .areAllDisabled();
2479 
2480             // Re-publish s2 with addDynamicShortcuts.
2481             mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
2482 
2483             assertTrue(mManager.addDynamicShortcuts(list(
2484                     makeShortcut("s2"))));
2485 
2486             assertWith(getCallerShortcuts())
2487                     .haveIds("s1", "s2", "s3")
2488 
2489                     .selectByIds("s1", "s2")
2490                     .areAllDynamic()
2491                     .areAllPinned()
2492                     .areAllEnabled()
2493 
2494                     .revertToOriginalList()
2495                     .selectByIds("s3")
2496                     .areAllNotDynamic()
2497                     .areAllPinned()
2498                     .areAllDisabled();
2499         });
2500     }
2501 
testPinShortcutAndGetPinnedShortcuts_multi()2502     public void testPinShortcutAndGetPinnedShortcuts_multi() {
2503         // Create some shortcuts.
2504         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2505             assertTrue(mManager.setDynamicShortcuts(list(
2506                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2507         });
2508 
2509         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2510             assertTrue(mManager.setDynamicShortcuts(list(
2511                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2512         });
2513 
2514         dumpsysOnLogcat();
2515 
2516         // Pin some.
2517         runWithCaller(LAUNCHER_1, USER_0, () -> {
2518             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2519                     list("s3", "s4"), getCallingUser());
2520 
2521             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2522                     list("s1", "s2", "s4"), getCallingUser());
2523         });
2524 
2525         dumpsysOnLogcat();
2526 
2527         // Delete some.
2528         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2529             assertShortcutIds(mManager.getPinnedShortcuts(), "s3");
2530             mManager.removeDynamicShortcuts(list("s3"));
2531             assertShortcutIds(mManager.getPinnedShortcuts(), "s3");
2532         });
2533 
2534         dumpsysOnLogcat();
2535 
2536         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2537             assertShortcutIds(mManager.getPinnedShortcuts(), "s1", "s2");
2538             mManager.removeDynamicShortcuts(list("s1"));
2539             mManager.removeDynamicShortcuts(list("s3"));
2540             assertShortcutIds(mManager.getPinnedShortcuts(), "s1", "s2");
2541         });
2542 
2543         dumpsysOnLogcat();
2544 
2545         // Get pinned shortcuts from launcher
2546         runWithCaller(LAUNCHER_1, USER_0, () -> {
2547             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2548                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2549                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2550                     "s3");
2551 
2552             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2553                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2554                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2555                     "s1", "s2");
2556 
2557             assertShortcutIds(assertAllDynamicOrPinned(
2558                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2559                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2560                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2561                     "s1", "s2", "s3");
2562 
2563             assertShortcutIds(assertAllDynamicOrPinned(
2564                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2565                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2566                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2567                     "s1", "s2");
2568         });
2569 
2570         dumpsysOnLogcat("Before launcher 2");
2571 
2572         runWithCaller(LAUNCHER_2, USER_0, () -> {
2573             // Launcher2 still has no pinned ones.
2574             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2575                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2576                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser())))
2577                     /* none */);
2578             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2579                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2580                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser())))
2581                     /* none */);
2582 
2583             // Make sure FLAG_MATCH_ALL_PINNED will be ignored.
2584             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2585                     /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED
2586                             | ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER), getCallingUser()))
2587                     .isEmpty();
2588 
2589             // Make sure the special permission works.
2590             mInjectCheckAccessShortcutsPermission = true;
2591 
2592             dumpsysOnLogcat("All-pinned");
2593 
2594             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2595                     /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED
2596                             | ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER), getCallingUser()))
2597                     .haveIds("s1", "s2");
2598             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2599                     /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED), getCallingUser()))
2600                     .isEmpty();
2601 
2602             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", getCallingUser().getIdentifier());
2603 
2604             mInjectCheckAccessShortcutsPermission = false;
2605 
2606             assertShortcutNotLaunched(CALLING_PACKAGE_2, "s1", getCallingUser().getIdentifier());
2607 
2608             assertShortcutIds(assertAllDynamic(
2609                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2610                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2611                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2612                     "s1", "s2");
2613             assertShortcutIds(assertAllDynamic(
2614                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2615                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2616                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2617                     "s2");
2618 
2619             // Now pin some.
2620             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2621                     list("s1", "s2"), getCallingUser());
2622 
2623             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2624                     list("s1", "s2"), getCallingUser());
2625 
2626             assertShortcutIds(assertAllDynamic(
2627                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2628                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2629                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2630                     "s1", "s2");
2631 
2632             // S1 was not visible to it, so shouldn't be pinned.
2633             assertShortcutIds(assertAllDynamic(
2634                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2635                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2636                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2637                     "s2");
2638         });
2639 
2640         // Re-initialize and load from the files.
2641         mService.saveDirtyInfo();
2642         initService();
2643 
2644         // Load from file.
2645         mService.handleUnlockUser(USER_0);
2646 
2647         // Make sure package info is restored too.
2648         runWithCaller(LAUNCHER_1, USER_0, () -> {
2649             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2650                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2651                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2652                     "s3");
2653             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2654                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2655                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2656                     "s1", "s2");
2657         });
2658         runWithCaller(LAUNCHER_2, USER_0, () -> {
2659             assertShortcutIds(assertAllDynamic(
2660                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2661                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2662                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2663                     "s1", "s2");
2664             assertShortcutIds(assertAllDynamic(
2665                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2666                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
2667                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
2668                     "s2");
2669         });
2670 
2671         // Delete all dynamic.
2672         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2673             mManager.removeAllDynamicShortcuts();
2674 
2675             assertEquals(0, mManager.getDynamicShortcuts().size());
2676             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3");
2677         });
2678         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2679             mManager.removeAllDynamicShortcuts();
2680 
2681             assertEquals(0, mManager.getDynamicShortcuts().size());
2682             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s2", "s1");
2683         });
2684 
2685         runWithCaller(LAUNCHER_1, USER_0, () -> {
2686             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2687                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2688                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2689                     "s3");
2690 
2691             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2692                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2693                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2694                     "s1", "s2");
2695 
2696             // from all packages.
2697             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2698                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, null,
2699                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2700                     "s1", "s2", "s3");
2701 
2702             // Update pined.  Note s2 and s3 are actually available, but not visible to this
2703             // launcher, so still can't be pinned.
2704             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
2705                     getCallingUser());
2706 
2707             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2708                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2709                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2710                     "s3");
2711         });
2712         // Re-publish s1.
2713         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2714             assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
2715 
2716             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
2717             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3");
2718         });
2719         runWithCaller(LAUNCHER_1, USER_0, () -> {
2720             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2721                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2722                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2723                     "s3");
2724 
2725             // Now "s1" is visible, so can be pinned.
2726             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
2727                     getCallingUser());
2728 
2729             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2730                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2731                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2732                     "s1", "s3");
2733         });
2734 
2735         // Now clear pinned shortcuts.  First, from launcher 1.
2736         runWithCaller(LAUNCHER_1, USER_0, () -> {
2737             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
2738             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
2739 
2740             assertEquals(0,
2741                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2742                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2743             assertEquals(0,
2744                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2745                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2746         });
2747         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2748             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
2749             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2");
2750         });
2751         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2752             assertEquals(0, mManager.getDynamicShortcuts().size());
2753             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s2");
2754         });
2755 
2756         // Clear all pins from launcher 2.
2757         runWithCaller(LAUNCHER_2, USER_0, () -> {
2758             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
2759             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
2760 
2761             assertEquals(0,
2762                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2763                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2764             assertEquals(0,
2765                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2766                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2767         });
2768         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2769             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
2770             assertEquals(0, mManager.getPinnedShortcuts().size());
2771         });
2772         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2773             assertEquals(0, mManager.getDynamicShortcuts().size());
2774             assertEquals(0, mManager.getPinnedShortcuts().size());
2775         });
2776     }
2777 
testPinShortcutAndGetPinnedShortcuts_assistant()2778     public void testPinShortcutAndGetPinnedShortcuts_assistant() {
2779         // Create some shortcuts.
2780         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2781             assertTrue(mManager.setDynamicShortcuts(list(
2782                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2783         });
2784 
2785         // Pin some.
2786         runWithCaller(LAUNCHER_1, USER_0, () -> {
2787             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2788                     list("s3", "s4"), getCallingUser());
2789         });
2790 
2791         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2792             assertTrue(mManager.setDynamicShortcuts(list(
2793                     makeShortcut("s1"))));
2794         });
2795 
2796         runWithCaller(LAUNCHER_2, USER_0, () -> {
2797             final ShortcutQuery allPinned = new ShortcutQuery().setQueryFlags(
2798                     ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER);
2799 
2800             assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
2801                     .isEmpty();
2802 
2803             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2804             assertShortcutNotLaunched(CALLING_PACKAGE_1, "s3", USER_0);
2805             assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_0);
2806 
2807             // Make it the assistant app.
2808             mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_0);
2809             assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
2810                     .haveIds("s3");
2811 
2812             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2813             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2814             assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_0);
2815 
2816             mInternal.setShortcutHostPackage("another-type", LAUNCHER_3, USER_0);
2817             assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
2818                     .haveIds("s3");
2819 
2820             mInternal.setShortcutHostPackage("assistant", null, USER_0);
2821             assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
2822                     .isEmpty();
2823 
2824             mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_0);
2825             assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
2826                     .haveIds("s3");
2827 
2828             mInternal.setShortcutHostPackage("assistant", LAUNCHER_1, USER_0);
2829             assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
2830                     .isEmpty();
2831         });
2832     }
2833 
testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch()2834     public void testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
2835         // Create some shortcuts.
2836         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2837             assertTrue(mManager.setDynamicShortcuts(list(
2838                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2839         });
2840         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2841             assertTrue(mManager.setDynamicShortcuts(list(
2842                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2843         });
2844 
2845         mRunningUsers.put(USER_10, true);
2846 
2847         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
2848             assertTrue(mManager.setDynamicShortcuts(list(
2849                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
2850                     makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
2851         });
2852 
2853         // Pin some shortcuts and see the result.
2854 
2855         runWithCaller(LAUNCHER_1, USER_0, () -> {
2856             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2857                     list("s1"), HANDLE_USER_0);
2858 
2859             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2860                     list("s1", "s2", "s3"), HANDLE_USER_0);
2861         });
2862 
2863         runWithCaller(LAUNCHER_1, USER_P0, () -> {
2864             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2865                     list("s2"), HANDLE_USER_0);
2866 
2867             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2868                     list("s2", "s3"), HANDLE_USER_0);
2869         });
2870 
2871         runWithCaller(LAUNCHER_2, USER_P0, () -> {
2872             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2873                     list("s3"), HANDLE_USER_0);
2874 
2875             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2876                     list("s3"), HANDLE_USER_0);
2877         });
2878 
2879         runWithCaller(LAUNCHER_2, USER_10, () -> {
2880             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2881                     list("s1", "s2", "s3"), HANDLE_USER_10);
2882         });
2883 
2884         // First, make sure managed profile can't see other profiles.
2885         runWithCaller(LAUNCHER_1, USER_P1, () -> {
2886 
2887             final ShortcutQuery q = new ShortcutQuery().setQueryFlags(
2888                     ShortcutQuery.FLAG_MATCH_DYNAMIC | ShortcutQuery.FLAG_MATCH_PINNED
2889                             | ShortcutQuery.FLAG_MATCH_MANIFEST);
2890 
2891             // No shortcuts are visible.
2892             assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
2893 
2894             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
2895 
2896             // Should have no effects.
2897             assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
2898 
2899             assertShortcutNotLaunched(CALLING_PACKAGE_1, "s1", USER_0);
2900         });
2901 
2902         // Cross profile pinning.
2903         final int PIN_AND_DYNAMIC = ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC;
2904 
2905         runWithCaller(LAUNCHER_1, USER_0, () -> {
2906             assertShortcutIds(assertAllPinned(
2907                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2908                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2909                     "s1");
2910             assertShortcutIds(assertAllDynamic(
2911                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2912                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2913                     "s1", "s2", "s3");
2914             assertShortcutIds(assertAllDynamicOrPinned(
2915                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2916                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2917                     "s1", "s2", "s3");
2918 
2919             assertShortcutIds(assertAllPinned(
2920                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2921                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2922                     "s1", "s2", "s3");
2923             assertShortcutIds(assertAllDynamic(
2924                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2925                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2926                     "s1", "s2", "s3");
2927             assertShortcutIds(assertAllDynamicOrPinned(
2928                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2929                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2930                     "s1", "s2", "s3");
2931 
2932             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2933             assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2934             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2935 
2936             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2937             assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2938             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2939 
2940             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2941                     SecurityException.class);
2942             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2943                     SecurityException.class);
2944             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2945                     SecurityException.class);
2946             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2947                     SecurityException.class);
2948             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2949                     SecurityException.class);
2950             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2951                     SecurityException.class);
2952         });
2953         runWithCaller(LAUNCHER_1, USER_P0, () -> {
2954             assertShortcutIds(assertAllPinned(
2955                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2956                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2957                     "s2");
2958             assertShortcutIds(assertAllDynamic(
2959                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2960                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2961                     "s1", "s2", "s3");
2962             assertShortcutIds(assertAllDynamicOrPinned(
2963                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2964                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2965                     "s1", "s2", "s3");
2966 
2967             assertShortcutIds(assertAllPinned(
2968                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2969                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2970                     "s2", "s3");
2971             assertShortcutIds(assertAllDynamic(
2972                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2973                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2974                     "s1", "s2", "s3");
2975             assertShortcutIds(assertAllDynamicOrPinned(
2976                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2977                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2978                     "s1", "s2", "s3");
2979 
2980             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2981             assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2982             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2983 
2984             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2985             assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2986             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2987 
2988             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2989                     SecurityException.class);
2990             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2991                     SecurityException.class);
2992             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2993                     SecurityException.class);
2994             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2995                     SecurityException.class);
2996             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2997                     SecurityException.class);
2998             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2999                     SecurityException.class);
3000         });
3001         runWithCaller(LAUNCHER_2, USER_P0, () -> {
3002             assertShortcutIds(assertAllPinned(
3003                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3004                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3005                     "s3");
3006             assertShortcutIds(assertAllDynamic(
3007                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3008                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3009                     "s1", "s2", "s3");
3010             assertShortcutIds(assertAllDynamicOrPinned(
3011                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3012                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3013                     "s1", "s2", "s3");
3014 
3015             assertShortcutIds(assertAllPinned(
3016                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3017                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3018                     "s3");
3019             assertShortcutIds(assertAllDynamic(
3020                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3021                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3022                     "s1", "s2", "s3");
3023             assertShortcutIds(assertAllDynamicOrPinned(
3024                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3025                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3026                     "s1", "s2", "s3");
3027 
3028             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
3029             assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
3030             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
3031 
3032             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
3033             assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
3034             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
3035 
3036             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
3037                     SecurityException.class);
3038             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
3039                     SecurityException.class);
3040             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
3041                     SecurityException.class);
3042             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3043                     SecurityException.class);
3044             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3045                     SecurityException.class);
3046             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3047                     SecurityException.class);
3048         });
3049         runWithCaller(LAUNCHER_2, USER_10, () -> {
3050             assertShortcutIds(assertAllPinned(
3051                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3052                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
3053                     "s1", "s2", "s3");
3054             assertShortcutIds(assertAllDynamic(
3055                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3056                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
3057                     "s1", "s2", "s3", "s4", "s5", "s6");
3058             assertShortcutIds(assertAllDynamicOrPinned(
3059                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3060                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
3061                     "s1", "s2", "s3", "s4", "s5", "s6");
3062         });
3063 
3064         // Remove some dynamic shortcuts.
3065 
3066         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3067             assertTrue(mManager.setDynamicShortcuts(list(
3068                     makeShortcut("s1"))));
3069         });
3070         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
3071             assertTrue(mManager.setDynamicShortcuts(list(
3072                     makeShortcut("s1"))));
3073         });
3074         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3075             assertTrue(mManager.setDynamicShortcuts(list(
3076                     makeShortcut("s1"))));
3077         });
3078 
3079         runWithCaller(LAUNCHER_1, USER_0, () -> {
3080             assertShortcutIds(assertAllPinned(
3081                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3082                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3083                     "s1");
3084             assertShortcutIds(assertAllDynamic(
3085                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3086                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3087                     "s1");
3088             assertShortcutIds(assertAllDynamicOrPinned(
3089                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3090                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3091                     "s1");
3092 
3093             assertShortcutIds(assertAllPinned(
3094                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3095                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3096                     "s1", "s2", "s3");
3097             assertShortcutIds(assertAllDynamic(
3098                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3099                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3100                     "s1");
3101             assertShortcutIds(assertAllDynamicOrPinned(
3102                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3103                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3104                     "s1", "s2", "s3");
3105 
3106             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
3107             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
3108                     ActivityNotFoundException.class);
3109             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
3110                     ActivityNotFoundException.class);
3111 
3112             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
3113             assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
3114             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
3115 
3116             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
3117                     SecurityException.class);
3118             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
3119                     SecurityException.class);
3120             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
3121                     SecurityException.class);
3122             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3123                     SecurityException.class);
3124             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3125                     SecurityException.class);
3126             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3127                     SecurityException.class);
3128         });
3129         runWithCaller(LAUNCHER_1, USER_P0, () -> {
3130             assertShortcutIds(assertAllPinned(
3131                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3132                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3133                     "s2");
3134             assertShortcutIds(assertAllDynamic(
3135                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3136                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3137                     "s1");
3138             assertShortcutIds(assertAllDynamicOrPinned(
3139                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3140                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3141                     "s1", "s2");
3142 
3143             assertShortcutIds(assertAllPinned(
3144                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3145                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3146                     "s2", "s3");
3147             assertShortcutIds(assertAllDynamic(
3148                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3149                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3150                     "s1");
3151             assertShortcutIds(assertAllDynamicOrPinned(
3152                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3153                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3154                     "s1", "s2", "s3");
3155 
3156             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
3157             assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
3158             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
3159                     ActivityNotFoundException.class);
3160 
3161             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
3162             assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
3163             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
3164 
3165             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
3166                     SecurityException.class);
3167             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
3168                     SecurityException.class);
3169             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
3170                     SecurityException.class);
3171             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3172                     SecurityException.class);
3173             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3174                     SecurityException.class);
3175             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3176                     SecurityException.class);
3177         });
3178         runWithCaller(LAUNCHER_2, USER_P0, () -> {
3179             assertShortcutIds(assertAllPinned(
3180                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3181                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3182                     "s3");
3183             assertShortcutIds(assertAllDynamic(
3184                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3185                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3186                     "s1");
3187             assertShortcutIds(assertAllDynamicOrPinned(
3188                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3189                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3190                     "s1", "s3");
3191 
3192             assertShortcutIds(assertAllPinned(
3193                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3194                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3195                     "s3");
3196             assertShortcutIds(assertAllDynamic(
3197                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3198                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3199                     "s1");
3200             assertShortcutIds(assertAllDynamicOrPinned(
3201                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3202                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3203                     "s1", "s3");
3204 
3205             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
3206             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
3207                     ActivityNotFoundException.class);
3208             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
3209 
3210             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
3211             assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
3212                     ActivityNotFoundException.class);
3213             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
3214 
3215             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
3216                     SecurityException.class);
3217             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
3218                     SecurityException.class);
3219             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
3220                     SecurityException.class);
3221             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3222                     SecurityException.class);
3223             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3224                     SecurityException.class);
3225             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3226                     SecurityException.class);
3227         });
3228         runWithCaller(LAUNCHER_2, USER_10, () -> {
3229             assertShortcutIds(assertAllPinned(
3230                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3231                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
3232                     "s1", "s2", "s3");
3233             assertShortcutIds(assertAllDynamic(
3234                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3235                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
3236                     "s1");
3237             assertShortcutIds(assertAllDynamicOrPinned(
3238                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3239                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
3240                     "s1", "s2", "s3");
3241 
3242             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
3243                     SecurityException.class);
3244             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
3245                     SecurityException.class);
3246             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
3247                     SecurityException.class);
3248 
3249             assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s1", USER_0,
3250                     SecurityException.class);
3251             assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
3252                     SecurityException.class);
3253             assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s3", USER_0,
3254                     SecurityException.class);
3255 
3256             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
3257             assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
3258             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
3259             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3260                     ActivityNotFoundException.class);
3261             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3262                     ActivityNotFoundException.class);
3263             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3264                     ActivityNotFoundException.class);
3265         });
3266 
3267         // Save & load and make sure we still have the same information.
3268         mService.saveDirtyInfo();
3269         initService();
3270         mService.handleUnlockUser(USER_0);
3271 
3272         runWithCaller(LAUNCHER_1, USER_0, () -> {
3273             assertShortcutIds(assertAllPinned(
3274                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3275                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3276                     "s1");
3277             assertShortcutIds(assertAllDynamic(
3278                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3279                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3280                     "s1");
3281             assertShortcutIds(assertAllDynamicOrPinned(
3282                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3283                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3284                     "s1");
3285 
3286             assertShortcutIds(assertAllPinned(
3287                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3288                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3289                     "s1", "s2", "s3");
3290             assertShortcutIds(assertAllDynamic(
3291                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3292                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3293                     "s1");
3294             assertShortcutIds(assertAllDynamicOrPinned(
3295                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3296                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3297                     "s1", "s2", "s3");
3298 
3299             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
3300             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
3301                     ActivityNotFoundException.class);
3302             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
3303                     ActivityNotFoundException.class);
3304 
3305             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
3306             assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
3307             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
3308 
3309             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
3310                     SecurityException.class);
3311             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
3312                     SecurityException.class);
3313             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
3314                     SecurityException.class);
3315             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3316                     SecurityException.class);
3317             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3318                     SecurityException.class);
3319             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3320                     SecurityException.class);
3321         });
3322         runWithCaller(LAUNCHER_1, USER_P0, () -> {
3323             assertShortcutIds(assertAllPinned(
3324                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3325                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3326                     "s2");
3327             assertShortcutIds(assertAllDynamic(
3328                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3329                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3330                     "s1");
3331             assertShortcutIds(assertAllDynamicOrPinned(
3332                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3333                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3334                     "s1", "s2");
3335 
3336             assertShortcutIds(assertAllPinned(
3337                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3338                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3339                     "s2", "s3");
3340             assertShortcutIds(assertAllDynamic(
3341                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3342                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3343                     "s1");
3344             assertShortcutIds(assertAllDynamicOrPinned(
3345                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3346                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3347                     "s1", "s2", "s3");
3348 
3349             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
3350             assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
3351             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
3352                     ActivityNotFoundException.class);
3353 
3354             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
3355             assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
3356             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
3357 
3358             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
3359                     SecurityException.class);
3360             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
3361                     SecurityException.class);
3362             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
3363                     SecurityException.class);
3364             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3365                     SecurityException.class);
3366             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3367                     SecurityException.class);
3368             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3369                     SecurityException.class);
3370         });
3371         runWithCaller(LAUNCHER_2, USER_P0, () -> {
3372             assertShortcutIds(assertAllPinned(
3373                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3374                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3375                     "s3");
3376             assertShortcutIds(assertAllDynamic(
3377                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3378                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3379                     "s1");
3380             assertShortcutIds(assertAllDynamicOrPinned(
3381                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
3382                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3383                     "s1", "s3");
3384 
3385             assertShortcutIds(assertAllPinned(
3386                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3387                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
3388                     "s3");
3389             assertShortcutIds(assertAllDynamic(
3390                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3391                     /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
3392                     "s1");
3393             assertShortcutIds(assertAllDynamicOrPinned(
3394                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
3395                     /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
3396                     "s1", "s3");
3397 
3398             assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
3399             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
3400                     ActivityNotFoundException.class);
3401             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
3402 
3403             assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
3404             assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
3405                     ActivityNotFoundException.class);
3406             assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
3407 
3408             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
3409                     SecurityException.class);
3410             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
3411                     SecurityException.class);
3412             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
3413                     SecurityException.class);
3414             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
3415                     SecurityException.class);
3416             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
3417                     SecurityException.class);
3418             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
3419                     SecurityException.class);
3420         });
3421     }
3422 
testStartShortcut()3423     public void testStartShortcut() {
3424         // Create some shortcuts.
3425         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3426             final ShortcutInfo s1_1 = makeShortcut(
3427                     "s1",
3428                     "Title 1",
3429                     makeComponent(ShortcutActivity.class),
3430                     /* icon =*/ null,
3431                     new Intent[]{makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
3432                             "key1", "val1", "nest", makeBundle("key", 123))
3433                             .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
3434                             new Intent("act2").setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)},
3435                     /* rank */ 10);
3436 
3437             final ShortcutInfo s1_2 = makeShortcut(
3438                     "s2",
3439                     "Title 2",
3440             /* activity */ null,
3441             /* icon =*/ null,
3442                     makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
3443             /* rank */ 12);
3444 
3445             final ShortcutInfo s1_3 = makeShortcut("s3");
3446 
3447             assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3)));
3448         });
3449 
3450         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
3451             final ShortcutInfo s2_1 = makeShortcut(
3452                     "s1",
3453                     "ABC",
3454                     makeComponent(ShortcutActivity.class),
3455                     /* icon =*/ null,
3456                     makeIntent(Intent.ACTION_ANSWER, ShortcutActivity.class,
3457                             "key1", "val1", "nest", makeBundle("key", 123)),
3458                     /* weight */ 10);
3459             assertTrue(mManager.setDynamicShortcuts(list(s2_1)));
3460         });
3461 
3462         // Pin some.
3463         runWithCaller(LAUNCHER_1, USER_0, () -> {
3464             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
3465                     list("s1", "s2"), getCallingUser());
3466 
3467             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
3468                     list("s1"), getCallingUser());
3469         });
3470 
3471         // Just to make it complicated, delete some.
3472         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3473             mManager.removeDynamicShortcuts(list("s2"));
3474         });
3475 
3476         runWithCaller(LAUNCHER_1, USER_0, () -> {
3477             final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_0);
3478             assertEquals(ShortcutActivity2.class.getName(),
3479                     intents[0].getComponent().getClassName());
3480             assertEquals(Intent.ACTION_ASSIST,
3481                     intents[0].getAction());
3482             assertEquals(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK,
3483                     intents[0].getFlags());
3484 
3485             assertEquals("act2",
3486                     intents[1].getAction());
3487             assertEquals(Intent.FLAG_ACTIVITY_NO_ANIMATION,
3488                     intents[1].getFlags());
3489 
3490             assertEquals(
3491                     ShortcutActivity3.class.getName(),
3492                     launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_0)
3493                             .getComponent().getClassName());
3494             assertEquals(
3495                     ShortcutActivity.class.getName(),
3496                     launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_0)
3497                             .getComponent().getClassName());
3498 
3499             assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
3500 
3501             assertShortcutNotLaunched("no-such-package", "s2", USER_0);
3502             assertShortcutNotLaunched(CALLING_PACKAGE_1, "xxxx", USER_0);
3503         });
3504 
3505         // LAUNCHER_1 is no longer the default launcher
3506         setDefaultLauncherChecker((pkg, userId) -> false);
3507 
3508         runWithCaller(LAUNCHER_1, USER_0, () -> {
3509             // Not the default launcher, but pinned shortcuts are still lauchable.
3510             final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_0);
3511             assertEquals(ShortcutActivity2.class.getName(),
3512                     intents[0].getComponent().getClassName());
3513             assertEquals(Intent.ACTION_ASSIST,
3514                     intents[0].getAction());
3515             assertEquals(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK,
3516                     intents[0].getFlags());
3517 
3518             assertEquals("act2",
3519                     intents[1].getAction());
3520             assertEquals(Intent.FLAG_ACTIVITY_NO_ANIMATION,
3521                     intents[1].getFlags());
3522             assertEquals(
3523                     ShortcutActivity3.class.getName(),
3524                     launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_0)
3525                             .getComponent().getClassName());
3526             assertEquals(
3527                     ShortcutActivity.class.getName(),
3528                     launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_0)
3529                             .getComponent().getClassName());
3530 
3531             // Not pinned, so not lauchable.
3532         });
3533 
3534         // Test inner errors.
3535         runWithCaller(LAUNCHER_1, USER_0, () -> {
3536             // Not launchable.
3537             doReturn(ActivityManager.START_CLASS_NOT_FOUND)
3538                     .when(mMockActivityTaskManagerInternal).startActivitiesAsPackage(
3539                     anyStringOrNull(), anyStringOrNull(), anyInt(),
3540                     anyOrNull(Intent[].class), anyOrNull(Bundle.class));
3541             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
3542                     ActivityNotFoundException.class);
3543 
3544             // Still not launchable.
3545             doReturn(ActivityManager.START_CLASS_NOT_FOUND)
3546                     .when(mMockActivityTaskManagerInternal)
3547                     .startActivitiesAsPackage(
3548                             anyStringOrNull(), anyStringOrNull(), anyInt(),
3549                             anyOrNull(Intent[].class), anyOrNull(Bundle.class));
3550             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
3551                     ActivityNotFoundException.class);
3552         });
3553 
3554 
3555         // TODO Check extra, etc
3556     }
3557 
testLauncherCallback()3558     public void testLauncherCallback() throws Throwable {
3559         // Disable throttling for this test.
3560         mService.updateConfigurationLocked(
3561                 ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
3562                         + ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
3563         );
3564 
3565         setCaller(LAUNCHER_1, USER_0);
3566 
3567         assertForLauncherCallback(mLauncherApps, () -> {
3568             runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3569                 assertTrue(mManager.setDynamicShortcuts(list(
3570                         makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3571             });
3572         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
3573                 .haveIds("s1", "s2", "s3")
3574                 .areAllWithKeyFieldsOnly()
3575                 .areAllDynamic();
3576 
3577         // From different package.
3578         assertForLauncherCallback(mLauncherApps, () -> {
3579             runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
3580                 assertTrue(mManager.setDynamicShortcuts(list(
3581                         makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3582             });
3583         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_0)
3584                 .haveIds("s1", "s2", "s3")
3585                 .areAllWithKeyFieldsOnly()
3586                 .areAllDynamic();
3587 
3588         mRunningUsers.put(USER_10, true);
3589 
3590         // Different user, callback shouldn't be called.
3591         assertForLauncherCallback(mLauncherApps, () -> {
3592             runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3593                 assertTrue(mManager.setDynamicShortcuts(list(
3594                         makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3595             });
3596         }).assertNoCallbackCalled();
3597 
3598 
3599         // Test for addDynamicShortcuts.
3600         assertForLauncherCallback(mLauncherApps, () -> {
3601             runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3602                 assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s4"))));
3603             });
3604         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
3605                 .haveIds("s1", "s2", "s3", "s4")
3606                 .areAllWithKeyFieldsOnly()
3607                 .areAllDynamic();
3608 
3609         // Test for remove
3610         assertForLauncherCallback(mLauncherApps, () -> {
3611             runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3612                 mManager.removeDynamicShortcuts(list("s1"));
3613             });
3614         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
3615                 .haveIds("s2", "s3", "s4")
3616                 .areAllWithKeyFieldsOnly()
3617                 .areAllDynamic();
3618 
3619         // Test for update
3620         assertForLauncherCallback(mLauncherApps, () -> {
3621             runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3622                 assertTrue(mManager.updateShortcuts(list(
3623                         makeShortcut("s1"), makeShortcut("s2"))));
3624             });
3625         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
3626                 // All remaining shortcuts will be passed regardless of what's been updated.
3627                 .haveIds("s2", "s3", "s4")
3628                 .areAllWithKeyFieldsOnly()
3629                 .areAllDynamic();
3630 
3631         // Test for deleteAll
3632         assertForLauncherCallback(mLauncherApps, () -> {
3633             runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3634                 mManager.removeAllDynamicShortcuts();
3635             });
3636         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
3637                 .isEmpty();
3638 
3639         // Update package1 with manifest shortcuts
3640         assertForLauncherCallback(mLauncherApps, () -> {
3641             addManifestShortcutResource(
3642                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
3643                     R.xml.shortcut_2);
3644             updatePackageVersion(CALLING_PACKAGE_1, 1);
3645             mService.mPackageMonitor.onReceive(getTestContext(),
3646                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
3647         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
3648                 .areAllManifest()
3649                 .areAllWithKeyFieldsOnly()
3650                 .haveIds("ms1", "ms2");
3651 
3652         // Make sure pinned shortcuts are passed too.
3653         // 1. Add dynamic shortcuts.
3654         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
3655             assertTrue(mManager.setDynamicShortcuts(list(
3656                     makeShortcut("s1"), makeShortcut("s2"))));
3657         });
3658 
3659         // 2. Pin some.
3660         runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> {
3661             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_0);
3662         });
3663         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
3664             assertWith(getCallerShortcuts())
3665                     .haveIds("ms1", "ms2", "s1", "s2")
3666                     .areAllEnabled()
3667 
3668                     .selectByIds("ms1", "ms2")
3669                     .areAllManifest()
3670 
3671                     .revertToOriginalList()
3672                     .selectByIds("s1", "s2")
3673                     .areAllDynamic()
3674             ;
3675         });
3676 
3677         // 3 Update the app with no manifest shortcuts.  (Pinned one will survive.)
3678         addManifestShortcutResource(
3679                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
3680                 R.xml.shortcut_0);
3681         updatePackageVersion(CALLING_PACKAGE_1, 1);
3682         mService.mPackageMonitor.onReceive(getTestContext(),
3683                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
3684 
3685         assertForLauncherCallback(mLauncherApps, () -> {
3686             runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3687                 mManager.removeDynamicShortcuts(list("s2"));
3688 
3689                 assertWith(getCallerShortcuts())
3690                         .haveIds("ms2", "s1", "s2")
3691 
3692                         .selectByIds("ms2")
3693                         .areAllNotManifest()
3694                         .areAllPinned()
3695                         .areAllImmutable()
3696                         .areAllDisabled()
3697 
3698                         .revertToOriginalList()
3699                         .selectByIds("s1")
3700                         .areAllDynamic()
3701                         .areAllNotPinned()
3702                         .areAllEnabled()
3703 
3704                         .revertToOriginalList()
3705                         .selectByIds("s2")
3706                         .areAllNotDynamic()
3707                         .areAllPinned()
3708                         .areAllEnabled()
3709                 ;
3710             });
3711         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
3712                 .haveIds("ms2", "s1", "s2")
3713                 .areAllWithKeyFieldsOnly();
3714 
3715         // Remove CALLING_PACKAGE_2
3716         assertForLauncherCallback(mLauncherApps, () -> {
3717             uninstallPackage(USER_0, CALLING_PACKAGE_2);
3718             mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_0, USER_0,
3719                     /* appStillExists = */ false);
3720         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_0)
3721                 .isEmpty();
3722     }
3723 
testLauncherCallback_crossProfile()3724     public void testLauncherCallback_crossProfile() throws Throwable {
3725         prepareCrossProfileDataSet();
3726 
3727         final Handler h = new Handler(Looper.getMainLooper());
3728 
3729         final LauncherApps.Callback c0_1 = mock(LauncherApps.Callback.class);
3730         final LauncherApps.Callback c0_2 = mock(LauncherApps.Callback.class);
3731         final LauncherApps.Callback c0_3 = mock(LauncherApps.Callback.class);
3732         final LauncherApps.Callback c0_4 = mock(LauncherApps.Callback.class);
3733 
3734         final LauncherApps.Callback cP0_1 = mock(LauncherApps.Callback.class);
3735         final LauncherApps.Callback cP1_1 = mock(LauncherApps.Callback.class);
3736         final LauncherApps.Callback c10_1 = mock(LauncherApps.Callback.class);
3737         final LauncherApps.Callback c10_2 = mock(LauncherApps.Callback.class);
3738         final LauncherApps.Callback c11_1 = mock(LauncherApps.Callback.class);
3739 
3740         final List<LauncherApps.Callback> all =
3741                 list(c0_1, c0_2, c0_3, c0_4, cP0_1, c10_1, c11_1);
3742 
3743         setDefaultLauncherChecker((pkg, userId) -> {
3744             switch (userId) {
3745                 case USER_0:
3746                     return LAUNCHER_2.equals(pkg);
3747                 case USER_P0:
3748                     return LAUNCHER_1.equals(pkg);
3749                 case USER_P1:
3750                     return LAUNCHER_1.equals(pkg);
3751                 case USER_10:
3752                     return LAUNCHER_1.equals(pkg);
3753                 case USER_11:
3754                     return LAUNCHER_1.equals(pkg);
3755                 default:
3756                     return false;
3757             }
3758         });
3759 
3760         runWithCaller(LAUNCHER_1, USER_0, () -> mLauncherApps.registerCallback(c0_1, h));
3761         runWithCaller(LAUNCHER_2, USER_0, () -> mLauncherApps.registerCallback(c0_2, h));
3762         runWithCaller(LAUNCHER_3, USER_0, () -> mLauncherApps.registerCallback(c0_3, h));
3763         runWithCaller(LAUNCHER_4, USER_0, () -> mLauncherApps.registerCallback(c0_4, h));
3764         runWithCaller(LAUNCHER_1, USER_P0, () -> mLauncherApps.registerCallback(cP0_1, h));
3765         runWithCaller(LAUNCHER_1, USER_P1, () -> mLauncherApps.registerCallback(cP1_1, h));
3766         runWithCaller(LAUNCHER_1, USER_10, () -> mLauncherApps.registerCallback(c10_1, h));
3767         runWithCaller(LAUNCHER_2, USER_10, () -> mLauncherApps.registerCallback(c10_2, h));
3768         runWithCaller(LAUNCHER_1, USER_11, () -> mLauncherApps.registerCallback(c11_1, h));
3769 
3770         // User 0.
3771 
3772         resetAll(all);
3773         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3774             mManager.removeDynamicShortcuts(list());
3775         });
3776         waitOnMainThread();
3777 
3778         assertCallbackNotReceived(c0_1);
3779         assertCallbackNotReceived(c0_3);
3780         assertCallbackNotReceived(c0_4);
3781         assertCallbackNotReceived(c10_1);
3782         assertCallbackNotReceived(c10_2);
3783         assertCallbackNotReceived(c11_1);
3784         assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3");
3785         assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
3786         assertCallbackNotReceived(cP1_1);
3787 
3788         // User 0, different package.
3789 
3790         resetAll(all);
3791         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
3792             mManager.removeDynamicShortcuts(list());
3793         });
3794         waitOnMainThread();
3795 
3796         assertCallbackNotReceived(c0_1);
3797         assertCallbackNotReceived(c0_3);
3798         assertCallbackNotReceived(c0_4);
3799         assertCallbackNotReceived(c10_1);
3800         assertCallbackNotReceived(c10_2);
3801         assertCallbackNotReceived(c11_1);
3802         assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_3, "s1", "s2", "s3", "s4");
3803         assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_3,
3804                 "s1", "s2", "s3", "s4", "s5", "s6");
3805         assertCallbackNotReceived(cP1_1);
3806 
3807         // Work profile.
3808         resetAll(all);
3809         runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
3810             mManager.removeDynamicShortcuts(list());
3811         });
3812         waitOnMainThread();
3813 
3814         assertCallbackNotReceived(c0_1);
3815         assertCallbackNotReceived(c0_3);
3816         assertCallbackNotReceived(c0_4);
3817         assertCallbackNotReceived(c10_1);
3818         assertCallbackNotReceived(c10_2);
3819         assertCallbackNotReceived(c11_1);
3820         assertCallbackReceived(c0_2, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s5");
3821         assertCallbackReceived(cP0_1, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
3822         assertCallbackNotReceived(cP1_1);
3823 
3824         // Normal secondary user.
3825         mRunningUsers.put(USER_10, true);
3826 
3827         resetAll(all);
3828         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3829             mManager.removeDynamicShortcuts(list());
3830         });
3831         waitOnMainThread();
3832 
3833         assertCallbackNotReceived(c0_1);
3834         assertCallbackNotReceived(c0_2);
3835         assertCallbackNotReceived(c0_3);
3836         assertCallbackNotReceived(c0_4);
3837         assertCallbackNotReceived(cP0_1);
3838         assertCallbackNotReceived(c10_2);
3839         assertCallbackNotReceived(c11_1);
3840         assertCallbackReceived(c10_1, HANDLE_USER_10, CALLING_PACKAGE_1,
3841                 "x1", "x2", "x3", "x4", "x5");
3842         assertCallbackNotReceived(cP1_1);
3843     }
3844 
3845     // === Test for persisting ===
3846 
testSaveAndLoadUser_empty()3847     public void testSaveAndLoadUser_empty() {
3848         assertTrue(mManager.setDynamicShortcuts(list()));
3849 
3850         Log.i(TAG, "Saved state");
3851         dumpsysOnLogcat();
3852         dumpUserFile(0);
3853 
3854         // Restore.
3855         mService.saveDirtyInfo();
3856         initService();
3857 
3858         assertEquals(0, mManager.getDynamicShortcuts().size());
3859     }
3860 
3861     /**
3862      * Try save and load, also stop/start the user.
3863      */
testSaveAndLoadUser()3864     public void testSaveAndLoadUser() {
3865         // First, create some shortcuts and save.
3866         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
3867             final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
3868             final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
3869                     getTestContext().getResources(), R.drawable.icon2));
3870 
3871             final ShortcutInfo si1 = makeShortcut(
3872                     "s1",
3873                     "title1-1",
3874                     makeComponent(ShortcutActivity.class),
3875                     icon1,
3876                     makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
3877                             "key1", "val1", "nest", makeBundle("key", 123)),
3878                         /* weight */ 10);
3879 
3880             final ShortcutInfo si2 = makeShortcut(
3881                     "s2",
3882                     "title1-2",
3883                         /* activity */ null,
3884                     icon2,
3885                     makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
3886                         /* weight */ 12);
3887 
3888             assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
3889 
3890             assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
3891             assertEquals(2, mManager.getRemainingCallCount());
3892         });
3893         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
3894             final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_16x64);
3895             final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
3896                     getTestContext().getResources(), R.drawable.icon2));
3897 
3898             final ShortcutInfo si1 = makeShortcut(
3899                     "s1",
3900                     "title2-1",
3901                     makeComponent(ShortcutActivity.class),
3902                     icon1,
3903                     makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
3904                             "key1", "val1", "nest", makeBundle("key", 123)),
3905                         /* weight */ 10);
3906 
3907             final ShortcutInfo si2 = makeShortcut(
3908                     "s2",
3909                     "title2-2",
3910                         /* activity */ null,
3911                     icon2,
3912                     makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
3913                         /* weight */ 12);
3914 
3915             assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
3916 
3917             assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
3918             assertEquals(2, mManager.getRemainingCallCount());
3919         });
3920 
3921         mRunningUsers.put(USER_10, true);
3922 
3923         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3924             final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
3925             final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
3926                     getTestContext().getResources(), R.drawable.icon2));
3927 
3928             final ShortcutInfo si1 = makeShortcut(
3929                     "s1",
3930                     "title10-1-1",
3931                     makeComponent(ShortcutActivity.class),
3932                     icon1,
3933                     makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
3934                             "key1", "val1", "nest", makeBundle("key", 123)),
3935                         /* weight */ 10);
3936 
3937             final ShortcutInfo si2 = makeShortcut(
3938                     "s2",
3939                     "title10-1-2",
3940                         /* activity */ null,
3941                     icon2,
3942                     makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
3943                         /* weight */ 12);
3944 
3945             assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
3946 
3947             assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
3948             assertEquals(2, mManager.getRemainingCallCount());
3949         });
3950 
3951         // Restore.
3952         mService.saveDirtyInfo();
3953         initService();
3954 
3955         // Before the load, the map should be empty.
3956         assertEquals(0, mService.getShortcutsForTest().size());
3957 
3958         // this will pre-load the per-user info.
3959         mService.handleUnlockUser(UserHandle.USER_SYSTEM);
3960 
3961         // Now it's loaded.
3962         assertEquals(1, mService.getShortcutsForTest().size());
3963 
3964         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
3965             assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
3966                     mManager.getDynamicShortcuts()))), "s1", "s2");
3967             assertEquals(2, mManager.getRemainingCallCount());
3968 
3969             assertEquals("title1-1", getCallerShortcut("s1").getTitle());
3970             assertEquals("title1-2", getCallerShortcut("s2").getTitle());
3971         });
3972         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
3973             assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
3974                     mManager.getDynamicShortcuts()))), "s1", "s2");
3975             assertEquals(2, mManager.getRemainingCallCount());
3976 
3977             assertEquals("title2-1", getCallerShortcut("s1").getTitle());
3978             assertEquals("title2-2", getCallerShortcut("s2").getTitle());
3979         });
3980 
3981         // Start another user
3982         mService.handleUnlockUser(USER_10);
3983 
3984         // Now the size is 2.
3985         assertEquals(2, mService.getShortcutsForTest().size());
3986 
3987         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3988             assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
3989                     mManager.getDynamicShortcuts()))), "s1", "s2");
3990             assertEquals(2, mManager.getRemainingCallCount());
3991 
3992             assertEquals("title10-1-1", getCallerShortcut("s1").getTitle());
3993             assertEquals("title10-1-2", getCallerShortcut("s2").getTitle());
3994         });
3995 
3996         // Try stopping the user
3997         mService.handleStopUser(USER_10);
3998 
3999         // Now it's unloaded.
4000         assertEquals(1, mService.getShortcutsForTest().size());
4001 
4002         // TODO Check all other fields
4003     }
4004 
testCleanupPackage()4005     public void testCleanupPackage() {
4006         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4007             assertTrue(mManager.setDynamicShortcuts(list(
4008                     makeShortcut("s0_1"))));
4009         });
4010         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4011             assertTrue(mManager.setDynamicShortcuts(list(
4012                     makeShortcut("s0_2"))));
4013         });
4014         runWithCaller(LAUNCHER_1, USER_0, () -> {
4015             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
4016                     HANDLE_USER_0);
4017             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
4018                     HANDLE_USER_0);
4019         });
4020         runWithCaller(LAUNCHER_2, USER_0, () -> {
4021             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
4022                     HANDLE_USER_0);
4023             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
4024                     HANDLE_USER_0);
4025         });
4026 
4027         mRunningUsers.put(USER_10, true);
4028 
4029         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4030             assertTrue(mManager.setDynamicShortcuts(list(
4031                     makeShortcut("s10_1"))));
4032         });
4033         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
4034             assertTrue(mManager.setDynamicShortcuts(list(
4035                     makeShortcut("s10_2"))));
4036         });
4037         runWithCaller(LAUNCHER_1, USER_10, () -> {
4038             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
4039                     HANDLE_USER_10);
4040             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
4041                     HANDLE_USER_10);
4042         });
4043         runWithCaller(LAUNCHER_2, USER_10, () -> {
4044             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
4045                     HANDLE_USER_10);
4046             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
4047                     HANDLE_USER_10);
4048         });
4049 
4050         // Remove all dynamic shortcuts; now all shortcuts are just pinned.
4051         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4052             mManager.removeAllDynamicShortcuts();
4053         });
4054         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4055             mManager.removeAllDynamicShortcuts();
4056         });
4057         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4058             mManager.removeAllDynamicShortcuts();
4059         });
4060         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
4061             mManager.removeAllDynamicShortcuts();
4062         });
4063 
4064 
4065         final SparseArray<ShortcutUser> users = mService.getShortcutsForTest();
4066         assertEquals(2, users.size());
4067         assertEquals(USER_0, users.keyAt(0));
4068         assertEquals(USER_10, users.keyAt(1));
4069 
4070         final ShortcutUser user0 = users.get(USER_0);
4071         final ShortcutUser user10 = users.get(USER_10);
4072 
4073 
4074         // Check the registered packages.
4075         dumpsysOnLogcat();
4076         assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
4077                 hashSet(user0.getAllPackagesForTest().keySet()));
4078         assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
4079                 hashSet(user10.getAllPackagesForTest().keySet()));
4080         assertEquals(
4081                 set(PackageWithUser.of(USER_0, LAUNCHER_1),
4082                         PackageWithUser.of(USER_0, LAUNCHER_2)),
4083                 hashSet(user0.getAllLaunchersForTest().keySet()));
4084         assertEquals(
4085                 set(PackageWithUser.of(USER_10, LAUNCHER_1),
4086                         PackageWithUser.of(USER_10, LAUNCHER_2)),
4087                 hashSet(user10.getAllLaunchersForTest().keySet()));
4088         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
4089                 "s0_1", "s0_2");
4090         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
4091                 "s0_1", "s0_2");
4092         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
4093                 "s10_1", "s10_2");
4094         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
4095                 "s10_1", "s10_2");
4096         assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_0);
4097         assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
4098         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
4099         assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
4100 
4101         mService.saveDirtyInfo();
4102 
4103         // Nonexistent package.
4104         uninstallPackage(USER_0, "abc");
4105         mService.cleanUpPackageLocked("abc", USER_0, USER_0, /* appStillExists = */ false);
4106 
4107         // No changes.
4108         assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
4109                 hashSet(user0.getAllPackagesForTest().keySet()));
4110         assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
4111                 hashSet(user10.getAllPackagesForTest().keySet()));
4112         assertEquals(
4113                 set(PackageWithUser.of(USER_0, LAUNCHER_1),
4114                         PackageWithUser.of(USER_0, LAUNCHER_2)),
4115                 hashSet(user0.getAllLaunchersForTest().keySet()));
4116         assertEquals(
4117                 set(PackageWithUser.of(USER_10, LAUNCHER_1),
4118                         PackageWithUser.of(USER_10, LAUNCHER_2)),
4119                 hashSet(user10.getAllLaunchersForTest().keySet()));
4120         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
4121                 "s0_1", "s0_2");
4122         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
4123                 "s0_1", "s0_2");
4124         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
4125                 "s10_1", "s10_2");
4126         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
4127                 "s10_1", "s10_2");
4128         assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_0);
4129         assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
4130         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
4131         assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
4132 
4133         mService.saveDirtyInfo();
4134 
4135         // Remove a package.
4136         uninstallPackage(USER_0, CALLING_PACKAGE_1);
4137         mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0, USER_0,
4138                 /* appStillExists = */ false);
4139 
4140         assertEquals(set(CALLING_PACKAGE_2),
4141                 hashSet(user0.getAllPackagesForTest().keySet()));
4142         assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
4143                 hashSet(user10.getAllPackagesForTest().keySet()));
4144         assertEquals(
4145                 set(PackageWithUser.of(USER_0, LAUNCHER_1),
4146                         PackageWithUser.of(USER_0, LAUNCHER_2)),
4147                 hashSet(user0.getAllLaunchersForTest().keySet()));
4148         assertEquals(
4149                 set(PackageWithUser.of(USER_10, LAUNCHER_1),
4150                         PackageWithUser.of(USER_10, LAUNCHER_2)),
4151                 hashSet(user10.getAllLaunchersForTest().keySet()));
4152         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
4153                 "s0_2");
4154         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
4155                 "s0_2");
4156         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
4157                 "s10_1", "s10_2");
4158         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
4159                 "s10_1", "s10_2");
4160         assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
4161         assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
4162         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
4163         assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
4164 
4165         mService.saveDirtyInfo();
4166 
4167         // Remove a launcher.
4168         uninstallPackage(USER_10, LAUNCHER_1);
4169         mService.cleanUpPackageLocked(LAUNCHER_1, USER_10, USER_10, /* appStillExists = */ false);
4170 
4171         assertEquals(set(CALLING_PACKAGE_2),
4172                 hashSet(user0.getAllPackagesForTest().keySet()));
4173         assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
4174                 hashSet(user10.getAllPackagesForTest().keySet()));
4175         assertEquals(
4176                 set(PackageWithUser.of(USER_0, LAUNCHER_1),
4177                         PackageWithUser.of(USER_0, LAUNCHER_2)),
4178                 hashSet(user0.getAllLaunchersForTest().keySet()));
4179         assertEquals(
4180                 set(PackageWithUser.of(USER_10, LAUNCHER_2)),
4181                 hashSet(user10.getAllLaunchersForTest().keySet()));
4182         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
4183                 "s0_2");
4184         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
4185                 "s0_2");
4186         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
4187                 "s10_1", "s10_2");
4188         assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
4189         assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
4190         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
4191         assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
4192 
4193         mService.saveDirtyInfo();
4194 
4195         // Remove a package.
4196         uninstallPackage(USER_10, CALLING_PACKAGE_2);
4197         mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_10, USER_10,
4198                 /* appStillExists = */ false);
4199 
4200         assertEquals(set(CALLING_PACKAGE_2),
4201                 hashSet(user0.getAllPackagesForTest().keySet()));
4202         assertEquals(set(CALLING_PACKAGE_1),
4203                 hashSet(user10.getAllPackagesForTest().keySet()));
4204         assertEquals(
4205                 set(PackageWithUser.of(USER_0, LAUNCHER_1),
4206                         PackageWithUser.of(USER_0, LAUNCHER_2)),
4207                 hashSet(user0.getAllLaunchersForTest().keySet()));
4208         assertEquals(
4209                 set(PackageWithUser.of(USER_10, LAUNCHER_2)),
4210                 hashSet(user10.getAllLaunchersForTest().keySet()));
4211         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
4212                 "s0_2");
4213         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
4214                 "s0_2");
4215         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
4216                 "s10_1");
4217         assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
4218         assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
4219         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
4220         assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
4221 
4222         mService.saveDirtyInfo();
4223 
4224         // Remove the other launcher from user 10 too.
4225         uninstallPackage(USER_10, LAUNCHER_2);
4226         mService.cleanUpPackageLocked(LAUNCHER_2, USER_10, USER_10,
4227                 /* appStillExists = */ false);
4228 
4229         assertEquals(set(CALLING_PACKAGE_2),
4230                 hashSet(user0.getAllPackagesForTest().keySet()));
4231         assertEquals(set(CALLING_PACKAGE_1),
4232                 hashSet(user10.getAllPackagesForTest().keySet()));
4233         assertEquals(
4234                 set(PackageWithUser.of(USER_0, LAUNCHER_1),
4235                         PackageWithUser.of(USER_0, LAUNCHER_2)),
4236                 hashSet(user0.getAllLaunchersForTest().keySet()));
4237         assertEquals(
4238                 set(),
4239                 hashSet(user10.getAllLaunchersForTest().keySet()));
4240         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
4241                 "s0_2");
4242         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
4243                 "s0_2");
4244 
4245         // Note the pinned shortcuts on user-10 no longer referred, so they should both be removed.
4246         assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
4247         assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
4248         assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_10);
4249         assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
4250 
4251         mService.saveDirtyInfo();
4252 
4253         // More remove.
4254         uninstallPackage(USER_10, CALLING_PACKAGE_1);
4255         mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_10, USER_10,
4256                 /* appStillExists = */ false);
4257 
4258         assertEquals(set(CALLING_PACKAGE_2),
4259                 hashSet(user0.getAllPackagesForTest().keySet()));
4260         assertEquals(set(),
4261                 hashSet(user10.getAllPackagesForTest().keySet()));
4262         assertEquals(
4263                 set(PackageWithUser.of(USER_0, LAUNCHER_1),
4264                         PackageWithUser.of(USER_0, LAUNCHER_2)),
4265                 hashSet(user0.getAllLaunchersForTest().keySet()));
4266         assertEquals(set(),
4267                 hashSet(user10.getAllLaunchersForTest().keySet()));
4268         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
4269                 "s0_2");
4270         assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
4271                 "s0_2");
4272 
4273         // Note the pinned shortcuts on user-10 no longer referred, so they should both be removed.
4274         assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
4275         assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
4276         assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_10);
4277         assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
4278 
4279         mService.saveDirtyInfo();
4280     }
4281 
testCleanupPackage_republishManifests()4282     public void testCleanupPackage_republishManifests() {
4283         addManifestShortcutResource(
4284                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
4285                 R.xml.shortcut_2);
4286         updatePackageVersion(CALLING_PACKAGE_1, 1);
4287         mService.mPackageMonitor.onReceive(getTestContext(),
4288                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
4289 
4290         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4291             assertTrue(mManager.setDynamicShortcuts(list(
4292                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
4293         });
4294         runWithCaller(LAUNCHER_1, USER_0, () -> {
4295             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
4296                     list("s2", "s3", "ms1", "ms2"), HANDLE_USER_0);
4297         });
4298 
4299         // Remove ms2 from manifest.
4300         addManifestShortcutResource(
4301                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
4302                 R.xml.shortcut_1);
4303         updatePackageVersion(CALLING_PACKAGE_1, 1);
4304         mService.mPackageMonitor.onReceive(getTestContext(),
4305                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
4306 
4307         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4308             assertTrue(mManager.setDynamicShortcuts(list(
4309                     makeShortcut("s1"), makeShortcut("s2"))));
4310 
4311             // Make sure the shortcuts are in the intended state.
4312             assertWith(getCallerShortcuts())
4313                     .haveIds("ms1", "ms2", "s1", "s2", "s3")
4314 
4315                     .selectByIds("ms1")
4316                     .areAllManifest()
4317                     .areAllPinned()
4318 
4319                     .revertToOriginalList()
4320                     .selectByIds("ms2")
4321                     .areAllNotManifest()
4322                     .areAllPinned()
4323 
4324                     .revertToOriginalList()
4325                     .selectByIds("s1")
4326                     .areAllDynamic()
4327                     .areAllNotPinned()
4328 
4329                     .revertToOriginalList()
4330                     .selectByIds("s2")
4331                     .areAllDynamic()
4332                     .areAllPinned()
4333 
4334                     .revertToOriginalList()
4335                     .selectByIds("s3")
4336                     .areAllNotDynamic()
4337                     .areAllPinned();
4338         });
4339 
4340         // Clean up + re-publish manifests.
4341         mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0, USER_0,
4342                 /* appStillExists = */ true);
4343         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4344             assertWith(getCallerShortcuts())
4345                     .haveIds("ms1")
4346                     .areAllManifest();
4347         });
4348     }
4349 
testHandleGonePackage_crossProfile()4350     public void testHandleGonePackage_crossProfile() {
4351         // Create some shortcuts.
4352         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4353             assertTrue(mManager.setDynamicShortcuts(list(
4354                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
4355         });
4356         runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
4357             assertTrue(mManager.setDynamicShortcuts(list(
4358                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
4359         });
4360         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4361             assertTrue(mManager.setDynamicShortcuts(list(
4362                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
4363         });
4364 
4365         mRunningUsers.put(USER_10, true);
4366 
4367         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4368             assertTrue(mManager.setDynamicShortcuts(list(
4369                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
4370         });
4371 
4372         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4373         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4374         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4375 
4376         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4377         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4378         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4379 
4380         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4381         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4382         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4383 
4384         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4385         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4386         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4387 
4388         // Pin some.
4389 
4390         runWithCaller(LAUNCHER_1, USER_0, () -> {
4391             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
4392                     list("s1"), HANDLE_USER_0);
4393 
4394             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
4395                     list("s2"), UserHandle.of(USER_P0));
4396 
4397             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
4398                     list("s3"), HANDLE_USER_0);
4399         });
4400 
4401         runWithCaller(LAUNCHER_1, USER_P0, () -> {
4402             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
4403                     list("s2"), HANDLE_USER_0);
4404 
4405             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
4406                     list("s3"), UserHandle.of(USER_P0));
4407 
4408             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
4409                     list("s1"), HANDLE_USER_0);
4410         });
4411 
4412         runWithCaller(LAUNCHER_1, USER_10, () -> {
4413             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
4414                     list("s3"), HANDLE_USER_10);
4415         });
4416 
4417         // Check the state.
4418 
4419         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4420         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4421         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4422 
4423         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4424         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4425         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4426 
4427         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4428         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4429         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4430 
4431         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4432         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4433         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4434 
4435         // Make sure all the information is persisted.
4436         mService.saveDirtyInfo();
4437         initService();
4438         mService.handleUnlockUser(USER_0);
4439         mService.handleUnlockUser(USER_P0);
4440         mService.handleUnlockUser(USER_10);
4441 
4442         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4443         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4444         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4445 
4446         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4447         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4448         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4449 
4450         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4451         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4452         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4453 
4454         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4455         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4456         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4457 
4458         // Start uninstalling.
4459         uninstallPackage(USER_10, LAUNCHER_1);
4460         mService.checkPackageChanges(USER_10);
4461 
4462         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4463         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4464         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4465 
4466         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4467         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4468         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4469 
4470         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4471         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4472         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4473 
4474         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4475         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4476         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4477 
4478         // Uninstall.
4479         uninstallPackage(USER_10, CALLING_PACKAGE_1);
4480         mService.checkPackageChanges(USER_10);
4481 
4482         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4483         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4484         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4485 
4486         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4487         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4488         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4489 
4490         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4491         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4492         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4493 
4494         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4495         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4496         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4497 
4498         uninstallPackage(USER_P0, LAUNCHER_1);
4499         mService.checkPackageChanges(USER_0);
4500 
4501         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4502         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4503         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4504 
4505         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4506         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4507         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4508 
4509         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4510         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4511         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4512 
4513         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4514         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4515         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4516 
4517         mService.checkPackageChanges(USER_P0);
4518 
4519         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4520         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4521         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4522 
4523         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4524         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4525         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4526 
4527         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4528         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4529         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4530 
4531         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4532         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4533         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4534 
4535         uninstallPackage(USER_P0, CALLING_PACKAGE_1);
4536 
4537         mService.saveDirtyInfo();
4538         initService();
4539         mService.handleUnlockUser(USER_0);
4540         mService.handleUnlockUser(USER_P0);
4541         mService.handleUnlockUser(USER_10);
4542 
4543         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4544         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4545         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4546 
4547         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4548         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4549         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4550 
4551         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4552         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4553         assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4554 
4555         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4556         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4557         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4558 
4559         // Uninstall
4560         uninstallPackage(USER_0, LAUNCHER_1);
4561 
4562         mService.saveDirtyInfo();
4563         initService();
4564         mService.handleUnlockUser(USER_0);
4565         mService.handleUnlockUser(USER_P0);
4566         mService.handleUnlockUser(USER_10);
4567 
4568         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4569         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4570         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4571 
4572         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4573         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4574         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4575 
4576         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4577         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4578         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4579 
4580         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4581         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4582         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4583 
4584         uninstallPackage(USER_0, CALLING_PACKAGE_2);
4585 
4586         mService.saveDirtyInfo();
4587         initService();
4588         mService.handleUnlockUser(USER_0);
4589         mService.handleUnlockUser(USER_P0);
4590         mService.handleUnlockUser(USER_10);
4591 
4592         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
4593         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
4594         assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
4595 
4596         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
4597         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
4598         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
4599 
4600         assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
4601         assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
4602         assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
4603 
4604         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
4605         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
4606         assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
4607     }
4608 
checkCanRestoreTo(int expected, ShortcutPackageInfo spi, boolean anyVersionOk, int version, boolean nowBackupAllowed, String... signatures)4609     protected void checkCanRestoreTo(int expected, ShortcutPackageInfo spi,
4610             boolean anyVersionOk, int version, boolean nowBackupAllowed, String... signatures) {
4611         final PackageInfo pi = genPackage("dummy", /* uid */ 0, version, signatures);
4612         if (!nowBackupAllowed) {
4613             pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP;
4614         }
4615 
4616         doReturn(expected != DISABLED_REASON_SIGNATURE_MISMATCH).when(
4617                 mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class), anyString());
4618 
4619         assertEquals(expected, spi.canRestoreTo(mService, pi, anyVersionOk));
4620     }
4621 
testCanRestoreTo()4622     public void testCanRestoreTo() {
4623         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
4624         addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 10, "sig1", "sig2");
4625         addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 10, "sig1");
4626 
4627         updatePackageInfo(CALLING_PACKAGE_3,
4628                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
4629 
4630         final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackageForTest(
4631                 mService, CALLING_PACKAGE_1, USER_0);
4632         final ShortcutPackageInfo spi2 = ShortcutPackageInfo.generateForInstalledPackageForTest(
4633                 mService, CALLING_PACKAGE_2, USER_0);
4634         final ShortcutPackageInfo spi3 = ShortcutPackageInfo.generateForInstalledPackageForTest(
4635                 mService, CALLING_PACKAGE_3, USER_0);
4636 
4637         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "sig1");
4638         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "x", "sig1");
4639         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "sig1", "y");
4640         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "x", "sig1", "y");
4641         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 11, true, "sig1");
4642 
4643         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true/* empty */);
4644         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x");
4645         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x", "y");
4646         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x");
4647         checkCanRestoreTo(DISABLED_REASON_VERSION_LOWER, spi1, false, 9, true, "sig1");
4648 
4649         // Any version okay.
4650         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, true, 9, true, "sig1");
4651         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, true, 9, true, "sig1");
4652 
4653         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig1", "sig2");
4654         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig2", "sig1");
4655         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig1", "sig2");
4656         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig2", "sig1");
4657         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig1", "sig2", "y");
4658         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig2", "sig1", "y");
4659         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig1", "sig2", "y");
4660         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig2", "sig1", "y");
4661         checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 11, true, "x", "sig2", "sig1", "y");
4662 
4663         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4664                 spi2, false, 10, true, "sig1", "sig2x");
4665         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4666                 spi2, false, 10, true, "sig2", "sig1x");
4667         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4668                 spi2, false, 10, true, "x", "sig1x", "sig2");
4669         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4670                 spi2, false, 10, true, "x", "sig2x", "sig1");
4671         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4672                 spi2, false, 10, true, "sig1", "sig2x", "y");
4673         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4674                 spi2, false, 10, true, "sig2", "sig1x", "y");
4675         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4676                 spi2, false, 10, true, "x", "sig1x", "sig2", "y");
4677         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4678                 spi2, false, 10, true, "x", "sig2x", "sig1", "y");
4679         checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
4680                 spi2, false, 11, true, "x", "sig2x", "sig1", "y");
4681 
4682         checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi1, true, 10, false, "sig1");
4683         checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi3, true, 10, true, "sig1");
4684     }
4685 
testHandlePackageDelete()4686     public void testHandlePackageDelete() {
4687         checkHandlePackageDeleteInner((userId, packageName) -> {
4688             uninstallPackage(userId, packageName);
4689             mService.mPackageMonitor.onReceive(getTestContext(),
4690                     genPackageDeleteIntent(packageName, userId));
4691         });
4692     }
4693 
testHandlePackageDisable()4694     public void testHandlePackageDisable() {
4695         checkHandlePackageDeleteInner((userId, packageName) -> {
4696             disablePackage(userId, packageName);
4697             mService.mPackageMonitor.onReceive(getTestContext(),
4698                     genPackageChangedIntent(packageName, userId));
4699         });
4700     }
4701 
checkHandlePackageDeleteInner(BiConsumer<Integer, String> remover)4702     private void checkHandlePackageDeleteInner(BiConsumer<Integer, String> remover) {
4703         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
4704                 getTestContext().getResources(), R.drawable.black_32x32));
4705         setCaller(CALLING_PACKAGE_1, USER_0);
4706         assertTrue(mManager.addDynamicShortcuts(list(
4707                 makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
4708         )));
4709         // Also add a manifest shortcut, which should be removed too.
4710         addManifestShortcutResource(
4711                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
4712                 R.xml.shortcut_1);
4713         updatePackageVersion(CALLING_PACKAGE_1, 1);
4714         mService.mPackageMonitor.onReceive(getTestContext(),
4715                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
4716         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4717             assertWith(getCallerShortcuts())
4718                     .haveIds("s1", "s2", "ms1")
4719 
4720                     .selectManifest()
4721                     .haveIds("ms1");
4722         });
4723 
4724         setCaller(CALLING_PACKAGE_2, USER_0);
4725         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4726 
4727         setCaller(CALLING_PACKAGE_3, USER_0);
4728         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4729 
4730         mRunningUsers.put(USER_10, true);
4731 
4732         setCaller(CALLING_PACKAGE_1, USER_10);
4733         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4734 
4735         setCaller(CALLING_PACKAGE_2, USER_10);
4736         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4737 
4738         setCaller(CALLING_PACKAGE_3, USER_10);
4739         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4740 
4741         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4742         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4743         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4744         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4745         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4746         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4747 
4748         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4749         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4750         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4751         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4752         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4753         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4754 
4755         remover.accept(USER_0, CALLING_PACKAGE_1);
4756 
4757         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4758         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4759         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4760         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4761         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4762         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4763 
4764         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4765         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4766         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4767         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4768         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4769         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4770 
4771         mRunningUsers.put(USER_10, true);
4772 
4773         remover.accept(USER_10, CALLING_PACKAGE_2);
4774 
4775         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4776         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4777         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4778         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4779         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4780         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4781 
4782         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4783         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4784         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4785         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4786         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4787         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4788 
4789         mInjectedPackages.remove(CALLING_PACKAGE_1);
4790         mInjectedPackages.remove(CALLING_PACKAGE_3);
4791 
4792         mService.checkPackageChanges(USER_0);
4793 
4794         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4795         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4796         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));  // ---------------
4797         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4798         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4799         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4800 
4801         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4802         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4803         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4804         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4805         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4806         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4807 
4808         mService.checkPackageChanges(USER_10);
4809 
4810         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4811         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4812         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4813         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4814         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4815         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4816 
4817         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4818         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4819         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4820         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4821         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4822         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4823     }
4824 
4825     /** Almost ame as testHandlePackageDelete, except it doesn't uninstall packages. */
testHandlePackageClearData()4826     public void testHandlePackageClearData() {
4827         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
4828                 getTestContext().getResources(), R.drawable.black_32x32));
4829         setCaller(CALLING_PACKAGE_1, USER_0);
4830         assertTrue(mManager.addDynamicShortcuts(list(
4831                 makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
4832         )));
4833 
4834         setCaller(CALLING_PACKAGE_2, USER_0);
4835         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4836 
4837         setCaller(CALLING_PACKAGE_3, USER_0);
4838         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4839 
4840         mRunningUsers.put(USER_10, true);
4841 
4842         setCaller(CALLING_PACKAGE_1, USER_10);
4843         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4844 
4845         setCaller(CALLING_PACKAGE_2, USER_10);
4846         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4847 
4848         setCaller(CALLING_PACKAGE_3, USER_10);
4849         assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4850 
4851         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4852         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4853         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4854         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4855         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4856         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4857 
4858         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4859         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4860         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4861         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4862         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4863         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4864 
4865         mService.mPackageMonitor.onReceive(getTestContext(),
4866                 genPackageDataClear(CALLING_PACKAGE_1, USER_0));
4867 
4868         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4869         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4870         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4871         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4872         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4873         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4874 
4875         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4876         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4877         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4878         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4879         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4880         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4881 
4882         mRunningUsers.put(USER_10, true);
4883 
4884         mService.mPackageMonitor.onReceive(getTestContext(),
4885                 genPackageDataClear(CALLING_PACKAGE_2, USER_10));
4886 
4887         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4888         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4889         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4890         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4891         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4892         assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4893 
4894         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4895         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4896         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4897         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4898         assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4899         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4900     }
4901 
testHandlePackageClearData_manifestRepublished()4902     public void testHandlePackageClearData_manifestRepublished() {
4903 
4904         mRunningUsers.put(USER_10, true);
4905 
4906         // Add two manifests and two dynamics.
4907         addManifestShortcutResource(
4908                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
4909                 R.xml.shortcut_2);
4910         updatePackageVersion(CALLING_PACKAGE_1, 1);
4911         mService.mPackageMonitor.onReceive(getTestContext(),
4912                 genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
4913 
4914         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4915             assertTrue(mManager.addDynamicShortcuts(list(
4916                     makeShortcut("s1"), makeShortcut("s2"))));
4917         });
4918         runWithCaller(LAUNCHER_1, USER_10, () -> {
4919             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_10);
4920         });
4921 
4922         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4923             assertWith(getCallerShortcuts())
4924                     .haveIds("ms1", "ms2", "s1", "s2")
4925                     .areAllEnabled()
4926 
4927                     .selectPinned()
4928                     .haveIds("ms2", "s2");
4929         });
4930 
4931         // Clear data
4932         mService.mPackageMonitor.onReceive(getTestContext(),
4933                 genPackageDataClear(CALLING_PACKAGE_1, USER_10));
4934 
4935         // Only manifest shortcuts will remain, and are no longer pinned.
4936         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4937             assertWith(getCallerShortcuts())
4938                     .haveIds("ms1", "ms2")
4939                     .areAllEnabled()
4940                     .areAllNotPinned();
4941         });
4942     }
4943 
testHandlePackageUpdate()4944     public void testHandlePackageUpdate() throws Throwable {
4945         // Set up shortcuts and launchers.
4946 
4947         final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
4948         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
4949                 getTestContext().getResources(), R.drawable.black_32x32));
4950 
4951         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4952             assertTrue(mManager.setDynamicShortcuts(list(
4953                     makeShortcut("s1"),
4954                     makeShortcutWithIcon("s2", res32x32),
4955                     makeShortcutWithIcon("s3", res32x32),
4956                     makeShortcutWithIcon("s4", bmp32x32))));
4957         });
4958         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4959             assertTrue(mManager.setDynamicShortcuts(list(
4960                     makeShortcut("s1"),
4961                     makeShortcutWithIcon("s2", bmp32x32))));
4962         });
4963         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
4964             assertTrue(mManager.setDynamicShortcuts(list(
4965                     makeShortcutWithIcon("s1", res32x32))));
4966         });
4967 
4968         mRunningUsers.put(USER_10, true);
4969 
4970         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4971             assertTrue(mManager.setDynamicShortcuts(list(
4972                     makeShortcutWithIcon("s1", res32x32),
4973                     makeShortcutWithIcon("s2", res32x32))));
4974         });
4975         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
4976             assertTrue(mManager.setDynamicShortcuts(list(
4977                     makeShortcutWithIcon("s1", bmp32x32),
4978                     makeShortcutWithIcon("s2", bmp32x32))));
4979         });
4980 
4981         LauncherApps.Callback c0 = mock(LauncherApps.Callback.class);
4982         LauncherApps.Callback c10 = mock(LauncherApps.Callback.class);
4983 
4984         runWithCaller(LAUNCHER_1, USER_0, () -> {
4985             mLauncherApps.registerCallback(c0, new Handler(Looper.getMainLooper()));
4986         });
4987         runWithCaller(LAUNCHER_1, USER_10, () -> {
4988             mLauncherApps.registerCallback(c10, new Handler(Looper.getMainLooper()));
4989         });
4990 
4991         mInjectedCurrentTimeMillis = START_TIME + 100;
4992 
4993         ArgumentCaptor<List> shortcuts;
4994 
4995         // Update the version info for package 1.
4996         reset(c0);
4997         reset(c10);
4998         updatePackageVersion(CALLING_PACKAGE_1, 1);
4999 
5000         // Then send the broadcast, to only user-0.
5001         mService.mPackageMonitor.onReceive(getTestContext(),
5002                 genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
5003 
5004         waitOnMainThread();
5005 
5006         // User-0 should get the notification.
5007         shortcuts = ArgumentCaptor.forClass(List.class);
5008         verify(c0).onShortcutsChanged(
5009                 eq(CALLING_PACKAGE_1),
5010                 shortcuts.capture(),
5011                 eq(HANDLE_USER_0));
5012 
5013         // User-10 shouldn't yet get the notification.
5014         verify(c10, times(0)).onShortcutsChanged(
5015                 eq(CALLING_PACKAGE_1),
5016                 any(List.class),
5017                 any(UserHandle.class));
5018         assertShortcutIds(shortcuts.getValue(), "s1", "s2", "s3", "s4");
5019         assertEquals(START_TIME,
5020                 findShortcut(shortcuts.getValue(), "s1").getLastChangedTimestamp());
5021         assertEquals(START_TIME + 100,
5022                 findShortcut(shortcuts.getValue(), "s2").getLastChangedTimestamp());
5023         assertEquals(START_TIME + 100,
5024                 findShortcut(shortcuts.getValue(), "s3").getLastChangedTimestamp());
5025         assertEquals(START_TIME,
5026                 findShortcut(shortcuts.getValue(), "s4").getLastChangedTimestamp());
5027 
5028         // Next, send an unlock event on user-10.  Now we scan packages on this user and send a
5029         // notification to the launcher.
5030         mInjectedCurrentTimeMillis = START_TIME + 200;
5031 
5032         mRunningUsers.put(USER_10, true);
5033         mUnlockedUsers.put(USER_10, true);
5034 
5035         reset(c0);
5036         reset(c10);
5037         setPackageLastUpdateTime(CALLING_PACKAGE_1, mInjectedCurrentTimeMillis);
5038         mService.handleUnlockUser(USER_10);
5039         mService.checkPackageChanges(USER_10);
5040 
5041         waitOnMainThread();
5042 
5043         shortcuts = ArgumentCaptor.forClass(List.class);
5044         verify(c0, times(0)).onShortcutsChanged(
5045                 eq(CALLING_PACKAGE_1),
5046                 any(List.class),
5047                 any(UserHandle.class));
5048 
5049         verify(c10).onShortcutsChanged(
5050                 eq(CALLING_PACKAGE_1),
5051                 shortcuts.capture(),
5052                 eq(HANDLE_USER_10));
5053 
5054         assertShortcutIds(shortcuts.getValue(), "s1", "s2");
5055         assertEquals(START_TIME + 200,
5056                 findShortcut(shortcuts.getValue(), "s1").getLastChangedTimestamp());
5057         assertEquals(START_TIME + 200,
5058                 findShortcut(shortcuts.getValue(), "s2").getLastChangedTimestamp());
5059 
5060 
5061         // Do the same thing for package 2, which doesn't have resource icons.
5062         mInjectedCurrentTimeMillis = START_TIME + 300;
5063 
5064         reset(c0);
5065         reset(c10);
5066         updatePackageVersion(CALLING_PACKAGE_2, 10);
5067 
5068         // Then send the broadcast, to only user-0.
5069         mService.mPackageMonitor.onReceive(getTestContext(),
5070                 genPackageUpdateIntent(CALLING_PACKAGE_2, USER_0));
5071 
5072         waitOnMainThread();
5073 
5074         verify(c0, times(0)).onShortcutsChanged(
5075                 eq(CALLING_PACKAGE_1),
5076                 any(List.class),
5077                 any(UserHandle.class));
5078 
5079         verify(c10, times(0)).onShortcutsChanged(
5080                 eq(CALLING_PACKAGE_1),
5081                 any(List.class),
5082                 any(UserHandle.class));
5083 
5084         // Do the same thing for package 3
5085         mInjectedCurrentTimeMillis = START_TIME + 400;
5086 
5087         reset(c0);
5088         reset(c10);
5089         updatePackageVersion(CALLING_PACKAGE_3, 100);
5090 
5091         // Then send the broadcast, to only user-0.
5092         mService.mPackageMonitor.onReceive(getTestContext(),
5093                 genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0));
5094         mService.checkPackageChanges(USER_10);
5095 
5096         waitOnMainThread();
5097 
5098         shortcuts = ArgumentCaptor.forClass(List.class);
5099         verify(c0).onShortcutsChanged(
5100                 eq(CALLING_PACKAGE_3),
5101                 shortcuts.capture(),
5102                 eq(HANDLE_USER_0));
5103 
5104         // User 10 doesn't have package 3, so no callback.
5105         verify(c10, times(0)).onShortcutsChanged(
5106                 eq(CALLING_PACKAGE_3),
5107                 any(List.class),
5108                 any(UserHandle.class));
5109 
5110         assertShortcutIds(shortcuts.getValue(), "s1");
5111         assertEquals(START_TIME + 400,
5112                 findShortcut(shortcuts.getValue(), "s1").getLastChangedTimestamp());
5113     }
5114 
5115     /**
5116      * Test the case where an updated app has resource IDs changed.
5117      */
testHandlePackageUpdate_resIdChanged()5118     public void testHandlePackageUpdate_resIdChanged() throws Exception {
5119         final Icon icon1 = Icon.createWithResource(getTestContext(), /* res ID */ 1000);
5120         final Icon icon2 = Icon.createWithResource(getTestContext(), /* res ID */ 1001);
5121 
5122         // Set up shortcuts.
5123         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5124             // Note resource strings are not officially supported (they're hidden), but
5125             // should work.
5126 
5127             final ShortcutInfo s1 = new ShortcutInfo.Builder(mClientContext)
5128                     .setId("s1")
5129                     .setActivity(makeComponent(ShortcutActivity.class))
5130                     .setIntent(new Intent(Intent.ACTION_VIEW))
5131                     .setIcon(icon1)
5132                     .setTitleResId(10000)
5133                     .setTextResId(10001)
5134                     .setDisabledMessageResId(10002)
5135                     .build();
5136 
5137             final ShortcutInfo s2 = new ShortcutInfo.Builder(mClientContext)
5138                     .setId("s2")
5139                     .setActivity(makeComponent(ShortcutActivity.class))
5140                     .setIntent(new Intent(Intent.ACTION_VIEW))
5141                     .setIcon(icon2)
5142                     .setTitleResId(20000)
5143                     .build();
5144 
5145             assertTrue(mManager.setDynamicShortcuts(list(s1, s2)));
5146         });
5147 
5148         // Verify.
5149         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5150             final ShortcutInfo s1 = getCallerShortcut("s1");
5151             final ShortcutInfo s2 = getCallerShortcut("s2");
5152 
5153             assertEquals(1000, s1.getIconResourceId());
5154             assertEquals(10000, s1.getTitleResId());
5155             assertEquals(10001, s1.getTextResId());
5156             assertEquals(10002, s1.getDisabledMessageResourceId());
5157 
5158             assertEquals(1001, s2.getIconResourceId());
5159             assertEquals(20000, s2.getTitleResId());
5160             assertEquals(0, s2.getTextResId());
5161             assertEquals(0, s2.getDisabledMessageResourceId());
5162         });
5163 
5164         mService.saveDirtyInfo();
5165         initService();
5166 
5167         // Set up the mock resources again, with an "adjustment".
5168         // When the package is updated, the service will fetch the updated res-IDs with res-names,
5169         // and the new IDs will have this offset.
5170         setUpAppResources(10);
5171 
5172         // Update the package.
5173         updatePackageVersion(CALLING_PACKAGE_1, 1);
5174         mService.mPackageMonitor.onReceive(getTestContext(),
5175                 genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
5176 
5177         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5178             final ShortcutInfo s1 = getCallerShortcut("s1");
5179             final ShortcutInfo s2 = getCallerShortcut("s2");
5180 
5181             assertEquals(1010, s1.getIconResourceId());
5182             assertEquals(10010, s1.getTitleResId());
5183             assertEquals(10011, s1.getTextResId());
5184             assertEquals(10012, s1.getDisabledMessageResourceId());
5185 
5186             assertEquals(1011, s2.getIconResourceId());
5187             assertEquals(20010, s2.getTitleResId());
5188             assertEquals(0, s2.getTextResId());
5189             assertEquals(0, s2.getDisabledMessageResourceId());
5190         });
5191     }
5192 
testHandlePackageUpdate_systemAppUpdate()5193     public void testHandlePackageUpdate_systemAppUpdate() {
5194 
5195         // Package1 is a system app.  Package 2 is not a system app, so it's not scanned
5196         // in this test at all.
5197         mSystemPackages.add(CALLING_PACKAGE_1);
5198 
5199         // Initial state: no shortcuts.
5200         mService.checkPackageChanges(USER_0);
5201 
5202         assertEquals(mInjectedCurrentTimeMillis,
5203                 mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
5204         assertEquals(mInjectedBuildFingerprint,
5205                 mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
5206 
5207         // They have no shortcuts.
5208         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5209             assertWith(getCallerShortcuts())
5210                     .isEmpty();
5211         });
5212 
5213         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5214             assertWith(getCallerShortcuts())
5215                     .isEmpty();
5216         });
5217 
5218         // Next.
5219         // Update the packages -- now they have 1 manifest shortcut.
5220         // But checkPackageChanges() don't notice it, since their version code / timestamp haven't
5221         // changed.
5222         addManifestShortcutResource(
5223                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5224                 R.xml.shortcut_1);
5225         addManifestShortcutResource(
5226                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
5227                 R.xml.shortcut_1);
5228         mInjectedCurrentTimeMillis += 1000;
5229         mService.checkPackageChanges(USER_0);
5230 
5231         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5232             assertWith(getCallerShortcuts())
5233                     .isEmpty();
5234         });
5235         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5236             assertWith(getCallerShortcuts())
5237                     .isEmpty();
5238         });
5239 
5240         // Next.
5241         // Update the build finger print.  All apps will be scanned now.
5242         mInjectedBuildFingerprint = "update1";
5243         mInjectedCurrentTimeMillis += 1000;
5244         mService.checkPackageChanges(USER_0);
5245 
5246         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5247             assertWith(getCallerShortcuts())
5248                     .haveIds("ms1");
5249         });
5250         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5251             assertWith(getCallerShortcuts())
5252                     .haveIds("ms1");
5253         });
5254 
5255         // Next.
5256         // Update manifest shortcuts.
5257         addManifestShortcutResource(
5258                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5259                 R.xml.shortcut_2);
5260         addManifestShortcutResource(
5261                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
5262                 R.xml.shortcut_2);
5263         mInjectedCurrentTimeMillis += 1000;
5264         mService.checkPackageChanges(USER_0);
5265 
5266         // Fingerprint hasn't changed, so there packages weren't scanned.
5267         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5268             assertWith(getCallerShortcuts())
5269                     .haveIds("ms1");
5270         });
5271         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5272             assertWith(getCallerShortcuts())
5273                     .haveIds("ms1");
5274         });
5275 
5276         // Update the fingerprint.  CALLING_PACKAGE_1's version code hasn't changed, but we scan
5277         // all apps anyway.
5278         mInjectedBuildFingerprint = "update2";
5279         mInjectedCurrentTimeMillis += 1000;
5280         mService.checkPackageChanges(USER_0);
5281 
5282         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5283             assertWith(getCallerShortcuts())
5284                     .haveIds("ms1", "ms2");
5285         });
5286         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5287             assertWith(getCallerShortcuts())
5288                     .haveIds("ms1", "ms2");
5289         });
5290 
5291         // Make sure getLastAppScanTime / getLastAppScanOsFingerprint are persisted.
5292         initService();
5293         assertEquals(mInjectedCurrentTimeMillis,
5294                 mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
5295         assertEquals(mInjectedBuildFingerprint,
5296                 mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
5297     }
5298 
testHandlePackageChanged()5299     public void testHandlePackageChanged() {
5300         final ComponentName ACTIVITY1 = new ComponentName(CALLING_PACKAGE_1, "act1");
5301         final ComponentName ACTIVITY2 = new ComponentName(CALLING_PACKAGE_1, "act2");
5302 
5303         addManifestShortcutResource(ACTIVITY1, R.xml.shortcut_1);
5304         addManifestShortcutResource(ACTIVITY2, R.xml.shortcut_1_alt);
5305 
5306         mRunningUsers.put(USER_10, true);
5307 
5308         updatePackageVersion(CALLING_PACKAGE_1, 1);
5309         mService.mPackageMonitor.onReceive(getTestContext(),
5310                 genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
5311 
5312         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
5313             assertTrue(mManager.addDynamicShortcuts(list(
5314                     makeShortcutWithActivity("s1", ACTIVITY1),
5315                     makeShortcutWithActivity("s2", ACTIVITY2)
5316             )));
5317         });
5318         runWithCaller(LAUNCHER_1, USER_10, () -> {
5319             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1-alt", "s2"), HANDLE_USER_10);
5320         });
5321 
5322         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
5323             assertWith(getCallerShortcuts())
5324                     .haveIds("ms1", "ms1-alt", "s1", "s2")
5325                     .areAllEnabled()
5326 
5327                     .selectPinned()
5328                     .haveIds("ms1-alt", "s2")
5329 
5330                     .revertToOriginalList()
5331                     .selectByIds("ms1", "s1")
5332                     .areAllWithActivity(ACTIVITY1)
5333 
5334                     .revertToOriginalList()
5335                     .selectByIds("ms1-alt", "s2")
5336                     .areAllWithActivity(ACTIVITY2)
5337             ;
5338         });
5339 
5340         // First, no changes.
5341         mService.mPackageMonitor.onReceive(getTestContext(),
5342                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
5343 
5344         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
5345             assertWith(getCallerShortcuts())
5346                     .haveIds("ms1", "ms1-alt", "s1", "s2")
5347                     .areAllEnabled()
5348 
5349                     .selectPinned()
5350                     .haveIds("ms1-alt", "s2")
5351 
5352                     .revertToOriginalList()
5353                     .selectByIds("ms1", "s1")
5354                     .areAllWithActivity(ACTIVITY1)
5355 
5356                     .revertToOriginalList()
5357                     .selectByIds("ms1-alt", "s2")
5358                     .areAllWithActivity(ACTIVITY2)
5359             ;
5360         });
5361 
5362         // Disable activity 1
5363         mEnabledActivityChecker = (activity, userId) -> !ACTIVITY1.equals(activity);
5364         mService.mPackageMonitor.onReceive(getTestContext(),
5365                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
5366 
5367         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
5368             assertWith(getCallerShortcuts())
5369                     .haveIds("ms1-alt", "s2")
5370                     .areAllEnabled()
5371 
5372                     .selectPinned()
5373                     .haveIds("ms1-alt", "s2")
5374 
5375                     .revertToOriginalList()
5376                     .selectByIds("ms1-alt", "s2")
5377                     .areAllWithActivity(ACTIVITY2)
5378             ;
5379         });
5380 
5381         // Re-enable activity 1.
5382         // Manifest shortcuts will be re-published, but dynamic ones are not.
5383         mEnabledActivityChecker = (activity, userId) -> true;
5384         mService.mPackageMonitor.onReceive(getTestContext(),
5385                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
5386 
5387         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
5388             assertWith(getCallerShortcuts())
5389                     .haveIds("ms1", "ms1-alt", "s2")
5390                     .areAllEnabled()
5391 
5392                     .selectPinned()
5393                     .haveIds("ms1-alt", "s2")
5394 
5395                     .revertToOriginalList()
5396                     .selectByIds("ms1")
5397                     .areAllWithActivity(ACTIVITY1)
5398 
5399                     .revertToOriginalList()
5400                     .selectByIds("ms1-alt", "s2")
5401                     .areAllWithActivity(ACTIVITY2)
5402             ;
5403         });
5404 
5405         // Disable activity 2
5406         // Because "ms1-alt" and "s2" are both pinned, they will remain, but disabled.
5407         mEnabledActivityChecker = (activity, userId) -> !ACTIVITY2.equals(activity);
5408         mService.mPackageMonitor.onReceive(getTestContext(),
5409                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
5410 
5411         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
5412             assertWith(getCallerShortcuts())
5413                     .haveIds("ms1", "ms1-alt", "s2")
5414 
5415                     .selectDynamic().isEmpty().revertToOriginalList() // no dynamics.
5416 
5417                     .selectPinned()
5418                     .haveIds("ms1-alt", "s2")
5419                     .areAllDisabled()
5420 
5421                     .revertToOriginalList()
5422                     .selectByIds("ms1")
5423                     .areAllWithActivity(ACTIVITY1)
5424                     .areAllEnabled()
5425             ;
5426         });
5427     }
5428 
testHandlePackageUpdate_activityNoLongerMain()5429     public void testHandlePackageUpdate_activityNoLongerMain() throws Throwable {
5430         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5431             assertTrue(mManager.setDynamicShortcuts(list(
5432                     makeShortcutWithActivity("s1a",
5433                             new ComponentName(getCallingPackage(), "act1")),
5434                     makeShortcutWithActivity("s1b",
5435                             new ComponentName(getCallingPackage(), "act1")),
5436                     makeShortcutWithActivity("s2a",
5437                             new ComponentName(getCallingPackage(), "act2")),
5438                     makeShortcutWithActivity("s2b",
5439                             new ComponentName(getCallingPackage(), "act2")),
5440                     makeShortcutWithActivity("s3a",
5441                             new ComponentName(getCallingPackage(), "act3")),
5442                     makeShortcutWithActivity("s3b",
5443                             new ComponentName(getCallingPackage(), "act3"))
5444             )));
5445             assertWith(getCallerShortcuts())
5446                     .haveIds("s1a", "s1b", "s2a", "s2b", "s3a", "s3b")
5447                     .areAllDynamic();
5448         });
5449         runWithCaller(LAUNCHER_1, USER_0, () -> {
5450             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
5451                     list("s1b", "s2b", "s3b"),
5452                     HANDLE_USER_0);
5453         });
5454         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5455             assertWith(getCallerShortcuts())
5456                     .haveIds("s1a", "s1b", "s2a", "s2b", "s3a", "s3b")
5457                     .areAllDynamic()
5458 
5459                     .selectByIds("s1b", "s2b", "s3b")
5460                     .areAllPinned();
5461         });
5462 
5463         // Update the app and act2 and act3 are no longer main.
5464         mMainActivityChecker = (activity, userId) -> {
5465             return activity.getClassName().equals("act1");
5466         };
5467 
5468         setCaller(LAUNCHER_1, USER_0);
5469         assertForLauncherCallback(mLauncherApps, () -> {
5470             updatePackageVersion(CALLING_PACKAGE_1, 1);
5471             mService.mPackageMonitor.onReceive(getTestContext(),
5472                     genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
5473         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
5474                 // Make sure the launcher gets callbacks.
5475                 .haveIds("s1a", "s1b", "s2b", "s3b")
5476                 .areAllWithKeyFieldsOnly();
5477 
5478         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5479             // s2a and s3a are gone, but s2b and s3b will remain because they're pinned, and
5480             // disabled.
5481             assertWith(getCallerShortcuts())
5482                     .haveIds("s1a", "s1b", "s2b", "s3b")
5483 
5484                     .selectByIds("s1a", "s1b")
5485                     .areAllDynamic()
5486                     .areAllEnabled()
5487 
5488                     .revertToOriginalList()
5489                     .selectByIds("s2b", "s3b")
5490                     .areAllNotDynamic()
5491                     .areAllDisabled()
5492                     .areAllPinned()
5493             ;
5494         });
5495     }
5496 
prepareForBackupTest()5497     protected void prepareForBackupTest() {
5498         prepareCrossProfileDataSet();
5499 
5500         backupAndRestore();
5501     }
5502 
5503     /**
5504      * Make sure the backup data doesn't have the following information:
5505      * - Launchers on other users.
5506      * - Non-backup app information.
5507      *
5508      * But restores all other infomation.
5509      *
5510      * It also omits the following pieces of information, but that's tested in
5511      * {@link ShortcutManagerTest2#testShortcutInfoSaveAndLoad_forBackup}.
5512      * - Unpinned dynamic shortcuts
5513      * - Bitmaps
5514      */
testBackupAndRestore()5515     public void testBackupAndRestore() {
5516 
5517         assertFileNotExists("user-0/shortcut_dump/restore-0-start.txt");
5518         assertFileNotExists("user-0/shortcut_dump/restore-1-payload.xml");
5519         assertFileNotExists("user-0/shortcut_dump/restore-2.txt");
5520         assertFileNotExists("user-0/shortcut_dump/restore-3.txt");
5521         assertFileNotExists("user-0/shortcut_dump/restore-4.txt");
5522         assertFileNotExists("user-0/shortcut_dump/restore-5-finish.txt");
5523 
5524         prepareForBackupTest();
5525 
5526         assertFileExistsWithContent("user-0/shortcut_dump/restore-0-start.txt");
5527         assertFileExistsWithContent("user-0/shortcut_dump/restore-1-payload.xml");
5528         assertFileExistsWithContent("user-0/shortcut_dump/restore-2.txt");
5529         assertFileExistsWithContent("user-0/shortcut_dump/restore-3.txt");
5530         assertFileExistsWithContent("user-0/shortcut_dump/restore-4.txt");
5531         assertFileExistsWithContent("user-0/shortcut_dump/restore-5-finish.txt");
5532 
5533         checkBackupAndRestore_success(/*firstRestore=*/ true);
5534     }
5535 
testBackupAndRestore_backupRestoreTwice()5536     public void testBackupAndRestore_backupRestoreTwice() {
5537         prepareForBackupTest();
5538 
5539         checkBackupAndRestore_success(/*firstRestore=*/ true);
5540 
5541         // Run a backup&restore again. Note the shortcuts that weren't restored in the previous
5542         // restore are disabled, so they won't be restored again.
5543         dumpsysOnLogcat("Before second backup&restore");
5544 
5545         backupAndRestore();
5546 
5547         dumpsysOnLogcat("After second backup&restore");
5548 
5549         checkBackupAndRestore_success(/*firstRestore=*/ false);
5550     }
5551 
testBackupAndRestore_restoreToNewVersion()5552     public void testBackupAndRestore_restoreToNewVersion() {
5553         prepareForBackupTest();
5554 
5555         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 2);
5556         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 5);
5557 
5558         checkBackupAndRestore_success(/*firstRestore=*/ true);
5559     }
5560 
testBackupAndRestore_restoreToSuperSetSignatures()5561     public void testBackupAndRestore_restoreToSuperSetSignatures() {
5562         prepareForBackupTest();
5563 
5564         // Change package signatures.
5565         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1, "sigx", CALLING_PACKAGE_1);
5566         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4, LAUNCHER_1, "sigy");
5567 
5568         checkBackupAndRestore_success(/*firstRestore=*/ true);
5569     }
5570 
checkBackupAndRestore_success(boolean firstRestore)5571     protected void checkBackupAndRestore_success(boolean firstRestore) {
5572         // Make sure non-system user is not restored.
5573         final ShortcutUser userP0 = mService.getUserShortcutsLocked(USER_P0);
5574         assertEquals(0, userP0.getAllPackagesForTest().size());
5575         assertEquals(0, userP0.getAllLaunchersForTest().size());
5576 
5577         // Make sure only "allowBackup" apps are restored, and are shadow.
5578         final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
5579         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
5580         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
5581 
5582         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
5583         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
5584                 PackageWithUser.of(USER_0, LAUNCHER_1)));
5585         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
5586                 PackageWithUser.of(USER_0, LAUNCHER_2)));
5587 
5588         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_0, LAUNCHER_3)));
5589         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_P0, LAUNCHER_1)));
5590 
5591         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
5592                 anyString());
5593 
5594         installPackage(USER_0, CALLING_PACKAGE_1);
5595         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5596             assertWith(getCallerVisibleShortcuts())
5597                     .selectDynamic()
5598                     .isEmpty()
5599 
5600                     .revertToOriginalList()
5601                     .selectPinned()
5602                     .haveIds("s1", "s2")
5603                     .areAllEnabled();
5604         });
5605 
5606         installPackage(USER_0, LAUNCHER_1);
5607         runWithCaller(LAUNCHER_1, USER_0, () -> {
5608             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5609                     .areAllPinned()
5610                     .haveIds("s1")
5611                     .areAllEnabled();
5612 
5613             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5614                     .isEmpty();
5615 
5616             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5617                     .isEmpty();
5618 
5619             assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
5620                     .isEmpty();
5621         });
5622 
5623         installPackage(USER_0, CALLING_PACKAGE_2);
5624         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5625             assertWith(getCallerVisibleShortcuts())
5626                     .selectDynamic()
5627                     .isEmpty()
5628 
5629                     .revertToOriginalList()
5630                     .selectPinned()
5631                     .haveIds("s1", "s2", "s3")
5632                     .areAllEnabled();
5633         });
5634 
5635         runWithCaller(LAUNCHER_1, USER_0, () -> {
5636             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5637                     .areAllPinned()
5638                     .haveIds("s1")
5639                     .areAllEnabled();
5640 
5641             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5642                     .areAllPinned()
5643                     .haveIds("s1", "s2")
5644                     .areAllEnabled();
5645 
5646             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5647                     .isEmpty();
5648 
5649             assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
5650                     .isEmpty();
5651         });
5652 
5653         // 3 shouldn't be backed up, so no pinned shortcuts.
5654         installPackage(USER_0, CALLING_PACKAGE_3);
5655         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5656             assertWith(getCallerVisibleShortcuts())
5657                     .isEmpty();
5658         });
5659 
5660         // Launcher on a different profile shouldn't be restored.
5661         runWithCaller(LAUNCHER_1, USER_P0, () -> {
5662             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5663                     .isEmpty();
5664             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5665                     .isEmpty();
5666             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5667                     .isEmpty();
5668         });
5669 
5670         // Package on a different profile, no restore.
5671         installPackage(USER_P0, CALLING_PACKAGE_1);
5672         runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
5673             assertWith(getCallerVisibleShortcuts())
5674                     .isEmpty();
5675         });
5676 
5677         // Restore launcher 2 on user 0.
5678         installPackage(USER_0, LAUNCHER_2);
5679         runWithCaller(LAUNCHER_2, USER_0, () -> {
5680             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5681                     .areAllPinned()
5682                     .haveIds("s2")
5683                     .areAllEnabled();
5684 
5685             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5686                     .areAllPinned()
5687                     .haveIds("s2", "s3")
5688                     .areAllEnabled();
5689 
5690             if (firstRestore) {
5691                 assertWith(
5692                         mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5693                         .haveIds("s2", "s3", "s4")
5694                         .areAllDisabled()
5695                         .areAllPinned()
5696                         .areAllNotDynamic()
5697                         .areAllWithDisabledReason(
5698                                 ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5699             } else {
5700                 assertWith(
5701                         mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5702                         .isEmpty();
5703             }
5704 
5705             assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
5706                     .isEmpty();
5707         });
5708 
5709 
5710         // Restoration of launcher2 shouldn't affect other packages; so do the same checks and
5711         // make sure they still have the same result.
5712         installPackage(USER_0, CALLING_PACKAGE_1);
5713         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5714             assertWith(getCallerVisibleShortcuts())
5715                     .areAllPinned()
5716                     .haveIds("s1", "s2");
5717         });
5718 
5719         installPackage(USER_0, LAUNCHER_1);
5720         runWithCaller(LAUNCHER_1, USER_0, () -> {
5721             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5722                     .areAllPinned()
5723                     .haveIds("s1")
5724                     .areAllEnabled();
5725 
5726             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5727                     .areAllPinned()
5728                     .haveIds("s1", "s2")
5729                     .areAllEnabled();
5730 
5731             if (firstRestore) {
5732                 assertWith(
5733                         mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5734                         .haveIds("s1", "s2", "s3")
5735                         .areAllDisabled()
5736                         .areAllPinned()
5737                         .areAllNotDynamic()
5738                         .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5739             } else {
5740                 assertWith(
5741                         mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5742                         .isEmpty();
5743             }
5744 
5745             assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
5746                     .isEmpty();
5747         });
5748 
5749         installPackage(USER_0, CALLING_PACKAGE_2);
5750         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5751             assertWith(getCallerVisibleShortcuts())
5752                     .areAllPinned()
5753                     .haveIds("s1", "s2", "s3")
5754                     .areAllEnabled();
5755         });
5756     }
5757 
testBackupAndRestore_publisherLowerVersion()5758     public void testBackupAndRestore_publisherLowerVersion() {
5759         prepareForBackupTest();
5760 
5761         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 0); // Lower version
5762 
5763         checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_VERSION_LOWER);
5764     }
5765 
testBackupAndRestore_publisherWrongSignature()5766     public void testBackupAndRestore_publisherWrongSignature() {
5767         prepareForBackupTest();
5768 
5769         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sigx"); // different signature
5770 
5771         checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH);
5772     }
5773 
testBackupAndRestore_publisherNoLongerBackupTarget()5774     public void testBackupAndRestore_publisherNoLongerBackupTarget() {
5775         prepareForBackupTest();
5776 
5777         updatePackageInfo(CALLING_PACKAGE_1,
5778                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
5779 
5780         checkBackupAndRestore_publisherNotRestored(
5781                 ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5782     }
5783 
checkBackupAndRestore_publisherNotRestored( int package1DisabledReason)5784     protected void checkBackupAndRestore_publisherNotRestored(
5785             int package1DisabledReason) {
5786         doReturn(package1DisabledReason != ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH).when(
5787                 mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
5788                 eq(CALLING_PACKAGE_1));
5789 
5790         installPackage(USER_0, CALLING_PACKAGE_1);
5791         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5792             assertEquals(0, mManager.getDynamicShortcuts().size());
5793             assertEquals(0, mManager.getPinnedShortcuts().size());
5794         });
5795         assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
5796                 .getPackageInfo().isShadow());
5797 
5798         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
5799                 any(byte[].class), anyString());
5800 
5801         installPackage(USER_0, CALLING_PACKAGE_2);
5802         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5803             assertEquals(0, mManager.getDynamicShortcuts().size());
5804             assertShortcutIds(assertAllPinned(
5805                     mManager.getPinnedShortcuts()),
5806                     "s1", "s2", "s3");
5807         });
5808         assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, USER_0)
5809                 .getPackageInfo().isShadow());
5810 
5811         installPackage(USER_0, LAUNCHER_1);
5812         runWithCaller(LAUNCHER_1, USER_0, () -> {
5813             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5814                     .haveIds("s1")
5815                     .areAllPinned()
5816                     .areAllDisabled()
5817                     .areAllWithDisabledReason(package1DisabledReason)
5818                     .forAllShortcuts(si -> {
5819                         switch (package1DisabledReason) {
5820                             case ShortcutInfo.DISABLED_REASON_VERSION_LOWER:
5821                                 assertEquals("App version downgraded, or isn’t compatible"
5822                                         + " with this shortcut",
5823                                         si.getDisabledMessage());
5824                                 break;
5825                             case ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH:
5826                                 assertEquals(
5827                                         "Couldn\u2019t restore shortcut because of app"
5828                                         + " signature mismatch",
5829                                         si.getDisabledMessage());
5830                                 break;
5831                             case ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED:
5832                                 assertEquals(
5833                                         "Couldn\u2019t restore shortcut because app"
5834                                         + " doesn\u2019t support backup and restore",
5835                                         si.getDisabledMessage());
5836                                 break;
5837                             default:
5838                                 fail("Unhandled disabled reason: " + package1DisabledReason);
5839                         }
5840                     });
5841             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5842                     .haveIds("s1", "s2")
5843                     .areAllPinned()
5844                     .areAllEnabled();
5845             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5846                     .isEmpty();
5847         });
5848         installPackage(USER_0, LAUNCHER_2);
5849         runWithCaller(LAUNCHER_2, USER_0, () -> {
5850             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5851                     .haveIds("s2")
5852                     .areAllPinned()
5853                     .areAllDisabled()
5854                     .areAllWithDisabledReason(package1DisabledReason);
5855             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5856                     .haveIds("s2", "s3")
5857                     .areAllPinned()
5858                     .areAllEnabled();
5859             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5860                     .isEmpty();
5861         });
5862 
5863         installPackage(USER_0, CALLING_PACKAGE_3);
5864         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5865             assertEquals(0, mManager.getDynamicShortcuts().size());
5866             assertEquals(0, mManager.getPinnedShortcuts().size());
5867         });
5868 
5869         runWithCaller(LAUNCHER_1, USER_0, () -> {
5870             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5871                     .haveIds("s1")
5872                     .areAllPinned()
5873                     .areAllDisabled()
5874                     .areAllWithDisabledReason(package1DisabledReason);
5875             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5876                     .haveIds("s1", "s2")
5877                     .areAllPinned()
5878                     .areAllEnabled();
5879             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5880                     .haveIds("s1", "s2", "s3")
5881                     .areAllPinned()
5882                     .areAllDisabled()
5883                     .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5884         });
5885         runWithCaller(LAUNCHER_2, USER_0, () -> {
5886             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5887                     .haveIds("s2")
5888                     .areAllPinned()
5889                     .areAllDisabled()
5890                     .areAllWithDisabledReason(package1DisabledReason);
5891             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5892                     .haveIds("s2", "s3")
5893                     .areAllPinned()
5894                     .areAllEnabled();
5895             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5896                     .haveIds("s2", "s3", "s4")
5897                     .areAllPinned()
5898                     .areAllDisabled()
5899                     .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5900         });
5901     }
5902 
testBackupAndRestore_launcherLowerVersion()5903     public void testBackupAndRestore_launcherLowerVersion() {
5904         prepareForBackupTest();
5905 
5906         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 0); // Lower version
5907 
5908         // Note, we restore pinned shortcuts even if the launcher is of a lower version.
5909         checkBackupAndRestore_success(/*firstRestore=*/ true);
5910     }
5911 
testBackupAndRestore_launcherWrongSignature()5912     public void testBackupAndRestore_launcherWrongSignature() {
5913         prepareForBackupTest();
5914 
5915         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "sigx"); // different signature
5916 
5917         checkBackupAndRestore_launcherNotRestored(true);
5918     }
5919 
testBackupAndRestore_launcherNoLongerBackupTarget()5920     public void testBackupAndRestore_launcherNoLongerBackupTarget() {
5921         prepareForBackupTest();
5922 
5923         updatePackageInfo(LAUNCHER_1,
5924                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
5925 
5926         checkBackupAndRestore_launcherNotRestored(false);
5927     }
5928 
checkBackupAndRestore_launcherNotRestored(boolean differentSignatures)5929     protected void checkBackupAndRestore_launcherNotRestored(boolean differentSignatures) {
5930         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
5931                 any(byte[].class), anyString());
5932 
5933         installPackage(USER_0, CALLING_PACKAGE_1);
5934         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5935             assertEquals(0, mManager.getDynamicShortcuts().size());
5936 
5937             // s1 was pinned by launcher 1, which is not restored, yet, so we still see "s1" here.
5938             assertShortcutIds(assertAllPinned(
5939                     mManager.getPinnedShortcuts()),
5940                     "s1", "s2");
5941         });
5942 
5943         installPackage(USER_0, CALLING_PACKAGE_2);
5944         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5945             assertEquals(0, mManager.getDynamicShortcuts().size());
5946             assertShortcutIds(assertAllPinned(
5947                     mManager.getPinnedShortcuts()),
5948                     "s1", "s2", "s3");
5949         });
5950 
5951         doReturn(!differentSignatures).when(mMockPackageManagerInternal).isDataRestoreSafe(
5952                 any(byte[].class), eq(LAUNCHER_1));
5953 
5954         // Now we try to restore launcher 1.  Then we realize it's not restorable, so L1 has no pinned
5955         // shortcuts.
5956         installPackage(USER_0, LAUNCHER_1);
5957         runWithCaller(LAUNCHER_1, USER_0, () -> {
5958             assertShortcutIds(assertAllPinned(
5959                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5960                     /* empty */);
5961             assertShortcutIds(assertAllPinned(
5962                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5963                     /* empty */);
5964             assertShortcutIds(assertAllPinned(
5965                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5966                     /* empty */);
5967         });
5968         assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
5969                 .getPackageInfo().isShadow());
5970 
5971         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5972             assertEquals(0, mManager.getDynamicShortcuts().size());
5973 
5974             // Now CALLING_PACKAGE_1 realizes "s1" is no longer pinned.
5975             assertShortcutIds(assertAllPinned(
5976                     mManager.getPinnedShortcuts()),
5977                     "s2");
5978         });
5979 
5980         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
5981                 any(byte[].class), anyString());
5982 
5983         installPackage(USER_0, LAUNCHER_2);
5984         runWithCaller(LAUNCHER_2, USER_0, () -> {
5985             assertShortcutIds(assertAllPinned(
5986                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0)),
5987                     "s2");
5988             assertShortcutIds(assertAllPinned(
5989                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
5990                     "s2", "s3");
5991             assertShortcutIds(assertAllPinned(
5992                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5993                     /* empty */);
5994         });
5995         assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_2, USER_0)
5996                 .getPackageInfo().isShadow());
5997 
5998         installPackage(USER_0, CALLING_PACKAGE_3);
5999         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6000             assertEquals(0, mManager.getDynamicShortcuts().size());
6001             assertEquals(0, mManager.getPinnedShortcuts().size());
6002         });
6003 
6004         runWithCaller(LAUNCHER_1, USER_0, () -> {
6005             assertShortcutIds(assertAllPinned(
6006                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
6007                     /* empty */);
6008             assertShortcutIds(assertAllPinned(
6009                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
6010                     /* empty */);
6011             assertShortcutIds(assertAllPinned(
6012                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
6013                     /* empty */);
6014         });
6015         runWithCaller(LAUNCHER_2, USER_0, () -> {
6016             assertShortcutIds(assertAllPinned(
6017                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0)),
6018                     "s2");
6019             assertShortcutIds(assertAllPinned(
6020                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
6021                     "s2", "s3");
6022         });
6023     }
6024 
testBackupAndRestore_launcherAndPackageNoLongerBackupTarget()6025     public void testBackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
6026         prepareForBackupTest();
6027 
6028         updatePackageInfo(CALLING_PACKAGE_1,
6029                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
6030 
6031         updatePackageInfo(LAUNCHER_1,
6032                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
6033 
6034         checkBackupAndRestore_publisherAndLauncherNotRestored();
6035     }
6036 
checkBackupAndRestore_publisherAndLauncherNotRestored()6037     protected void checkBackupAndRestore_publisherAndLauncherNotRestored() {
6038         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
6039                 anyString());
6040         installPackage(USER_0, CALLING_PACKAGE_1);
6041         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6042             assertEquals(0, mManager.getDynamicShortcuts().size());
6043             assertEquals(0, mManager.getPinnedShortcuts().size());
6044         });
6045 
6046         installPackage(USER_0, CALLING_PACKAGE_2);
6047         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6048             assertEquals(0, mManager.getDynamicShortcuts().size());
6049             assertShortcutIds(assertAllPinned(
6050                     mManager.getPinnedShortcuts()),
6051                     "s1", "s2", "s3");
6052         });
6053 
6054         installPackage(USER_0, LAUNCHER_1);
6055         runWithCaller(LAUNCHER_1, USER_0, () -> {
6056             assertShortcutIds(assertAllPinned(
6057                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
6058                     /* empty */);
6059             assertShortcutIds(assertAllPinned(
6060                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
6061                     /* empty */);
6062             assertShortcutIds(assertAllPinned(
6063                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
6064                     /* empty */);
6065         });
6066         installPackage(USER_0, LAUNCHER_2);
6067         runWithCaller(LAUNCHER_2, USER_0, () -> {
6068             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
6069                     .areAllPinned()
6070                     .haveIds("s2")
6071                     .areAllDisabled();
6072             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
6073                     .areAllPinned()
6074                     .haveIds("s2", "s3");
6075             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
6076                     .isEmpty();
6077         });
6078 
6079         // Because launcher 1 wasn't restored, "s1" is no longer pinned.
6080         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6081             assertEquals(0, mManager.getDynamicShortcuts().size());
6082             assertShortcutIds(assertAllPinned(
6083                     mManager.getPinnedShortcuts()),
6084                     "s2", "s3");
6085         });
6086 
6087         installPackage(USER_0, CALLING_PACKAGE_3);
6088         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6089             assertEquals(0, mManager.getDynamicShortcuts().size());
6090             assertEquals(0, mManager.getPinnedShortcuts().size());
6091         });
6092 
6093         runWithCaller(LAUNCHER_1, USER_0, () -> {
6094             assertShortcutIds(assertAllPinned(
6095                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
6096                     /* empty */);
6097             assertShortcutIds(assertAllPinned(
6098                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
6099                     /* empty */);
6100             assertShortcutIds(assertAllPinned(
6101                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
6102                     /* empty */);
6103         });
6104         runWithCaller(LAUNCHER_2, USER_0, () -> {
6105             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
6106                     .areAllPinned()
6107                     .haveIds("s2")
6108                     .areAllDisabled();
6109             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
6110                     .areAllPinned()
6111                     .haveIds("s2", "s3");
6112             assertWith(
6113                     mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
6114                     .haveIds("s2", "s3", "s4")
6115                     .areAllDisabled()
6116                     .areAllPinned()
6117                     .areAllNotDynamic()
6118                     .areAllWithDisabledReason(
6119                             ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
6120         });
6121     }
6122 
testBackupAndRestore_disabled()6123     public void testBackupAndRestore_disabled() {
6124         prepareCrossProfileDataSet();
6125 
6126         // Before doing backup & restore, disable s1.
6127         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6128             mManager.disableShortcuts(list("s1"));
6129         });
6130 
6131         backupAndRestore();
6132 
6133         // Below is copied from checkBackupAndRestore_success.
6134 
6135         // Make sure non-system user is not restored.
6136         final ShortcutUser userP0 = mService.getUserShortcutsLocked(USER_P0);
6137         assertEquals(0, userP0.getAllPackagesForTest().size());
6138         assertEquals(0, userP0.getAllLaunchersForTest().size());
6139 
6140         // Make sure only "allowBackup" apps are restored, and are shadow.
6141         final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
6142         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
6143         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
6144         assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
6145         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
6146                 PackageWithUser.of(USER_0, LAUNCHER_1)));
6147         assertExistsAndShadow(user0.getAllLaunchersForTest().get(
6148                 PackageWithUser.of(USER_0, LAUNCHER_2)));
6149 
6150         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_0, LAUNCHER_3)));
6151         assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_P0, LAUNCHER_1)));
6152 
6153         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
6154                 anyString());
6155 
6156         installPackage(USER_0, CALLING_PACKAGE_1);
6157         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6158             assertWith(getCallerVisibleShortcuts())
6159                     .areAllEnabled() // disabled shortcuts shouldn't be restored.
6160 
6161                     .selectDynamic()
6162                     .isEmpty()
6163 
6164                     .revertToOriginalList()
6165                     .selectPinned()
6166                     // s1 is not restored.
6167                     .haveIds("s2");
6168         });
6169 
6170         installPackage(USER_0, LAUNCHER_1);
6171         runWithCaller(LAUNCHER_1, USER_0, () -> {
6172             // Note, s1 was pinned by launcher 1, but was disabled, so isn't restored.
6173             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
6174                     .isEmpty();
6175 
6176             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
6177                     .isEmpty();
6178 
6179             assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
6180                     .isEmpty();
6181 
6182             assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
6183                     .isEmpty();
6184         });
6185     }
6186 
6187 
testBackupAndRestore_manifestRePublished()6188     public void testBackupAndRestore_manifestRePublished() {
6189         // Publish two manifest shortcuts.
6190         addManifestShortcutResource(
6191                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6192                 R.xml.shortcut_2);
6193         updatePackageVersion(CALLING_PACKAGE_1, 1);
6194         mService.mPackageMonitor.onReceive(mServiceContext,
6195                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6196 
6197         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6198             assertTrue(mManager.setDynamicShortcuts(list(
6199                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
6200         });
6201 
6202         // Pin from launcher 1.
6203         runWithCaller(LAUNCHER_1, USER_0, () -> {
6204             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
6205                     list("ms1", "ms2", "s1", "s2"), HANDLE_USER_0);
6206         });
6207 
6208         // Update and now ms2 is gone -> disabled.
6209         addManifestShortcutResource(
6210                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6211                 R.xml.shortcut_1);
6212         updatePackageVersion(CALLING_PACKAGE_1, 1);
6213         mService.mPackageMonitor.onReceive(mServiceContext,
6214                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6215 
6216         // Make sure the manifest shortcuts have been published.
6217         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6218             assertWith(getCallerShortcuts())
6219                     .selectManifest()
6220                     .haveIds("ms1")
6221 
6222                     .revertToOriginalList()
6223                     .selectDynamic()
6224                     .haveIds("s1", "s2", "s3")
6225 
6226                     .revertToOriginalList()
6227                     .selectPinned()
6228                     .haveIds("ms1", "ms2", "s1", "s2")
6229 
6230                     .revertToOriginalList()
6231                     .selectByIds("ms1")
6232                     .areAllManifest()
6233                     .areAllEnabled()
6234 
6235                     .revertToOriginalList()
6236                     .selectByIds("ms2")
6237                     .areAllNotManifest()
6238                     .areAllDisabled();
6239         });
6240 
6241         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
6242                 any(byte[].class), anyString());
6243         backupAndRestore();
6244 
6245         // When re-installing the app, the manifest shortcut should be re-published.
6246         mService.mPackageMonitor.onReceive(mServiceContext,
6247                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6248         mService.mPackageMonitor.onReceive(mServiceContext,
6249                 genPackageAddIntent(LAUNCHER_1, USER_0));
6250 
6251         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6252             assertWith(getCallerVisibleShortcuts())
6253                     .selectPinned()
6254                     // ms2 was disabled, so not restored.
6255                     .haveIds("ms1", "s1", "s2")
6256                     .areAllEnabled()
6257 
6258                     .revertToOriginalList()
6259                     .selectByIds("ms1")
6260                     .areAllManifest()
6261 
6262                     .revertToOriginalList()
6263                     .selectByIds("s1", "s2")
6264                     .areAllNotDynamic()
6265             ;
6266         });
6267     }
6268 
6269     /**
6270      * It's the case with preintalled apps -- when applyRestore() is called, the system
6271      * apps are already installed, so manifest shortcuts need to be re-published.
6272      *
6273      * Also, when a restore target app is already installed, and
6274      * - if it has allowBackup=true, we'll restore normally, so all existing shortcuts will be
6275      * replaced. (but manifest shortcuts will be re-published anyway.)  We log a warning on
6276      * logcat.
6277      * - if it has allowBackup=false, we don't touch any of the existing shortcuts.
6278      */
testBackupAndRestore_appAlreadyInstalledWhenRestored()6279     public void testBackupAndRestore_appAlreadyInstalledWhenRestored() {
6280         // Pre-backup.  Same as testBackupAndRestore_manifestRePublished().
6281 
6282         // Publish two manifest shortcuts.
6283         addManifestShortcutResource(
6284                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6285                 R.xml.shortcut_2);
6286         updatePackageVersion(CALLING_PACKAGE_1, 1);
6287         mService.mPackageMonitor.onReceive(mServiceContext,
6288                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6289 
6290         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6291             assertTrue(mManager.setDynamicShortcuts(list(
6292                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
6293         });
6294 
6295         // Pin from launcher 1.
6296         runWithCaller(LAUNCHER_1, USER_0, () -> {
6297             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
6298                     list("ms1", "ms2", "s1", "s2"), HANDLE_USER_0);
6299         });
6300 
6301         // Update and now ms2 is gone -> disabled.
6302         addManifestShortcutResource(
6303                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6304                 R.xml.shortcut_1);
6305         updatePackageVersion(CALLING_PACKAGE_1, 1);
6306         mService.mPackageMonitor.onReceive(mServiceContext,
6307                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6308 
6309         // Set up shortcuts for package 3, which won't be backed up / restored.
6310         addManifestShortcutResource(
6311                 new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
6312                 R.xml.shortcut_1);
6313         updatePackageVersion(CALLING_PACKAGE_3, 1);
6314         mService.mPackageMonitor.onReceive(mServiceContext,
6315                 genPackageAddIntent(CALLING_PACKAGE_3, USER_0));
6316 
6317         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6318             assertTrue(getManager().setDynamicShortcuts(list(
6319                     makeShortcut("s1"))));
6320         });
6321 
6322         // Make sure the manifest shortcuts have been published.
6323         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6324             assertWith(getCallerShortcuts())
6325                     .selectManifest()
6326                     .haveIds("ms1")
6327 
6328                     .revertToOriginalList()
6329                     .selectDynamic()
6330                     .haveIds("s1", "s2", "s3")
6331 
6332                     .revertToOriginalList()
6333                     .selectPinned()
6334                     .haveIds("ms1", "ms2", "s1", "s2")
6335 
6336                     .revertToOriginalList()
6337                     .selectByIds("ms1")
6338                     .areAllManifest()
6339                     .areAllEnabled()
6340 
6341                     .revertToOriginalList()
6342                     .selectByIds("ms2")
6343                     .areAllNotManifest()
6344                     .areAllDisabled();
6345         });
6346 
6347         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6348             assertWith(getCallerShortcuts())
6349                     .haveIds("s1", "ms1");
6350         });
6351 
6352         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
6353                 anyString());
6354         // Backup and *without restarting the service, just call applyRestore()*.
6355         {
6356             int prevUid = mInjectedCallingUid;
6357             mInjectedCallingUid = Process.SYSTEM_UID; // Only system can call it.
6358 
6359             dumpsysOnLogcat("Before backup");
6360 
6361             final byte[] payload = mService.getBackupPayload(USER_0);
6362             if (ENABLE_DUMP) {
6363                 final String xml = new String(payload);
6364                 Log.v(TAG, "Backup payload:");
6365                 for (String line : xml.split("\n")) {
6366                     Log.v(TAG, line);
6367                 }
6368             }
6369             mService.applyRestore(payload, USER_0);
6370 
6371             dumpsysOnLogcat("After restore");
6372 
6373             mInjectedCallingUid = prevUid;
6374         }
6375 
6376         // The check is also the same as testBackupAndRestore_manifestRePublished().
6377         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6378             assertWith(getCallerVisibleShortcuts())
6379                     .selectPinned()
6380                     // ms2 was disabled, so not restored.
6381                     .haveIds("ms1", "s1", "s2")
6382                     .areAllEnabled()
6383 
6384                     .revertToOriginalList()
6385                     .selectByIds("ms1")
6386                     .areAllManifest()
6387 
6388                     .revertToOriginalList()
6389                     .selectByIds("s1", "s2")
6390                     .areAllNotDynamic()
6391             ;
6392         });
6393 
6394         // Package 3 still has the same shortcuts.
6395         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6396             assertWith(getCallerShortcuts())
6397                     .haveIds("s1", "ms1");
6398         });
6399     }
6400 
6401 
6402     /**
6403      * Restored to a lower version with no manifest shortcuts. All shortcuts are now invisible,
6404      * and all calls from the publisher should ignore them.
6405      */
testBackupAndRestore_disabledShortcutsAreIgnored()6406     public void testBackupAndRestore_disabledShortcutsAreIgnored() {
6407         // Publish two manifest shortcuts.
6408         addManifestShortcutResource(
6409                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6410                 R.xml.shortcut_5_altalt);
6411         updatePackageVersion(CALLING_PACKAGE_1, 1);
6412         mService.mPackageMonitor.onReceive(mServiceContext,
6413                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6414 
6415         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6416             assertTrue(mManager.setDynamicShortcuts(list(
6417                     makeShortcutWithShortLabel("s1", "original-title"),
6418                     makeShortcut("s2"), makeShortcut("s3"))));
6419         });
6420 
6421         // Pin from launcher 1.
6422         runWithCaller(LAUNCHER_1, USER_0, () -> {
6423             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
6424                     list("ms1", "ms2", "ms3", "ms4", "s1", "s2"), HANDLE_USER_0);
6425         });
6426 
6427         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
6428                 any(byte[].class), anyString());
6429 
6430         backupAndRestore();
6431 
6432         // Lower the version and remove the manifest shortcuts.
6433         addManifestShortcutResource(
6434                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6435                 R.xml.shortcut_0);
6436         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 0); // Lower version
6437 
6438         // When re-installing the app, the manifest shortcut should be re-published.
6439         mService.mPackageMonitor.onReceive(mServiceContext,
6440                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6441         mService.mPackageMonitor.onReceive(mServiceContext,
6442                 genPackageAddIntent(LAUNCHER_1, USER_0));
6443 
6444         // No shortcuts should be visible to the publisher.
6445         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6446             assertWith(getCallerVisibleShortcuts())
6447                     .isEmpty();
6448         });
6449 
6450         final Runnable checkAllDisabledForLauncher = () -> {
6451             runWithCaller(LAUNCHER_1, USER_0, () -> {
6452                 assertWith(getShortcutAsLauncher(USER_0))
6453                         .areAllPinned()
6454                         .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
6455                         .areAllDisabled()
6456                         .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_VERSION_LOWER)
6457 
6458                         .forShortcutWithId("s1", si -> {
6459                             assertEquals("original-title", si.getShortLabel());
6460                         })
6461                         .forShortcutWithId("ms1", si -> {
6462                             assertEquals("string-com.android.test.1-user:0-res:"
6463                                             + R.string.shortcut_title1 + "/en"
6464                                     , si.getShortLabel());
6465                         })
6466                         .forShortcutWithId("ms2", si -> {
6467                             assertEquals("string-com.android.test.1-user:0-res:"
6468                                             + R.string.shortcut_title2 + "/en"
6469                                     , si.getShortLabel());
6470                         })
6471                         .forShortcutWithId("ms3", si -> {
6472                             assertEquals("string-com.android.test.1-user:0-res:"
6473                                             + R.string.shortcut_title1 + "/en"
6474                                     , si.getShortLabel());
6475                             assertEquals("string-com.android.test.1-user:0-res:"
6476                                             + R.string.shortcut_title2 + "/en"
6477                                     , si.getLongLabel());
6478                         })
6479                         .forShortcutWithId("ms4", si -> {
6480                             assertEquals("string-com.android.test.1-user:0-res:"
6481                                             + R.string.shortcut_title2 + "/en"
6482                                     , si.getShortLabel());
6483                             assertEquals("string-com.android.test.1-user:0-res:"
6484                                             + R.string.shortcut_title2 + "/en"
6485                                     , si.getLongLabel());
6486                         });
6487             });
6488         };
6489 
6490         checkAllDisabledForLauncher.run();
6491 
6492         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6493 
6494             makeCallerForeground(); // CALLING_PACKAGE_1 is now in the foreground.
6495 
6496             // All changing API calls should be ignored.
6497 
6498             getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
6499             checkAllDisabledForLauncher.run();
6500 
6501             getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
6502             checkAllDisabledForLauncher.run();
6503 
6504             getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
6505             checkAllDisabledForLauncher.run();
6506 
6507             getManager().removeAllDynamicShortcuts();
6508             getManager().removeDynamicShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
6509             checkAllDisabledForLauncher.run();
6510 
6511             getManager().updateShortcuts(list(makeShortcutWithShortLabel("s1", "new-title")));
6512             checkAllDisabledForLauncher.run();
6513 
6514 
6515             // Add a shortcut -- even though ms1 was immutable, it will succeed.
6516             assertTrue(getManager().addDynamicShortcuts(list(
6517                     makeShortcutWithShortLabel("ms1", "original-title"))));
6518 
6519             runWithCaller(LAUNCHER_1, USER_0, () -> {
6520                 assertWith(getShortcutAsLauncher(USER_0))
6521                         .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
6522 
6523                         .selectByIds("ms1")
6524                         .areAllEnabled()
6525                         .areAllDynamic()
6526                         .areAllPinned()
6527                         .forAllShortcuts(si -> {
6528                             assertEquals("original-title", si.getShortLabel());
6529                         })
6530 
6531                         // The rest still exist and disabled.
6532                         .revertToOriginalList()
6533                         .selectByIds("ms2", "ms3", "ms4", "s1", "s2")
6534                         .areAllDisabled()
6535                         .areAllPinned()
6536                 ;
6537             });
6538 
6539             assertTrue(getManager().setDynamicShortcuts(list(
6540                     makeShortcutWithShortLabel("ms2", "new-title-2"))));
6541 
6542             runWithCaller(LAUNCHER_1, USER_0, () -> {
6543                 assertWith(getShortcutAsLauncher(USER_0))
6544                         .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
6545 
6546                         .selectByIds("ms1")
6547                         .areAllEnabled()
6548                         .areAllNotDynamic() // ms1 was not in the list, so no longer dynamic.
6549                         .areAllPinned()
6550                         .areAllMutable()
6551                         .forAllShortcuts(si -> {
6552                             assertEquals("original-title", si.getShortLabel());
6553                         })
6554 
6555                         .revertToOriginalList()
6556                         .selectByIds("ms2")
6557                         .areAllEnabled()
6558                         .areAllDynamic()
6559                         .areAllPinned()
6560                         .areAllMutable()
6561                         .forAllShortcuts(si -> {
6562                             assertEquals("new-title-2", si.getShortLabel());
6563                         })
6564 
6565                         // The rest still exist and disabled.
6566                         .revertToOriginalList()
6567                         .selectByIds("ms3", "ms4", "s1", "s2")
6568                         .areAllDisabled()
6569                         .areAllPinned()
6570                 ;
6571             });
6572 
6573             // Prepare for requestPinShortcut().
6574             setDefaultLauncher(USER_0, LAUNCHER_1);
6575             mPinConfirmActivityFetcher = (packageName, userId) ->
6576                     new ComponentName(packageName, PIN_CONFIRM_ACTIVITY_CLASS);
6577 
6578             mManager.requestPinShortcut(
6579                     makeShortcutWithShortLabel("ms3", "new-title-3"),
6580                     /*PendingIntent=*/ null);
6581 
6582             // Note this was pinned, so it'll be accepted right away.
6583             runWithCaller(LAUNCHER_1, USER_0, () -> {
6584                 assertWith(getShortcutAsLauncher(USER_0))
6585                         .selectByIds("ms3")
6586                         .areAllEnabled()
6587                         .areAllNotDynamic()
6588                         .areAllPinned()
6589                         .areAllMutable()
6590                         .forAllShortcuts(si -> {
6591                             assertEquals("new-title-3", si.getShortLabel());
6592                             // The new one replaces the old manifest shortcut, so the long label
6593                             // should be gone now.
6594                             assertNull(si.getLongLabel());
6595                         });
6596             });
6597 
6598             // Now, change the launcher to launcher2, and request pin again.
6599             setDefaultLauncher(USER_0, LAUNCHER_2);
6600 
6601             reset(mServiceContext);
6602 
6603             assertTrue(mManager.isRequestPinShortcutSupported());
6604             mManager.requestPinShortcut(
6605                     makeShortcutWithShortLabel("ms4", "new-title-4"),
6606                     /*PendingIntent=*/ null);
6607 
6608             // Initially there should be no pinned shortcuts for L2.
6609             runWithCaller(LAUNCHER_2, USER_0, () -> {
6610                 assertWith(getShortcutAsLauncher(USER_0))
6611                         .selectPinned()
6612                         .isEmpty();
6613 
6614                 final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
6615 
6616                 verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
6617 
6618                 assertEquals(LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT,
6619                         intent.getValue().getAction());
6620                 assertEquals(LAUNCHER_2, intent.getValue().getComponent().getPackageName());
6621 
6622                 // Check the request object.
6623                 final PinItemRequest request = mLauncherApps.getPinItemRequest(intent.getValue());
6624 
6625                 assertNotNull(request);
6626                 assertEquals(PinItemRequest.REQUEST_TYPE_SHORTCUT, request.getRequestType());
6627 
6628                 assertWith(request.getShortcutInfo())
6629                         .haveIds("ms4")
6630                         .areAllOrphan()
6631                         .forAllShortcuts(si -> {
6632                             assertEquals("new-title-4", si.getShortLabel());
6633                             // The new one replaces the old manifest shortcut, so the long label
6634                             // should be gone now.
6635                             assertNull(si.getLongLabel());
6636                         });
6637                 assertTrue(request.accept());
6638 
6639                 assertWith(getShortcutAsLauncher(USER_0))
6640                         .selectPinned()
6641                         .haveIds("ms4")
6642                         .areAllEnabled();
6643             });
6644         });
6645     }
6646 
6647     /**
6648      * Test for restoring the pre-P backup format.
6649      */
testBackupAndRestore_api27format()6650     public void testBackupAndRestore_api27format() throws Exception {
6651         final byte[] payload = readTestAsset("shortcut/shortcut_api27_backup.xml").getBytes();
6652 
6653         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "22222");
6654         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "11111");
6655 
6656         doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
6657                 any(byte[].class), anyString());
6658 
6659         runWithSystemUid(() -> mService.applyRestore(payload, USER_0));
6660 
6661         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6662             assertWith(getCallerShortcuts())
6663                     .areAllPinned()
6664                     .haveIds("s1")
6665                     .areAllEnabled();
6666         });
6667 
6668         runWithCaller(LAUNCHER_1, USER_0, () -> {
6669             assertWith(getShortcutAsLauncher(USER_0))
6670                     .areAllPinned()
6671                     .haveIds("s1")
6672                     .areAllEnabled();
6673         });
6674         // Make sure getBackupSourceVersionCode and isBackupSourceBackupAllowed
6675         // are correct. We didn't have them in the old format.
6676         assertEquals(8, mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
6677                 .getPackageInfo().getBackupSourceVersionCode());
6678         assertTrue(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
6679                 .getPackageInfo().isBackupSourceBackupAllowed());
6680 
6681         assertEquals(9, mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
6682                 .getPackageInfo().getBackupSourceVersionCode());
6683         assertTrue(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
6684                 .getPackageInfo().isBackupSourceBackupAllowed());
6685 
6686     }
6687 
testSaveAndLoad_crossProfile()6688     public void testSaveAndLoad_crossProfile() {
6689         prepareCrossProfileDataSet();
6690 
6691         dumpsysOnLogcat("Before save & load");
6692 
6693         mService.saveDirtyInfo();
6694         initService();
6695 
6696         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6697             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
6698                     "s1", "s2", "s3");
6699             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
6700                     "s1", "s2", "s3", "s4");
6701         });
6702         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6703             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
6704                     "s1", "s2", "s3");
6705             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
6706                     "s1", "s2", "s3", "s4", "s5");
6707         });
6708         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6709             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
6710                     "s1", "s2", "s3");
6711             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
6712                     "s1", "s2", "s3", "s4", "s5", "s6");
6713         });
6714         runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
6715             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts())
6716                     /* empty */);
6717             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts())
6718                     /* empty */);
6719         });
6720         runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
6721             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
6722                     "s1", "s2", "s3");
6723             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
6724                     "s1", "s2", "s3", "s4", "s5", "s6");
6725         });
6726         runWithCaller(CALLING_PACKAGE_2, USER_P0, () -> {
6727             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts())
6728                     /* empty */);
6729             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts())
6730                     /* empty */);
6731         });
6732         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
6733             assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
6734                     "x1", "x2", "x3");
6735             assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
6736                     "x4", "x5");
6737         });
6738         runWithCaller(LAUNCHER_1, USER_0, () -> {
6739             assertShortcutIds(
6740                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
6741                     "s1");
6742             assertShortcutIds(
6743                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
6744                     "s1", "s2");
6745             assertShortcutIds(
6746                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
6747                     "s1", "s2", "s3");
6748             assertShortcutIds(
6749                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
6750                     /* empty */);
6751             assertShortcutIds(
6752                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
6753                     "s1", "s4");
6754             assertShortcutIds(
6755                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
6756                     /* empty */);
6757             assertExpectException(
6758                     SecurityException.class, "", () -> {
6759                         mLauncherApps.getShortcuts(
6760                                 buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10);
6761                     });
6762         });
6763         runWithCaller(LAUNCHER_2, USER_0, () -> {
6764             assertShortcutIds(
6765                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
6766                     "s2");
6767             assertShortcutIds(
6768                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
6769                     "s2", "s3");
6770             assertShortcutIds(
6771                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
6772                     "s2", "s3", "s4");
6773             assertShortcutIds(
6774                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
6775                     /* empty */);
6776             assertShortcutIds(
6777                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
6778                     "s2", "s5");
6779             assertShortcutIds(
6780                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
6781                     /* empty */);
6782         });
6783         runWithCaller(LAUNCHER_3, USER_0, () -> {
6784             assertShortcutIds(
6785                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
6786                     "s3");
6787             assertShortcutIds(
6788                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
6789                     "s3", "s4");
6790             assertShortcutIds(
6791                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
6792                     "s3", "s4", "s5");
6793             assertShortcutIds(
6794                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
6795                     /* empty */);
6796             assertShortcutIds(
6797                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
6798                     "s3", "s6");
6799             assertShortcutIds(
6800                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
6801                     /* empty */);
6802         });
6803         runWithCaller(LAUNCHER_4, USER_0, () -> {
6804             assertShortcutIds(
6805                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0)
6806                     /* empty */);
6807             assertShortcutIds(
6808                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0)
6809                     /* empty */);
6810             assertShortcutIds(
6811                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0)
6812                     /* empty */);
6813             assertShortcutIds(
6814                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
6815                     /* empty */);
6816             assertShortcutIds(
6817                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0)
6818                     /* empty */);
6819             assertShortcutIds(
6820                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
6821                     /* empty */);
6822         });
6823         runWithCaller(LAUNCHER_1, USER_P0, () -> {
6824             assertShortcutIds(
6825                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
6826                     "s3", "s4");
6827             assertShortcutIds(
6828                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
6829                     "s3", "s4", "s5");
6830             assertShortcutIds(
6831                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
6832                     "s3", "s4", "s5", "s6");
6833             assertShortcutIds(
6834                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
6835                     "s1", "s4");
6836             assertExpectException(
6837                     SecurityException.class, "unrelated profile", () -> {
6838                         mLauncherApps.getShortcuts(
6839                                 buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10);
6840                     });
6841         });
6842         runWithCaller(LAUNCHER_1, USER_10, () -> {
6843             assertShortcutIds(
6844                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10),
6845                     "x4", "x5");
6846             assertShortcutIds(
6847                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10)
6848                     /* empty */);
6849             assertShortcutIds(
6850                     mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10)
6851                     /* empty */);
6852             assertExpectException(
6853                     SecurityException.class, "unrelated profile", () -> {
6854                         mLauncherApps.getShortcuts(
6855                                 buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0);
6856                     });
6857             assertExpectException(
6858                     SecurityException.class, "unrelated profile", () -> {
6859                         mLauncherApps.getShortcuts(
6860                                 buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_P0);
6861                     });
6862         });
6863         // Check the user-IDs.
6864         assertEquals(USER_0,
6865                 mService.getUserShortcutsLocked(USER_0).getPackageShortcuts(CALLING_PACKAGE_1)
6866                         .getOwnerUserId());
6867         assertEquals(USER_0,
6868                 mService.getUserShortcutsLocked(USER_0).getPackageShortcuts(CALLING_PACKAGE_1)
6869                         .getPackageUserId());
6870         assertEquals(USER_P0,
6871                 mService.getUserShortcutsLocked(USER_P0).getPackageShortcuts(CALLING_PACKAGE_1)
6872                         .getOwnerUserId());
6873         assertEquals(USER_P0,
6874                 mService.getUserShortcutsLocked(USER_P0).getPackageShortcuts(CALLING_PACKAGE_1)
6875                         .getPackageUserId());
6876 
6877         assertEquals(USER_0,
6878                 mService.getUserShortcutsLocked(USER_0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6879                         .getOwnerUserId());
6880         assertEquals(USER_0,
6881                 mService.getUserShortcutsLocked(USER_0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6882                         .getPackageUserId());
6883         assertEquals(USER_P0,
6884                 mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6885                         .getOwnerUserId());
6886         assertEquals(USER_0,
6887                 mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6888                         .getPackageUserId());
6889     }
6890 
testOnApplicationActive_permission()6891     public void testOnApplicationActive_permission() {
6892         assertExpectException(SecurityException.class, "Missing permission", () ->
6893                 mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0));
6894 
6895         // Has permission, now it should pass.
6896         mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
6897         mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
6898     }
6899 
testGetShareTargets_permission()6900     public void testGetShareTargets_permission() {
6901         IntentFilter filter = new IntentFilter();
6902 
6903         assertExpectException(SecurityException.class, "Missing permission", () ->
6904                 mManager.getShareTargets(filter));
6905 
6906         // Has permission, now it should pass.
6907         mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
6908         mManager.getShareTargets(filter);
6909     }
6910 
testHasShareTargets_permission()6911     public void testHasShareTargets_permission() {
6912         assertExpectException(SecurityException.class, "Missing permission", () ->
6913                 mManager.hasShareTargets(CALLING_PACKAGE_1));
6914 
6915         // Has permission, now it should pass.
6916         mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
6917         mManager.hasShareTargets(CALLING_PACKAGE_1);
6918     }
6919 
testisSharingShortcut_permission()6920     public void testisSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
6921         setCaller(LAUNCHER_1, USER_0);
6922 
6923         IntentFilter filter_any = new IntentFilter();
6924         filter_any.addDataType("*/*");
6925 
6926         assertExpectException(SecurityException.class, "Missing permission", () ->
6927                 mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
6928                         filter_any));
6929 
6930         // Has permission, now it should pass.
6931         mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
6932         mManager.hasShareTargets(CALLING_PACKAGE_1);
6933     }
6934 
testDumpsys_crossProfile()6935     public void testDumpsys_crossProfile() {
6936         prepareCrossProfileDataSet();
6937         dumpsysOnLogcat("test1", /* force= */ true);
6938     }
6939 
testDumpsys_withIcons()6940     public void testDumpsys_withIcons() throws IOException {
6941         testIcons();
6942         // Dump after having some icons.
6943         dumpsysOnLogcat("test1", /* force= */ true);
6944     }
6945 
testManifestShortcut_publishOnUnlockUser()6946     public void testManifestShortcut_publishOnUnlockUser() {
6947         addManifestShortcutResource(
6948                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6949                 R.xml.shortcut_1);
6950         addManifestShortcutResource(
6951                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
6952                 R.xml.shortcut_2);
6953         addManifestShortcutResource(
6954                 new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
6955                 R.xml.shortcut_5);
6956 
6957         // Unlock user-0.
6958         mInjectedCurrentTimeMillis += 100;
6959         mService.handleUnlockUser(USER_0);
6960 
6961         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6962             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6963                     mManager.getManifestShortcuts()))),
6964                     "ms1");
6965             assertEmpty(mManager.getPinnedShortcuts());
6966         });
6967 
6968         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6969             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6970                     mManager.getManifestShortcuts()))),
6971                     "ms1", "ms2");
6972             assertEmpty(mManager.getPinnedShortcuts());
6973         });
6974 
6975         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6976             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6977                     mManager.getManifestShortcuts()))),
6978                     "ms1", "ms2", "ms3", "ms4", "ms5");
6979             assertEmpty(mManager.getPinnedShortcuts());
6980         });
6981 
6982         // Try on another user, with some packages uninstalled.
6983         mRunningUsers.put(USER_10, true);
6984 
6985         uninstallPackage(USER_10, CALLING_PACKAGE_1);
6986         uninstallPackage(USER_10, CALLING_PACKAGE_3);
6987 
6988         mInjectedCurrentTimeMillis += 100;
6989         mService.handleUnlockUser(USER_10);
6990 
6991         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
6992             assertEmpty(mManager.getManifestShortcuts());
6993             assertEmpty(mManager.getPinnedShortcuts());
6994         });
6995 
6996         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
6997             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6998                     mManager.getManifestShortcuts()))),
6999                     "ms1", "ms2");
7000             assertEmpty(mManager.getPinnedShortcuts());
7001         });
7002 
7003         runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
7004             assertEmpty(mManager.getManifestShortcuts());
7005             assertEmpty(mManager.getPinnedShortcuts());
7006         });
7007 
7008         // Now change the resources for package 1, and unlock again.
7009         // But we still see *old* shortcuts, because the package version and install time
7010         // hasn't changed.
7011         shutdownServices();
7012 
7013         mInjectedCurrentTimeMillis += 100;
7014 
7015         addManifestShortcutResource(
7016                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7017                 R.xml.shortcut_5);
7018         addManifestShortcutResource(
7019                 new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
7020                 R.xml.shortcut_1);
7021 
7022         initService();
7023         mService.handleUnlockUser(USER_0);
7024 
7025         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7026             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( // FAIL
7027                     mManager.getManifestShortcuts()))),
7028                     "ms1");
7029             assertEmpty(mManager.getPinnedShortcuts());
7030         });
7031 
7032         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7033             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7034                     mManager.getManifestShortcuts()))),
7035                     "ms1", "ms2");
7036             assertEmpty(mManager.getPinnedShortcuts());
7037         });
7038 
7039         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
7040             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7041                     mManager.getManifestShortcuts()))),
7042                     "ms1", "ms2", "ms3", "ms4", "ms5");
7043             assertEmpty(mManager.getPinnedShortcuts());
7044         });
7045 
7046         // Do it again, but this time we change the app version, so we do detect the changes.
7047         shutdownServices();
7048 
7049         mInjectedCurrentTimeMillis += 100;
7050 
7051         updatePackageVersion(CALLING_PACKAGE_1, 1);
7052         updatePackageLastUpdateTime(CALLING_PACKAGE_3, 1);
7053 
7054         initService();
7055         mService.handleUnlockUser(USER_0);
7056 
7057         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7058             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7059                     mManager.getManifestShortcuts()))),
7060                     "ms1", "ms2", "ms3", "ms4", "ms5");
7061             assertEmpty(mManager.getPinnedShortcuts());
7062         });
7063 
7064         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7065             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7066                     mManager.getManifestShortcuts()))),
7067                     "ms1", "ms2");
7068             assertEmpty(mManager.getPinnedShortcuts());
7069         });
7070 
7071         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
7072             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7073                     mManager.getManifestShortcuts()))),
7074                     "ms1");
7075             assertEmpty(mManager.getPinnedShortcuts());
7076         });
7077 
7078         // Next, try removing all shortcuts, with some of them pinned.
7079         runWithCaller(LAUNCHER_1, USER_0, () -> {
7080             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms3"), HANDLE_USER_0);
7081             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2"), HANDLE_USER_0);
7082             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("ms1"), HANDLE_USER_0);
7083         });
7084         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7085             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7086                     mManager.getManifestShortcuts()))),
7087                     "ms1", "ms2", "ms3", "ms4", "ms5");
7088             assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllManifest(
7089                     assertAllEnabled(mManager.getPinnedShortcuts())))),
7090                     "ms3");
7091         });
7092 
7093         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7094             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7095                     mManager.getManifestShortcuts()))),
7096                     "ms1", "ms2");
7097             assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllManifest(
7098                     assertAllEnabled(mManager.getPinnedShortcuts())))),
7099                     "ms2");
7100         });
7101 
7102         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
7103             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7104                     mManager.getManifestShortcuts()))),
7105                     "ms1");
7106             assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllManifest(
7107                     assertAllEnabled(mManager.getPinnedShortcuts())))),
7108                     "ms1");
7109         });
7110 
7111         shutdownServices();
7112 
7113         mInjectedCurrentTimeMillis += 100;
7114 
7115         addManifestShortcutResource(
7116                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7117                 R.xml.shortcut_0);
7118         addManifestShortcutResource(
7119                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
7120                 R.xml.shortcut_1);
7121         addManifestShortcutResource(
7122                 new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
7123                 R.xml.shortcut_0);
7124 
7125         updatePackageVersion(CALLING_PACKAGE_1, 1);
7126         updatePackageVersion(CALLING_PACKAGE_2, 1);
7127         updatePackageVersion(CALLING_PACKAGE_3, 1);
7128 
7129         initService();
7130         mService.handleUnlockUser(USER_0);
7131 
7132         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7133             assertEmpty(mManager.getManifestShortcuts());
7134             assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
7135                     assertAllDisabled(mManager.getPinnedShortcuts())))),
7136                     "ms3");
7137         });
7138 
7139         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7140             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7141                     mManager.getManifestShortcuts()))),
7142                     "ms1");
7143             assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
7144                     assertAllDisabled(mManager.getPinnedShortcuts())))),
7145                     "ms2");
7146         });
7147 
7148         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
7149             assertEmpty(mManager.getManifestShortcuts());
7150             assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
7151                     assertAllDisabled(mManager.getPinnedShortcuts())))),
7152                     "ms1");
7153         });
7154 
7155         // Make sure we don't have ShortcutPackage for packages that don't have shortcuts.
7156         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_4, USER_0));
7157         assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_0));
7158     }
7159 
testManifestShortcut_publishOnBroadcast()7160     public void testManifestShortcut_publishOnBroadcast() {
7161         // First, no packages are installed.
7162         uninstallPackage(USER_0, CALLING_PACKAGE_1);
7163         uninstallPackage(USER_0, CALLING_PACKAGE_2);
7164         uninstallPackage(USER_0, CALLING_PACKAGE_3);
7165         uninstallPackage(USER_0, CALLING_PACKAGE_4);
7166         uninstallPackage(USER_10, CALLING_PACKAGE_1);
7167         uninstallPackage(USER_10, CALLING_PACKAGE_2);
7168         uninstallPackage(USER_10, CALLING_PACKAGE_3);
7169         uninstallPackage(USER_10, CALLING_PACKAGE_4);
7170 
7171         mService.handleUnlockUser(USER_0);
7172 
7173         mRunningUsers.put(USER_10, true);
7174         mService.handleUnlockUser(USER_10);
7175 
7176         // Originally no manifest shortcuts.
7177         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7178             assertEmpty(mManager.getManifestShortcuts());
7179             assertEmpty(mManager.getPinnedShortcuts());
7180         });
7181 
7182         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7183             assertEmpty(mManager.getManifestShortcuts());
7184             assertEmpty(mManager.getPinnedShortcuts());
7185         });
7186 
7187         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
7188             assertEmpty(mManager.getManifestShortcuts());
7189             assertEmpty(mManager.getPinnedShortcuts());
7190         });
7191 
7192         // Package 1 updated, with manifest shortcuts.
7193         addManifestShortcutResource(
7194                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7195                 R.xml.shortcut_1);
7196         updatePackageVersion(CALLING_PACKAGE_1, 1);
7197                 mService.mPackageMonitor.onReceive(getTestContext(),
7198                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7199 
7200         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7201             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7202                     mManager.getManifestShortcuts()))),
7203                     "ms1");
7204             assertEmpty(mManager.getPinnedShortcuts());
7205         });
7206 
7207         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7208             assertEmpty(mManager.getManifestShortcuts());
7209             assertEmpty(mManager.getPinnedShortcuts());
7210         });
7211 
7212         // Package 2 updated, with manifest shortcuts.
7213 
7214         addManifestShortcutResource(
7215                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
7216                 R.xml.shortcut_5_altalt);
7217         updatePackageVersion(CALLING_PACKAGE_2, 1);
7218                 mService.mPackageMonitor.onReceive(getTestContext(),
7219                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
7220 
7221         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7222             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7223                     mManager.getManifestShortcuts()))),
7224                     "ms1");
7225             assertEmpty(mManager.getPinnedShortcuts());
7226         });
7227 
7228         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7229             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7230                     mManager.getManifestShortcuts()))),
7231                     "ms1", "ms2", "ms3", "ms4", "ms5");
7232             assertWith(getCallerShortcuts()).selectManifest()
7233                     .selectByActivity(
7234                             new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
7235                     .haveRanksInOrder("ms1", "ms2", "ms3", "ms4", "ms5");
7236             assertEmpty(mManager.getPinnedShortcuts());
7237         });
7238 
7239         // Package 2 updated, with less manifest shortcuts.
7240         // This time we use updatePackageLastUpdateTime() instead of updatePackageVersion().
7241 
7242         dumpsysOnLogcat("Before pinning");
7243 
7244         // Also pin some.
7245         runWithCaller(LAUNCHER_1, USER_0, () -> {
7246             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2", "ms3"), HANDLE_USER_0);
7247         });
7248 
7249         dumpsysOnLogcat("After pinning");
7250 
7251         addManifestShortcutResource(
7252                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
7253                 R.xml.shortcut_2);
7254         updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
7255                 mService.mPackageMonitor.onReceive(getTestContext(),
7256                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
7257 
7258         dumpsysOnLogcat("After updating package 2");
7259 
7260         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7261             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7262                     mManager.getManifestShortcuts()))),
7263                     "ms1");
7264             assertEmpty(mManager.getPinnedShortcuts());
7265         });
7266 
7267         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7268             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7269                     mManager.getManifestShortcuts()))),
7270                     "ms1", "ms2");
7271             assertWith(getCallerShortcuts()).selectManifest()
7272                     .selectByActivity(
7273                             new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
7274                     .haveRanksInOrder("ms1", "ms2");
7275             assertShortcutIds(assertAllImmutable(assertAllPinned(
7276                     mManager.getPinnedShortcuts())),
7277                     "ms2", "ms3");
7278             // ms3 is no longer in manifest, so should be disabled.
7279             // but ms1 and ms2 should be enabled.
7280             assertWith(getCallerShortcuts())
7281                     .selectByIds("ms1", "ms2")
7282                     .areAllEnabled()
7283 
7284                     .revertToOriginalList()
7285                     .selectByIds("ms3")
7286                     .areAllDisabled()
7287                     .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_APP_CHANGED);
7288         });
7289 
7290         // Make sure the launcher see the correct disabled reason.
7291         runWithCaller(LAUNCHER_1, USER_0, () -> {
7292             assertWith(getShortcutAsLauncher(USER_0))
7293                     .forShortcutWithId("ms3", si -> {
7294                         assertEquals("string-com.android.test.2-user:0-res:"
7295                                         + R.string.shortcut_disabled_message3 + "/en",
7296                                 si.getDisabledMessage());
7297                     });
7298         });
7299 
7300 
7301         // Package 2 on user 10 has no shortcuts yet.
7302         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
7303             assertEmpty(mManager.getManifestShortcuts());
7304             assertEmpty(mManager.getPinnedShortcuts());
7305         });
7306         // Send add broadcast, but the user is not running, so should be ignored.
7307         mService.handleStopUser(USER_10);
7308         mRunningUsers.put(USER_10, false);
7309         mUnlockedUsers.put(USER_10, false);
7310 
7311         mService.mPackageMonitor.onReceive(getTestContext(),
7312                 genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
7313         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
7314             // Don't use the mManager APIs to get shortcuts, because they'll trigger the package
7315             // update check.
7316             // So look the internal data directly using getCallerShortcuts().
7317             assertEmpty(getCallerShortcuts());
7318         });
7319 
7320         // Try again, but the user is locked, so still ignored.
7321         mRunningUsers.put(USER_10, true);
7322                 mService.mPackageMonitor.onReceive(getTestContext(),
7323                 genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
7324         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
7325             // Don't use the mManager APIs to get shortcuts, because they'll trigger the package
7326             // update check.
7327             // So look the internal data directly using getCallerShortcuts().
7328             assertEmpty(getCallerShortcuts());
7329         });
7330 
7331         // Unlock the user, now it should work.
7332         mUnlockedUsers.put(USER_10, true);
7333 
7334         // Send PACKAGE_ADD broadcast to have Package 2 on user-10 publish manifest shortcuts.
7335                 mService.mPackageMonitor.onReceive(getTestContext(),
7336                 genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
7337 
7338         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
7339             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7340                     mManager.getManifestShortcuts()))),
7341                     "ms1", "ms2");
7342             assertWith(getCallerShortcuts()).selectManifest()
7343                     .selectByActivity(
7344                             new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
7345                     .haveRanksInOrder("ms1", "ms2");
7346             assertEmpty(mManager.getPinnedShortcuts());
7347         });
7348 
7349         // But it shouldn't affect user-0.
7350         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7351             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7352                     mManager.getManifestShortcuts()))),
7353                     "ms1", "ms2");
7354             assertWith(getCallerShortcuts()).selectManifest()
7355                     .selectByActivity(
7356                             new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
7357                     .haveRanksInOrder("ms1", "ms2");
7358             assertShortcutIds(assertAllImmutable(assertAllPinned(
7359                     mManager.getPinnedShortcuts())),
7360                     "ms2", "ms3");
7361             assertAllEnabled(list(getCallerShortcut("ms1")));
7362             assertAllEnabled(list(getCallerShortcut("ms2")));
7363             assertAllDisabled(list(getCallerShortcut("ms3")));
7364         });
7365 
7366         // Multiple activities.
7367         // Add shortcuts on activity 2 for package 2.
7368         addManifestShortcutResource(
7369                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
7370                 R.xml.shortcut_5_alt);
7371         addManifestShortcutResource(
7372                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()),
7373                 R.xml.shortcut_5_reverse);
7374 
7375         updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
7376                 mService.mPackageMonitor.onReceive(getTestContext(),
7377                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
7378 
7379         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7380             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7381                     mManager.getManifestShortcuts()))),
7382                     "ms1", "ms2", "ms3", "ms4", "ms5",
7383                     "ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
7384 
7385             // Make sure they have the correct ranks, regardless of their ID's alphabetical order.
7386             assertWith(getCallerShortcuts()).selectManifest()
7387                     .selectByActivity(
7388                             new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
7389                     .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
7390             assertWith(getCallerShortcuts()).selectManifest()
7391                     .selectByActivity(
7392                             new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()))
7393                     .haveRanksInOrder("ms5", "ms4", "ms3", "ms2", "ms1");
7394         });
7395 
7396         // Package 2 now has no manifest shortcuts.
7397         addManifestShortcutResource(
7398                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
7399                 R.xml.shortcut_0);
7400         addManifestShortcutResource(
7401                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()),
7402                 R.xml.shortcut_0);
7403         updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
7404                 mService.mPackageMonitor.onReceive(getTestContext(),
7405                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
7406 
7407         // No manifest shortcuts, and pinned ones are disabled.
7408         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
7409             assertEmpty(mManager.getManifestShortcuts());
7410             assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllDisabled(
7411                     mManager.getPinnedShortcuts()))),
7412                     "ms2", "ms3");
7413         });
7414     }
7415 
testManifestShortcuts_missingMandatoryFields()7416     public void testManifestShortcuts_missingMandatoryFields() {
7417         // Start with no apps installed.
7418         uninstallPackage(USER_0, CALLING_PACKAGE_1);
7419         uninstallPackage(USER_0, CALLING_PACKAGE_2);
7420         uninstallPackage(USER_0, CALLING_PACKAGE_3);
7421         uninstallPackage(USER_0, CALLING_PACKAGE_4);
7422 
7423         mService.handleUnlockUser(USER_0);
7424 
7425         // Make sure no manifest shortcuts.
7426         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7427             assertEmpty(mManager.getManifestShortcuts());
7428         });
7429 
7430         // Package 1 updated, which has one valid manifest shortcut and one invalid.
7431         addManifestShortcutResource(
7432                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7433                 R.xml.shortcut_error_1);
7434         updatePackageVersion(CALLING_PACKAGE_1, 1);
7435                 mService.mPackageMonitor.onReceive(getTestContext(),
7436                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7437 
7438         // Only the valid one is published.
7439         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7440             assertWith(getCallerShortcuts())
7441                     .areAllManifest()
7442                     .areAllImmutable()
7443                     .areAllEnabled()
7444                     .haveIds("x1");
7445         });
7446 
7447         // Package 1 updated, which has one valid manifest shortcut and one invalid.
7448         addManifestShortcutResource(
7449                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7450                 R.xml.shortcut_error_2);
7451         updatePackageVersion(CALLING_PACKAGE_1, 1);
7452                 mService.mPackageMonitor.onReceive(getTestContext(),
7453                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7454 
7455         // Only the valid one is published.
7456         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7457             assertWith(getCallerShortcuts())
7458                     .areAllManifest()
7459                     .areAllImmutable()
7460                     .areAllEnabled()
7461                     .haveIds("x2");
7462         });
7463 
7464         // Package 1 updated, which has one valid manifest shortcut and one invalid.
7465         addManifestShortcutResource(
7466                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7467                 R.xml.shortcut_error_3);
7468         updatePackageVersion(CALLING_PACKAGE_1, 1);
7469                 mService.mPackageMonitor.onReceive(getTestContext(),
7470                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7471 
7472         // Only the valid one is published.
7473         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7474             assertWith(getCallerShortcuts())
7475                     .areAllManifest()
7476                     .areAllImmutable()
7477                     .areAllEnabled()
7478                     .haveIds("x3")
7479                     .forShortcutWithId("x3", si -> {
7480                         assertEquals(set("cat2"), si.getCategories());
7481                      });
7482         });
7483     }
7484 
testManifestShortcuts_intentDefinitions()7485     public void testManifestShortcuts_intentDefinitions() {
7486         addManifestShortcutResource(
7487                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7488                 R.xml.shortcut_error_4);
7489         updatePackageVersion(CALLING_PACKAGE_1, 1);
7490                 mService.mPackageMonitor.onReceive(getTestContext(),
7491                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7492 
7493         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7494             // Make sure invalid ones are not published.
7495             // Note that at this point disabled ones don't show up because they weren't pinned.
7496             assertWith(getCallerShortcuts())
7497                     .haveIds("ms1", "ms2")
7498                     .areAllManifest()
7499                     .areAllNotDynamic()
7500                     .areAllNotPinned()
7501                     .areAllImmutable()
7502                     .areAllEnabled()
7503                     .forShortcutWithId("ms1", si -> {
7504                         assertTrue(si.isEnabled());
7505                         assertEquals(1, si.getIntents().length);
7506 
7507                         assertEquals("action1", si.getIntent().getAction());
7508                         assertEquals("value1", si.getIntent().getStringExtra("key1"));
7509                         assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK |
7510                                 Intent.FLAG_ACTIVITY_CLEAR_TASK |
7511                                 Intent.FLAG_ACTIVITY_TASK_ON_HOME, si.getIntent().getFlags());
7512 
7513                         assertEquals("action1", si.getIntents()[0].getAction());
7514                         assertEquals("value1", si.getIntents()[0].getStringExtra("key1"));
7515                         assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK |
7516                                 Intent.FLAG_ACTIVITY_CLEAR_TASK |
7517                                 Intent.FLAG_ACTIVITY_TASK_ON_HOME, si.getIntents()[0].getFlags());
7518                     })
7519                     .forShortcutWithId("ms2", si -> {
7520                         assertTrue(si.isEnabled());
7521                         assertEquals(2, si.getIntents().length);
7522 
7523                         // getIntent will return the last one.
7524                         assertEquals("action2_2", si.getIntent().getAction());
7525                         assertEquals("value2", si.getIntent().getStringExtra("key2"));
7526                         assertEquals(0, si.getIntent().getFlags());
7527 
7528                         final Intent i1 = si.getIntents()[0];
7529                         final Intent i2 = si.getIntents()[1];
7530 
7531                         assertEquals("action2_1", i1.getAction());
7532                         assertEquals("value1", i1.getStringExtra("key1"));
7533                         assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK |
7534                                         Intent.FLAG_ACTIVITY_CLEAR_TASK |
7535                                         Intent.FLAG_ACTIVITY_TASK_ON_HOME, i1.getFlags());
7536 
7537                         assertEquals("action2_2", i2.getAction());
7538                         assertEquals("value2", i2.getStringExtra("key2"));
7539                         assertEquals(0, i2.getFlags());
7540                     });
7541         });
7542 
7543         // Publish 5 enabled to pin some, so we can later test disabled manfiest shortcuts..
7544         addManifestShortcutResource(
7545                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7546                 R.xml.shortcut_5);
7547         updatePackageVersion(CALLING_PACKAGE_1, 1);
7548                 mService.mPackageMonitor.onReceive(getTestContext(),
7549                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7550 
7551         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7552             // Make sure 5 manifest shortcuts are published.
7553             assertWith(getCallerShortcuts())
7554                     .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
7555                     .areAllManifest()
7556                     .areAllNotDynamic()
7557                     .areAllNotPinned()
7558                     .areAllImmutable()
7559                     .areAllEnabled();
7560         });
7561 
7562         runWithCaller(LAUNCHER_1, USER_0, () -> {
7563             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
7564                     list("ms3", "ms4", "ms5"), HANDLE_USER_0);
7565         });
7566 
7567         // Make sure they're pinned.
7568         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7569             assertWith(getCallerShortcuts())
7570                     .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
7571                     .selectByIds("ms1", "ms2")
7572                     .areAllNotPinned()
7573                     .areAllEnabled()
7574 
7575                     .revertToOriginalList()
7576                     .selectByIds("ms3", "ms4", "ms5")
7577                     .areAllPinned()
7578                     .areAllEnabled();
7579         });
7580 
7581         // Update the app.
7582         addManifestShortcutResource(
7583                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7584                 R.xml.shortcut_error_4);
7585         updatePackageVersion(CALLING_PACKAGE_1, 1);
7586                 mService.mPackageMonitor.onReceive(getTestContext(),
7587                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7588 
7589         // Make sure 3, 4 and 5 still exist but disabled.
7590         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7591             assertWith(getCallerShortcuts())
7592                     .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
7593                     .areAllNotDynamic()
7594                     .areAllImmutable()
7595 
7596                     .selectByIds("ms1", "ms2")
7597                     .areAllManifest()
7598                     .areAllNotPinned()
7599                     .areAllEnabled()
7600 
7601                     .revertToOriginalList()
7602                     .selectByIds("ms3", "ms4", "ms5")
7603                     .areAllNotManifest()
7604                     .areAllPinned()
7605                     .areAllDisabled()
7606 
7607                     .revertToOriginalList()
7608                     .forShortcutWithId("ms1", si -> {
7609                         assertEquals(si.getId(), "action1", si.getIntent().getAction());
7610                     })
7611                     .forShortcutWithId("ms2", si -> {
7612                         // getIntent returns the last one.
7613                         assertEquals(si.getId(), "action2_2", si.getIntent().getAction());
7614                     })
7615                     .forShortcutWithId("ms3", si -> {
7616                         assertEquals(si.getId(), Intent.ACTION_VIEW, si.getIntent().getAction());
7617                     })
7618                     .forShortcutWithId("ms4", si -> {
7619                         assertEquals(si.getId(), Intent.ACTION_VIEW, si.getIntent().getAction());
7620                     })
7621                     .forShortcutWithId("ms5", si -> {
7622                         assertEquals(si.getId(), "action", si.getIntent().getAction());
7623                     });
7624         });
7625     }
7626 
testManifestShortcuts_checkAllFields()7627     public void testManifestShortcuts_checkAllFields() {
7628         mService.handleUnlockUser(USER_0);
7629 
7630         // Package 1 updated, which has one valid manifest shortcut and one invalid.
7631         addManifestShortcutResource(
7632                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7633                 R.xml.shortcut_5);
7634         updatePackageVersion(CALLING_PACKAGE_1, 1);
7635                 mService.mPackageMonitor.onReceive(getTestContext(),
7636                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7637 
7638         // Only the valid one is published.
7639         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7640             assertWith(getCallerShortcuts())
7641                     .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
7642                     .areAllManifest()
7643                     .areAllImmutable()
7644                     .areAllEnabled()
7645                     .areAllNotPinned()
7646                     .areAllNotDynamic()
7647 
7648                     .forShortcutWithId("ms1", si -> {
7649                         assertEquals(R.drawable.icon1, si.getIconResourceId());
7650                         assertEquals(new ComponentName(CALLING_PACKAGE_1,
7651                                 ShortcutActivity.class.getName()),
7652                                 si.getActivity());
7653 
7654                         assertEquals(R.string.shortcut_title1, si.getTitleResId());
7655                         assertEquals("r" + R.string.shortcut_title1, si.getTitleResName());
7656                         assertEquals(R.string.shortcut_text1, si.getTextResId());
7657                         assertEquals("r" + R.string.shortcut_text1, si.getTextResName());
7658                         assertEquals(R.string.shortcut_disabled_message1,
7659                                 si.getDisabledMessageResourceId());
7660                         assertEquals("r" + R.string.shortcut_disabled_message1,
7661                                 si.getDisabledMessageResName());
7662 
7663                         assertEquals(set("android.shortcut.conversation", "android.shortcut.media"),
7664                                 si.getCategories());
7665                         assertEquals("action1", si.getIntent().getAction());
7666                         assertEquals(Uri.parse("http://a.b.c/1"), si.getIntent().getData());
7667                     })
7668 
7669                     .forShortcutWithId("ms2", si -> {
7670                         assertEquals("ms2", si.getId());
7671                         assertEquals(R.drawable.icon2, si.getIconResourceId());
7672 
7673                         assertEquals(R.string.shortcut_title2, si.getTitleResId());
7674                         assertEquals("r" + R.string.shortcut_title2, si.getTitleResName());
7675                         assertEquals(R.string.shortcut_text2, si.getTextResId());
7676                         assertEquals("r" + R.string.shortcut_text2, si.getTextResName());
7677                         assertEquals(R.string.shortcut_disabled_message2,
7678                                 si.getDisabledMessageResourceId());
7679                         assertEquals("r" + R.string.shortcut_disabled_message2,
7680                                 si.getDisabledMessageResName());
7681 
7682                         assertEquals(set("android.shortcut.conversation"), si.getCategories());
7683                         assertEquals("action2", si.getIntent().getAction());
7684                         assertEquals(null, si.getIntent().getData());
7685                     })
7686 
7687                     .forShortcutWithId("ms3", si -> {
7688                         assertEquals(0, si.getIconResourceId());
7689                         assertEquals(R.string.shortcut_title1, si.getTitleResId());
7690                         assertEquals("r" + R.string.shortcut_title1, si.getTitleResName());
7691 
7692                         assertEquals(0, si.getTextResId());
7693                         assertEquals(null, si.getTextResName());
7694                         assertEquals(0, si.getDisabledMessageResourceId());
7695                         assertEquals(null, si.getDisabledMessageResName());
7696 
7697                         assertEmpty(si.getCategories());
7698                         assertEquals("android.intent.action.VIEW", si.getIntent().getAction());
7699                         assertEquals(null, si.getIntent().getData());
7700                     })
7701 
7702                     .forShortcutWithId("ms4", si -> {
7703                         assertEquals(0, si.getIconResourceId());
7704                         assertEquals(R.string.shortcut_title2, si.getTitleResId());
7705                         assertEquals("r" + R.string.shortcut_title2, si.getTitleResName());
7706 
7707                         assertEquals(0, si.getTextResId());
7708                         assertEquals(null, si.getTextResName());
7709                         assertEquals(0, si.getDisabledMessageResourceId());
7710                         assertEquals(null, si.getDisabledMessageResName());
7711 
7712                         assertEquals(set("cat"), si.getCategories());
7713                         assertEquals("android.intent.action.VIEW2", si.getIntent().getAction());
7714                         assertEquals(null, si.getIntent().getData());
7715                     })
7716 
7717                     .forShortcutWithId("ms5", si -> {
7718                         si = getCallerShortcut("ms5");
7719                         assertEquals("action", si.getIntent().getAction());
7720                         assertEquals("http://www/", si.getIntent().getData().toString());
7721                         assertEquals("foo/bar", si.getIntent().getType());
7722                         assertEquals(
7723                                 new ComponentName("abc", "abc.xyz"), si.getIntent().getComponent());
7724 
7725                         assertEquals(set("cat1", "cat2"), si.getIntent().getCategories());
7726                         assertEquals("value1", si.getIntent().getStringExtra("key1"));
7727                         assertEquals("value2", si.getIntent().getStringExtra("key2"));
7728                     });
7729         });
7730     }
7731 
testManifestShortcuts_localeChange()7732     public void testManifestShortcuts_localeChange() throws InterruptedException {
7733         mService.handleUnlockUser(USER_0);
7734 
7735         // Package 1 updated, which has one valid manifest shortcut and one invalid.
7736         addManifestShortcutResource(
7737                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7738                 R.xml.shortcut_2);
7739         updatePackageVersion(CALLING_PACKAGE_1, 1);
7740                 mService.mPackageMonitor.onReceive(getTestContext(),
7741                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7742 
7743         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7744             mManager.setDynamicShortcuts(list(makeShortcutWithTitle("s1", "title")));
7745 
7746             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7747                     mManager.getManifestShortcuts()))),
7748                     "ms1", "ms2");
7749 
7750             // check first shortcut.
7751             ShortcutInfo si = getCallerShortcut("ms1");
7752 
7753             assertEquals("ms1", si.getId());
7754             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title1 + "/en",
7755                     si.getTitle());
7756             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text1 + "/en",
7757                     si.getText());
7758             assertEquals("string-com.android.test.1-user:0-res:"
7759                             + R.string.shortcut_disabled_message1 + "/en",
7760                     si.getDisabledMessage());
7761             assertEquals(START_TIME, si.getLastChangedTimestamp());
7762 
7763             // check another
7764             si = getCallerShortcut("ms2");
7765 
7766             assertEquals("ms2", si.getId());
7767             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title2 + "/en",
7768                     si.getTitle());
7769             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text2 + "/en",
7770                     si.getText());
7771             assertEquals("string-com.android.test.1-user:0-res:"
7772                             + R.string.shortcut_disabled_message2 + "/en",
7773                     si.getDisabledMessage());
7774             assertEquals(START_TIME, si.getLastChangedTimestamp());
7775 
7776             // Check the dynamic one.
7777             si = getCallerShortcut("s1");
7778 
7779             assertEquals("s1", si.getId());
7780             assertEquals("title", si.getTitle());
7781             assertEquals(null, si.getText());
7782             assertEquals(null, si.getDisabledMessage());
7783             assertEquals(START_TIME, si.getLastChangedTimestamp());
7784         });
7785 
7786         mInjectedCurrentTimeMillis++;
7787 
7788         // Change the locale and send the broadcast, make sure the launcher gets a callback too.
7789         mInjectedLocale = Locale.JAPANESE;
7790 
7791         setCaller(LAUNCHER_1, USER_0);
7792 
7793         assertForLauncherCallback(mLauncherApps, () -> {
7794             mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
7795         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
7796                 .haveIds("ms1", "ms2", "s1");
7797 
7798         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7799             // check first shortcut.
7800             ShortcutInfo si = getCallerShortcut("ms1");
7801 
7802             assertEquals("ms1", si.getId());
7803             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title1 + "/ja",
7804                     si.getTitle());
7805             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text1 + "/ja",
7806                     si.getText());
7807             assertEquals("string-com.android.test.1-user:0-res:"
7808                             + R.string.shortcut_disabled_message1 + "/ja",
7809                     si.getDisabledMessage());
7810             assertEquals(START_TIME + 1, si.getLastChangedTimestamp());
7811 
7812             // check another
7813             si = getCallerShortcut("ms2");
7814 
7815             assertEquals("ms2", si.getId());
7816             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title2 + "/ja",
7817                     si.getTitle());
7818             assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text2 + "/ja",
7819                     si.getText());
7820             assertEquals("string-com.android.test.1-user:0-res:"
7821                             + R.string.shortcut_disabled_message2 + "/ja",
7822                     si.getDisabledMessage());
7823             assertEquals(START_TIME + 1, si.getLastChangedTimestamp());
7824 
7825             // Check the dynamic one.  (locale change shouldn't affect.)
7826             si = getCallerShortcut("s1");
7827 
7828             assertEquals("s1", si.getId());
7829             assertEquals("title", si.getTitle());
7830             assertEquals(null, si.getText());
7831             assertEquals(null, si.getDisabledMessage());
7832             assertEquals(START_TIME, si.getLastChangedTimestamp()); // Not changed.
7833         });
7834     }
7835 
testManifestShortcuts_updateAndDisabled_notPinned()7836     public void testManifestShortcuts_updateAndDisabled_notPinned() {
7837         mService.handleUnlockUser(USER_0);
7838 
7839         // First, just publish a manifest shortcut.
7840         addManifestShortcutResource(
7841                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7842                 R.xml.shortcut_1);
7843         updatePackageVersion(CALLING_PACKAGE_1, 1);
7844                 mService.mPackageMonitor.onReceive(getTestContext(),
7845                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7846 
7847         // Only the valid one is published.
7848         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7849             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7850                     mManager.getManifestShortcuts()))),
7851                     "ms1");
7852             assertEmpty(mManager.getPinnedShortcuts());
7853 
7854             // Make sure there's no other dangling shortcuts.
7855             assertShortcutIds(getCallerShortcuts(), "ms1");
7856         });
7857 
7858         // Now version up, the manifest shortcut is disabled now.
7859         addManifestShortcutResource(
7860                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7861                 R.xml.shortcut_1_disable);
7862         updatePackageVersion(CALLING_PACKAGE_1, 1);
7863                 mService.mPackageMonitor.onReceive(getTestContext(),
7864                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7865 
7866         // Because shortcut 1 wasn't pinned, it'll just go away.
7867         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7868             assertEmpty(mManager.getManifestShortcuts());
7869             assertEmpty(mManager.getPinnedShortcuts());
7870 
7871             // Make sure there's no other dangling shortcuts.
7872             assertEmpty(getCallerShortcuts());
7873         });
7874     }
7875 
testManifestShortcuts_updateAndDisabled_pinned()7876     public void testManifestShortcuts_updateAndDisabled_pinned() {
7877         mService.handleUnlockUser(USER_0);
7878 
7879         // First, just publish a manifest shortcut.
7880         addManifestShortcutResource(
7881                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7882                 R.xml.shortcut_1);
7883         updatePackageVersion(CALLING_PACKAGE_1, 1);
7884                 mService.mPackageMonitor.onReceive(getTestContext(),
7885                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7886 
7887         // Only the valid one is published.
7888         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7889             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7890                     mManager.getManifestShortcuts()))),
7891                     "ms1");
7892             assertEmpty(mManager.getPinnedShortcuts());
7893 
7894             // Make sure there's no other dangling shortcuts.
7895             assertShortcutIds(getCallerShortcuts(), "ms1");
7896         });
7897 
7898         runWithCaller(LAUNCHER_1, USER_0, () -> {
7899             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_0);
7900         });
7901 
7902         // Now upgrade, the manifest shortcut is disabled now.
7903         addManifestShortcutResource(
7904                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7905                 R.xml.shortcut_1_disable);
7906         updatePackageVersion(CALLING_PACKAGE_1, 1);
7907                 mService.mPackageMonitor.onReceive(getTestContext(),
7908                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7909 
7910         // Because shortcut 1 was pinned, it'll still exist as pinned, but disabled.
7911         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7912             assertEmpty(mManager.getManifestShortcuts());
7913             assertShortcutIds(assertAllNotManifest(assertAllImmutable(assertAllDisabled(
7914                     mManager.getPinnedShortcuts()))),
7915                     "ms1");
7916 
7917             // Make sure the fields are updated.
7918             ShortcutInfo si = getCallerShortcut("ms1");
7919 
7920             assertEquals("ms1", si.getId());
7921             assertEquals(R.drawable.icon2, si.getIconResourceId());
7922             assertEquals(R.string.shortcut_title2, si.getTitleResId());
7923             assertEquals(R.string.shortcut_text2, si.getTextResId());
7924             assertEquals(R.string.shortcut_disabled_message2, si.getDisabledMessageResourceId());
7925             assertEquals(Intent.ACTION_VIEW, si.getIntent().getAction());
7926 
7927             // Make sure there's no other dangling shortcuts.
7928             assertShortcutIds(getCallerShortcuts(), "ms1");
7929         });
7930     }
7931 
testManifestShortcuts_duplicateInSingleActivity()7932     public void testManifestShortcuts_duplicateInSingleActivity() {
7933         mService.handleUnlockUser(USER_0);
7934 
7935         // The XML has two shortcuts with the same ID.
7936         addManifestShortcutResource(
7937                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7938                 R.xml.shortcut_2_duplicate);
7939         updatePackageVersion(CALLING_PACKAGE_1, 1);
7940                 mService.mPackageMonitor.onReceive(getTestContext(),
7941                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7942 
7943         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7944             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7945                     mManager.getManifestShortcuts()))),
7946                     "ms1");
7947 
7948             // Make sure the first one has survived.  (the second one has a different title.)
7949             ShortcutInfo si = getCallerShortcut("ms1");
7950             assertEquals(R.string.shortcut_title1, si.getTitleResId());
7951 
7952             // Make sure there's no other dangling shortcuts.
7953             assertShortcutIds(getCallerShortcuts(), "ms1");
7954         });
7955     }
7956 
testManifestShortcuts_duplicateInTwoActivities()7957     public void testManifestShortcuts_duplicateInTwoActivities() {
7958         mService.handleUnlockUser(USER_0);
7959 
7960         // ShortcutActivity has shortcut ms1
7961         addManifestShortcutResource(
7962                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7963                 R.xml.shortcut_1);
7964 
7965         // ShortcutActivity2 has two shortcuts, ms1 and ms2.
7966         addManifestShortcutResource(
7967                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
7968                 R.xml.shortcut_5);
7969         updatePackageVersion(CALLING_PACKAGE_1, 1);
7970                 mService.mPackageMonitor.onReceive(getTestContext(),
7971                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7972 
7973         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7974             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7975                     mManager.getManifestShortcuts()))),
7976                     "ms1", "ms2", "ms3", "ms4", "ms5");
7977 
7978             // ms1 should belong to ShortcutActivity.
7979             ShortcutInfo si = getCallerShortcut("ms1");
7980             assertEquals(R.string.shortcut_title1, si.getTitleResId());
7981             assertEquals(new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7982                     si.getActivity());
7983             assertEquals(0, si.getRank());
7984 
7985             // ms2 should belong to ShortcutActivity*2*.
7986             si = getCallerShortcut("ms2");
7987             assertEquals(R.string.shortcut_title2, si.getTitleResId());
7988             assertEquals(new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
7989                     si.getActivity());
7990 
7991             // Also check the ranks
7992             assertWith(getCallerShortcuts()).selectManifest()
7993                     .selectByActivity(
7994                             new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()))
7995                     .haveRanksInOrder("ms1");
7996             assertWith(getCallerShortcuts()).selectManifest()
7997                     .selectByActivity(
7998                             new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()))
7999                     .haveRanksInOrder("ms2", "ms3", "ms4", "ms5");
8000 
8001             // Make sure there's no other dangling shortcuts.
8002             assertShortcutIds(getCallerShortcuts(), "ms1", "ms2", "ms3", "ms4", "ms5");
8003         });
8004     }
8005 
8006     /**
8007      * Manifest shortcuts cannot override shortcuts that were published via the APIs.
8008      */
testManifestShortcuts_cannotOverrideNonManifest()8009     public void testManifestShortcuts_cannotOverrideNonManifest() {
8010         mService.handleUnlockUser(USER_0);
8011 
8012         // Create a non-pinned dynamic shortcut and a non-dynamic pinned shortcut.
8013 
8014         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8015             mManager.setDynamicShortcuts(list(
8016                     makeShortcut("ms1", "title1",
8017                             new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8018                     /* icon */ null, new Intent("action1"), /* rank */ 0),
8019                     makeShortcut("ms2", "title2",
8020                             new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8021                     /* icon */ null, new Intent("action1"), /* rank */ 0)));
8022         });
8023 
8024         runWithCaller(LAUNCHER_1, USER_0, () -> {
8025             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_0);
8026         });
8027 
8028         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8029             mManager.removeDynamicShortcuts(list("ms2"));
8030 
8031             assertShortcutIds(mManager.getDynamicShortcuts(), "ms1");
8032             assertShortcutIds(mManager.getPinnedShortcuts(), "ms2");
8033             assertEmpty(mManager.getManifestShortcuts());
8034         });
8035 
8036         // Then update the app with 5 manifest shortcuts.
8037         // Make sure "ms1" and "ms2" won't be replaced.
8038         addManifestShortcutResource(
8039                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8040                 R.xml.shortcut_5);
8041         updatePackageVersion(CALLING_PACKAGE_1, 1);
8042                 mService.mPackageMonitor.onReceive(getTestContext(),
8043                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8044 
8045         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8046             assertShortcutIds(assertAllNotManifest(mManager.getDynamicShortcuts()), "ms1");
8047             assertShortcutIds(assertAllNotManifest(mManager.getPinnedShortcuts()), "ms2");
8048             assertShortcutIds(assertAllManifest(mManager.getManifestShortcuts()),
8049                     "ms3", "ms4", "ms5");
8050 
8051             // ms1 and ms2 shouold keep the original title.
8052             ShortcutInfo si = getCallerShortcut("ms1");
8053             assertEquals("title1", si.getTitle());
8054 
8055             si = getCallerShortcut("ms2");
8056             assertEquals("title2", si.getTitle());
8057         });
8058     }
8059 
checkManifestShortcuts_immutable_verify()8060     protected void checkManifestShortcuts_immutable_verify() {
8061         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8062             assertShortcutIds(assertAllNotManifest(assertAllEnabled(
8063                     mManager.getDynamicShortcuts())),
8064                     "s1");
8065             assertShortcutIds(assertAllManifest(assertAllEnabled(
8066                     mManager.getManifestShortcuts())),
8067                     "ms1");
8068             assertShortcutIds(assertAllNotManifest(assertAllDisabled(
8069                     mManager.getPinnedShortcuts())),
8070                     "ms2");
8071 
8072             assertEquals("t1", getCallerShortcut("s1").getTitle());
8073 
8074             // Make sure there are no other shortcuts.
8075             assertShortcutIds(getCallerShortcuts(), "s1", "ms1", "ms2");
8076         });
8077     }
8078 
8079     /**
8080      * Make sure the APIs won't work on manifest shortcuts.
8081      */
testManifestShortcuts_immutable()8082     public void testManifestShortcuts_immutable() {
8083         mService.handleUnlockUser(USER_0);
8084 
8085         // Create a non-pinned manifest shortcut, a pinned shortcut that was originally
8086         // a manifest shortcut, as well as a dynamic shortcut.
8087 
8088         addManifestShortcutResource(
8089                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8090                 R.xml.shortcut_2);
8091         updatePackageVersion(CALLING_PACKAGE_1, 1);
8092                 mService.mPackageMonitor.onReceive(getTestContext(),
8093                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8094 
8095         runWithCaller(LAUNCHER_1, USER_0, () -> {
8096             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_0);
8097         });
8098 
8099         addManifestShortcutResource(
8100                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8101                 R.xml.shortcut_1);
8102         updatePackageVersion(CALLING_PACKAGE_1, 1);
8103                 mService.mPackageMonitor.onReceive(getTestContext(),
8104                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8105 
8106         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8107             mManager.addDynamicShortcuts(list(makeShortcutWithTitle("s1", "t1")));
8108         });
8109 
8110         checkManifestShortcuts_immutable_verify();
8111 
8112         // Note that even though the first argument is not immutable and only the second one
8113         // is immutable, the first argument should not be executed either.
8114 
8115         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8116             assertCannotUpdateImmutable(() -> {
8117                 mManager.setDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms1")));
8118             });
8119             assertCannotUpdateImmutable(() -> {
8120                 mManager.setDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms2")));
8121             });
8122         });
8123         checkManifestShortcuts_immutable_verify();
8124 
8125         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8126             assertCannotUpdateImmutable(() -> {
8127                 mManager.addDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms1")));
8128             });
8129             assertCannotUpdateImmutable(() -> {
8130                 mManager.addDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms2")));
8131             });
8132         });
8133         checkManifestShortcuts_immutable_verify();
8134 
8135 
8136         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8137             assertCannotUpdateImmutable(() -> {
8138                 mManager.updateShortcuts(list(makeShortcut("s1"), makeShortcut("ms1")));
8139             });
8140             assertCannotUpdateImmutable(() -> {
8141                 mManager.updateShortcuts(list(makeShortcut("s1"), makeShortcut("ms2")));
8142             });
8143         });
8144         checkManifestShortcuts_immutable_verify();
8145 
8146         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8147             assertCannotUpdateImmutable(() -> {
8148                 mManager.removeDynamicShortcuts(list("s1", "ms1"));
8149             });
8150             assertCannotUpdateImmutable(() -> {
8151                 mManager.removeDynamicShortcuts(list("s2", "ms2"));
8152             });
8153         });
8154         checkManifestShortcuts_immutable_verify();
8155 
8156         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8157             assertCannotUpdateImmutable(() -> {
8158                 mManager.disableShortcuts(list("s1", "ms1"));
8159             });
8160         });
8161         checkManifestShortcuts_immutable_verify();
8162 
8163         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8164             assertCannotUpdateImmutable(() -> {
8165                 mManager.enableShortcuts(list("s1", "ms2"));
8166             });
8167         });
8168         checkManifestShortcuts_immutable_verify();
8169     }
8170 
8171 
8172     /**
8173      * Make sure the APIs won't work on manifest shortcuts.
8174      */
testManifestShortcuts_tooMany()8175     public void testManifestShortcuts_tooMany() {
8176         // Change the max number of shortcuts.
8177         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
8178 
8179         mService.handleUnlockUser(USER_0);
8180 
8181         addManifestShortcutResource(
8182                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8183                 R.xml.shortcut_5);
8184         updatePackageVersion(CALLING_PACKAGE_1, 1);
8185                 mService.mPackageMonitor.onReceive(getTestContext(),
8186                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8187 
8188         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8189             // Only the first 3 should be published.
8190             assertShortcutIds(mManager.getManifestShortcuts(), "ms1", "ms2", "ms3");
8191         });
8192     }
8193 
testMaxShortcutCount_set()8194     public void testMaxShortcutCount_set() {
8195         // Change the max number of shortcuts.
8196         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
8197 
8198         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8199             final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
8200             final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
8201             final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
8202             final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
8203             final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
8204             final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
8205             final ShortcutInfo s1_5 = makeShortcutWithActivity("s15", a1);
8206             final ShortcutInfo s1_6 = makeShortcutWithActivity("s16", a1);
8207             final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
8208             final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
8209             final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
8210             final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
8211 
8212             // 3 shortcuts for 2 activities -> okay
8213             mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
8214             assertShortcutIds(mManager.getDynamicShortcuts(),
8215                     "s11", "s12", "s13", "s21", "s22", "s23");
8216 
8217             mManager.removeAllDynamicShortcuts();
8218 
8219             // 4 shortcut for activity 1 -> too many.
8220             assertDynamicShortcutCountExceeded(() -> {
8221                 mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s1_4, s2_1, s2_2, s2_3));
8222             });
8223             assertEmpty(mManager.getDynamicShortcuts());
8224 
8225             // 4 shortcut for activity 2 -> too many.
8226             assertDynamicShortcutCountExceeded(() -> {
8227                 mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3, s2_4));
8228             });
8229             assertEmpty(mManager.getDynamicShortcuts());
8230 
8231             // First, set 3.  Then set 4, which should be ignored.
8232             mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
8233             assertShortcutIds(mManager.getDynamicShortcuts(),
8234                     "s11", "s12", "s13");
8235             assertDynamicShortcutCountExceeded(() -> {
8236                 mManager.setDynamicShortcuts(list(s2_1, s2_2, s2_3, s2_4));
8237             });
8238             assertShortcutIds(mManager.getDynamicShortcuts(),
8239                     "s11", "s12", "s13");
8240 
8241             // Set will remove the old dynamic set, unlike add, so the following should pass.
8242             mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
8243             assertShortcutIds(mManager.getDynamicShortcuts(),
8244                     "s11", "s12", "s13");
8245             mManager.setDynamicShortcuts(list(s1_4, s1_5, s1_6));
8246             assertShortcutIds(mManager.getDynamicShortcuts(),
8247                     "s14", "s15", "s16");
8248 
8249             // Now, test with 2 manifest shortcuts.
8250             mManager.removeAllDynamicShortcuts();
8251             addManifestShortcutResource(
8252                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8253                     R.xml.shortcut_2);
8254             updatePackageVersion(CALLING_PACKAGE_1, 1);
8255                     mService.mPackageMonitor.onReceive(getTestContext(),
8256                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8257             assertEquals(2, mManager.getManifestShortcuts().size());
8258 
8259             // Setting 1 to activity 1 will work.
8260             mManager.setDynamicShortcuts(list(s1_1, s2_1, s2_2, s2_3));
8261             assertShortcutIds(mManager.getDynamicShortcuts(),
8262                     "s11", "s21", "s22", "s23");
8263             assertEquals(2, mManager.getManifestShortcuts().size());
8264 
8265             // But setting 2 will not.
8266             mManager.removeAllDynamicShortcuts();
8267             assertDynamicShortcutCountExceeded(() -> {
8268                 mManager.setDynamicShortcuts(list(s1_1, s1_2, s2_1, s2_2, s2_3));
8269             });
8270             assertEmpty(mManager.getDynamicShortcuts());
8271             assertEquals(2, mManager.getManifestShortcuts().size());
8272         });
8273     }
8274 
testMaxShortcutCount_add()8275     public void testMaxShortcutCount_add() {
8276         // Change the max number of shortcuts.
8277         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
8278 
8279         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8280             final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
8281             final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
8282             final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
8283             final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
8284             final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
8285             final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
8286             final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
8287             final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
8288             final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
8289             final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
8290 
8291             // 3 shortcuts for 2 activities -> okay
8292             mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
8293             assertShortcutIds(mManager.getDynamicShortcuts(),
8294                     "s11", "s12", "s13", "s21", "s22", "s23");
8295 
8296             mManager.removeAllDynamicShortcuts();
8297 
8298             // 4 shortcut for activity 1 -> too many.
8299             assertDynamicShortcutCountExceeded(() -> {
8300                 mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s1_4, s2_1, s2_2, s2_3));
8301             });
8302             assertEmpty(mManager.getDynamicShortcuts());
8303 
8304             // 4 shortcut for activity 2 -> too many.
8305             assertDynamicShortcutCountExceeded(() -> {
8306                 mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3, s2_4));
8307             });
8308             assertEmpty(mManager.getDynamicShortcuts());
8309 
8310             // First, set 3.  Then add 1 more, which should be ignored.
8311             mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
8312             assertShortcutIds(mManager.getDynamicShortcuts(),
8313                     "s11", "s12", "s13");
8314             assertDynamicShortcutCountExceeded(() -> {
8315                 mManager.addDynamicShortcuts(list(s1_4, s2_1));
8316             });
8317             assertShortcutIds(mManager.getDynamicShortcuts(),
8318                     "s11", "s12", "s13");
8319 
8320             // Update existing one, which should work.
8321             mManager.addDynamicShortcuts(list(makeShortcutWithActivityAndTitle(
8322                     "s11", a1, "xxx"), s2_1));
8323             assertShortcutIds(mManager.getDynamicShortcuts(),
8324                     "s11", "s12", "s13", "s21");
8325             assertEquals("xxx", getCallerShortcut("s11").getTitle());
8326 
8327             // Make sure pinned shortcuts won't affect.
8328             // - Pin s11 - s13, and remove all dynamic.
8329             runWithCaller(LAUNCHER_1, USER_0, () -> {
8330                 mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
8331                         HANDLE_USER_0);
8332             });
8333             mManager.removeAllDynamicShortcuts();
8334 
8335             assertEmpty(mManager.getDynamicShortcuts());
8336             assertShortcutIds(mManager.getPinnedShortcuts(),
8337                     "s11", "s12", "s13");
8338 
8339             // Then add dynamic.
8340             mManager.addDynamicShortcuts(list(s1_4, s2_1, s2_2, s2_3));
8341 
8342             assertShortcutIds(mManager.getDynamicShortcuts(),
8343                     "s14", "s21", "s22", "s23");
8344             assertShortcutIds(mManager.getPinnedShortcuts(),
8345                     "s11", "s12", "s13");
8346 
8347             // Adding "s11" and "s12" back, should work
8348             mManager.addDynamicShortcuts(list(s1_1, s1_2));
8349 
8350             assertShortcutIds(mManager.getDynamicShortcuts(),
8351                     "s14", "s11", "s12", "s21", "s22", "s23");
8352             assertShortcutIds(mManager.getPinnedShortcuts(),
8353                     "s11", "s12", "s13");
8354 
8355             // Adding back s13 doesn't work.
8356             assertDynamicShortcutCountExceeded(() -> {
8357                 mManager.addDynamicShortcuts(list(s1_3));
8358             });
8359 
8360             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
8361                     "s11", "s12", "s14");
8362             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
8363                     "s21", "s22", "s23");
8364 
8365             // Now swap the activities.
8366             mManager.updateShortcuts(list(
8367                     makeShortcutWithActivity("s11", a2),
8368                     makeShortcutWithActivity("s21", a1)));
8369 
8370             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
8371                     "s21", "s12", "s14");
8372             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
8373                     "s11", "s22", "s23");
8374 
8375             // Now, test with 2 manifest shortcuts.
8376             mManager.removeAllDynamicShortcuts();
8377             addManifestShortcutResource(
8378                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8379                     R.xml.shortcut_2);
8380             updatePackageVersion(CALLING_PACKAGE_1, 1);
8381                     mService.mPackageMonitor.onReceive(getTestContext(),
8382                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8383 
8384             assertEquals(2, mManager.getManifestShortcuts().size());
8385 
8386             // Adding one shortcut to activity 1 works fine.
8387             mManager.addDynamicShortcuts(list(s1_1, s2_1, s2_2, s2_3));
8388             assertShortcutIds(mManager.getDynamicShortcuts(),
8389                     "s11", "s21", "s22", "s23");
8390             assertEquals(2, mManager.getManifestShortcuts().size());
8391 
8392             // But adding one more doesn't.
8393             assertDynamicShortcutCountExceeded(() -> {
8394                 mManager.addDynamicShortcuts(list(s1_4, s2_1));
8395             });
8396             assertShortcutIds(mManager.getDynamicShortcuts(),
8397                     "s11", "s21", "s22", "s23");
8398             assertEquals(2, mManager.getManifestShortcuts().size());
8399         });
8400     }
8401 
testMaxShortcutCount_update()8402     public void testMaxShortcutCount_update() {
8403         // Change the max number of shortcuts.
8404         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
8405 
8406         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8407             final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
8408             final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
8409             final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
8410             final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
8411             final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
8412             final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
8413             final ShortcutInfo s1_5 = makeShortcutWithActivity("s15", a1);
8414             final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
8415             final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
8416             final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
8417             final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
8418 
8419             // 3 shortcuts for 2 activities -> okay
8420             mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
8421             assertShortcutIds(mManager.getDynamicShortcuts(),
8422                     "s11", "s12", "s13", "s21", "s22", "s23");
8423 
8424             // Trying to move s11 from a1 to a2 should fail.
8425             assertDynamicShortcutCountExceeded(() -> {
8426                 mManager.updateShortcuts(list(makeShortcutWithActivity("s11", a2)));
8427             });
8428             assertShortcutIds(mManager.getDynamicShortcuts(),
8429                     "s11", "s12", "s13", "s21", "s22", "s23");
8430 
8431             // Trying to move s21 from a2 to a1 should also fail.
8432             assertDynamicShortcutCountExceeded(() -> {
8433                 mManager.updateShortcuts(list(makeShortcutWithActivity("s21", a1)));
8434             });
8435             assertShortcutIds(mManager.getDynamicShortcuts(),
8436                     "s11", "s12", "s13", "s21", "s22", "s23");
8437 
8438             // But, if we do these two at the same time, it should work.
8439             mManager.updateShortcuts(list(
8440                     makeShortcutWithActivity("s11", a2),
8441                     makeShortcutWithActivity("s21", a1)));
8442             assertShortcutIds(mManager.getDynamicShortcuts(),
8443                     "s11", "s12", "s13", "s21", "s22", "s23");
8444             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
8445                     "s21", "s12", "s13");
8446             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
8447                     "s11", "s22", "s23");
8448 
8449             // Then reset.
8450             mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
8451             assertShortcutIds(mManager.getDynamicShortcuts(),
8452                     "s11", "s12", "s13", "s21", "s22", "s23");
8453 
8454             // Pin some to have more shortcuts for a1.
8455             runWithCaller(LAUNCHER_1, USER_0, () -> {
8456                 mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
8457                         HANDLE_USER_0);
8458             });
8459             mManager.setDynamicShortcuts(list(s1_4, s1_5, s2_1, s2_2, s2_3));
8460             assertShortcutIds(mManager.getDynamicShortcuts(),
8461                     "s14", "s15", "s21", "s22", "s23");
8462             assertShortcutIds(mManager.getPinnedShortcuts(),
8463                     "s11", "s12", "s13");
8464 
8465             // a1 already has 2 dynamic shortcuts (and 3 pinned shortcuts that used to belong on it)
8466             // But that doesn't matter for update -- the following should still work.
8467             mManager.updateShortcuts(list(
8468                     makeShortcutWithActivityAndTitle("s11", a1, "xxx1"),
8469                     makeShortcutWithActivityAndTitle("s12", a1, "xxx2"),
8470                     makeShortcutWithActivityAndTitle("s13", a1, "xxx3"),
8471                     makeShortcutWithActivityAndTitle("s14", a1, "xxx4"),
8472                     makeShortcutWithActivityAndTitle("s15", a1, "xxx5")));
8473             // All the shortcuts should still exist they all belong on same activities,
8474             // with the updated titles.
8475             assertShortcutIds(mManager.getDynamicShortcuts(),
8476                     "s14", "s15", "s21", "s22", "s23");
8477             assertShortcutIds(mManager.getPinnedShortcuts(),
8478                     "s11", "s12", "s13");
8479 
8480             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
8481                     "s14", "s15");
8482             assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
8483                     "s21", "s22", "s23");
8484 
8485             assertEquals("xxx1", getCallerShortcut("s11").getTitle());
8486             assertEquals("xxx2", getCallerShortcut("s12").getTitle());
8487             assertEquals("xxx3", getCallerShortcut("s13").getTitle());
8488             assertEquals("xxx4", getCallerShortcut("s14").getTitle());
8489             assertEquals("xxx5", getCallerShortcut("s15").getTitle());
8490         });
8491     }
8492 
testShortcutsPushedOutByManifest()8493     public void testShortcutsPushedOutByManifest() {
8494         // Change the max number of shortcuts.
8495         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
8496 
8497         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8498             final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
8499             final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
8500             final ShortcutInfo s1_1 = makeShortcutWithActivityAndRank("s11", a1, 4);
8501             final ShortcutInfo s1_2 = makeShortcutWithActivityAndRank("s12", a1, 3);
8502             final ShortcutInfo s1_3 = makeShortcutWithActivityAndRank("s13", a1, 2);
8503             final ShortcutInfo s1_4 = makeShortcutWithActivityAndRank("s14", a1, 1);
8504             final ShortcutInfo s1_5 = makeShortcutWithActivityAndRank("s15", a1, 0);
8505             final ShortcutInfo s2_1 = makeShortcutWithActivityAndRank("s21", a2, 0);
8506             final ShortcutInfo s2_2 = makeShortcutWithActivityAndRank("s22", a2, 1);
8507             final ShortcutInfo s2_3 = makeShortcutWithActivityAndRank("s23", a2, 2);
8508             final ShortcutInfo s2_4 = makeShortcutWithActivityAndRank("s24", a2, 3);
8509             final ShortcutInfo s2_5 = makeShortcutWithActivityAndRank("s25", a2, 4);
8510 
8511             // Initial state.
8512             mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
8513             runWithCaller(LAUNCHER_1, USER_0, () -> {
8514                 mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s21", "s22"),
8515                         HANDLE_USER_0);
8516             });
8517             mManager.setDynamicShortcuts(list(s1_2, s1_3, s1_4, s2_2, s2_3, s2_4));
8518             assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
8519                     "s12", "s13", "s14",
8520                     "s22", "s23", "s24");
8521             assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
8522                     "s11", "s12",
8523                     "s21", "s22");
8524 
8525             // Add 1 manifest shortcut to a1.
8526             addManifestShortcutResource(
8527                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8528                     R.xml.shortcut_1);
8529             updatePackageVersion(CALLING_PACKAGE_1, 1);
8530                     mService.mPackageMonitor.onReceive(getTestContext(),
8531                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8532             assertEquals(1, mManager.getManifestShortcuts().size());
8533 
8534             // s12 removed.
8535             assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
8536                     "s13", "s14",
8537                     "s22", "s23", "s24");
8538             assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
8539                     "s11", "s12",
8540                     "s21", "s22");
8541 
8542             // Add more manifest shortcuts.
8543             addManifestShortcutResource(
8544                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8545                     R.xml.shortcut_2);
8546             addManifestShortcutResource(
8547                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
8548                     R.xml.shortcut_1_alt);
8549             updatePackageVersion(CALLING_PACKAGE_1, 1);
8550                     mService.mPackageMonitor.onReceive(getTestContext(),
8551                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8552             assertEquals(3, mManager.getManifestShortcuts().size());
8553 
8554             // Note the ones with the highest rank values (== least important) will be removed.
8555             assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
8556                     "s14",
8557                     "s22", "s23");
8558             assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
8559                     "s11", "s12",
8560                     "s21", "s22");
8561 
8562             // Add more manifest shortcuts.
8563             addManifestShortcutResource(
8564                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8565                     R.xml.shortcut_2);
8566             addManifestShortcutResource(
8567                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
8568                     R.xml.shortcut_5_alt); // manifest has 5, but max is 3, so a2 will have 3.
8569             updatePackageVersion(CALLING_PACKAGE_1, 1);
8570                     mService.mPackageMonitor.onReceive(getTestContext(),
8571                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8572             assertEquals(5, mManager.getManifestShortcuts().size());
8573 
8574             assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
8575                     "s14" // a1 has 1 dynamic
8576             ); // a2 has no dynamic
8577             assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
8578                     "s11", "s12",
8579                     "s21", "s22");
8580 
8581             // Update, no manifest shortucts.  This doesn't affect anything.
8582             addManifestShortcutResource(
8583                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8584                     R.xml.shortcut_0);
8585             addManifestShortcutResource(
8586                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
8587                     R.xml.shortcut_0);
8588             updatePackageVersion(CALLING_PACKAGE_1, 1);
8589                     mService.mPackageMonitor.onReceive(getTestContext(),
8590                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8591             assertEquals(0, mManager.getManifestShortcuts().size());
8592 
8593             assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
8594                     "s14");
8595             assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
8596                     "s11", "s12",
8597                     "s21", "s22");
8598         });
8599     }
8600 
testReturnedByServer()8601     public void testReturnedByServer() {
8602         // Package 1 updated, with manifest shortcuts.
8603         addManifestShortcutResource(
8604                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8605                 R.xml.shortcut_1);
8606         updatePackageVersion(CALLING_PACKAGE_1, 1);
8607         mService.mPackageMonitor.onReceive(getTestContext(),
8608                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8609 
8610         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8611             assertWith(mManager.getManifestShortcuts())
8612                     .haveIds("ms1")
8613                     .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
8614 
8615             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
8616 
8617             assertWith(mManager.getDynamicShortcuts())
8618                     .haveIds("s1")
8619                     .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
8620         });
8621 
8622         // Pin them.
8623         runWithCaller(LAUNCHER_1, USER_0, () -> {
8624             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
8625                     list("ms1", "s1"), getCallingUser());
8626             assertWith(getShortcutAsLauncher(USER_0))
8627                     .haveIds("ms1", "s1")
8628                     .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
8629         });
8630 
8631         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8632             assertWith(mManager.getPinnedShortcuts())
8633                     .haveIds("ms1", "s1")
8634                     .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
8635         });
8636 
8637         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8638             // This shows a warning log, but should still work.
8639             assertTrue(mManager.setDynamicShortcuts(mManager.getDynamicShortcuts()));
8640 
8641             assertWith(mManager.getDynamicShortcuts())
8642                     .haveIds("s1")
8643                     .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
8644         });
8645     }
8646 
testIsForegroundDefaultLauncher_true()8647     public void testIsForegroundDefaultLauncher_true() {
8648         final int uid = 1024;
8649 
8650         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
8651         makeUidForeground(uid);
8652 
8653         assertTrue(mInternal.isForegroundDefaultLauncher("default", uid));
8654     }
8655 
8656 
testIsForegroundDefaultLauncher_defaultButNotForeground()8657     public void testIsForegroundDefaultLauncher_defaultButNotForeground() {
8658         final int uid = 1024;
8659 
8660         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
8661         makeUidBackground(uid);
8662 
8663         assertFalse(mInternal.isForegroundDefaultLauncher("default", uid));
8664     }
8665 
testIsForegroundDefaultLauncher_foregroundButNotDefault()8666     public void testIsForegroundDefaultLauncher_foregroundButNotDefault() {
8667         final int uid = 1024;
8668 
8669         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
8670         makeUidForeground(uid);
8671 
8672         assertFalse(mInternal.isForegroundDefaultLauncher("another", uid));
8673     }
8674 
testParseShareTargetsFromManifest()8675     public void testParseShareTargetsFromManifest() {
8676         // These values must exactly match the content of shortcuts_share_targets.xml resource
8677         List<ShareTargetInfo> expectedValues = new ArrayList<>();
8678         expectedValues.add(new ShareTargetInfo(
8679                 new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData(
8680                         "http", "www.google.com", "1234", "somePath", "somePathPattern",
8681                         "somePathPrefix", "text/plain")}, "com.test.directshare.TestActivity1",
8682                 new String[]{"com.test.category.CATEGORY1", "com.test.category.CATEGORY2"}));
8683         expectedValues.add(new ShareTargetInfo(new ShareTargetInfo.TargetData[]{
8684                 new ShareTargetInfo.TargetData(null, null, null, null, null, null, "video/mp4"),
8685                 new ShareTargetInfo.TargetData("content", null, null, null, null, null, "video/*")},
8686                 "com.test.directshare.TestActivity5",
8687                 new String[]{"com.test.category.CATEGORY5", "com.test.category.CATEGORY6"}));
8688 
8689         addManifestShortcutResource(
8690                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8691                 R.xml.shortcut_share_targets);
8692         updatePackageVersion(CALLING_PACKAGE_1, 1);
8693         mService.mPackageMonitor.onReceive(getTestContext(),
8694                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8695 
8696         List<ShareTargetInfo> shareTargets = getCallerShareTargets();
8697 
8698         assertNotNull(shareTargets);
8699         assertEquals(expectedValues.size(), shareTargets.size());
8700 
8701         for (int i = 0; i < expectedValues.size(); i++) {
8702             ShareTargetInfo expected = expectedValues.get(i);
8703             ShareTargetInfo actual = shareTargets.get(i);
8704 
8705             assertEquals(expected.mTargetData.length, actual.mTargetData.length);
8706             for (int j = 0; j < expected.mTargetData.length; j++) {
8707                 assertEquals(expected.mTargetData[j].mScheme, actual.mTargetData[j].mScheme);
8708                 assertEquals(expected.mTargetData[j].mHost, actual.mTargetData[j].mHost);
8709                 assertEquals(expected.mTargetData[j].mPort, actual.mTargetData[j].mPort);
8710                 assertEquals(expected.mTargetData[j].mPath, actual.mTargetData[j].mPath);
8711                 assertEquals(expected.mTargetData[j].mPathPrefix,
8712                         actual.mTargetData[j].mPathPrefix);
8713                 assertEquals(expected.mTargetData[j].mPathPattern,
8714                         actual.mTargetData[j].mPathPattern);
8715                 assertEquals(expected.mTargetData[j].mMimeType, actual.mTargetData[j].mMimeType);
8716             }
8717 
8718             assertEquals(expected.mTargetClass, actual.mTargetClass);
8719 
8720             assertEquals(expected.mCategories.length, actual.mCategories.length);
8721             for (int j = 0; j < expected.mCategories.length; j++) {
8722                 assertEquals(expected.mCategories[j], actual.mCategories[j]);
8723             }
8724         }
8725     }
8726 
testShareTargetInfo_saveToXml()8727     public void testShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
8728         List<ShareTargetInfo> expectedValues = new ArrayList<>();
8729         expectedValues.add(new ShareTargetInfo(
8730                 new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData(
8731                         "http", "www.google.com", "1234", "somePath", "somePathPattern",
8732                         "somePathPrefix", "text/plain")}, "com.test.directshare.TestActivity1",
8733                 new String[]{"com.test.category.CATEGORY1", "com.test.category.CATEGORY2"}));
8734         expectedValues.add(new ShareTargetInfo(new ShareTargetInfo.TargetData[]{
8735                 new ShareTargetInfo.TargetData(null, null, null, null, null, null, "video/mp4"),
8736                 new ShareTargetInfo.TargetData("content", null, null, null, null, null, "video/*")},
8737                 "com.test.directshare.TestActivity5",
8738                 new String[]{"com.test.category.CATEGORY5", "com.test.category.CATEGORY6"}));
8739 
8740         // Write ShareTargets to Xml
8741         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
8742         final TypedXmlSerializer outXml = Xml.newFastSerializer();
8743         outXml.setOutput(outStream, StandardCharsets.UTF_8.name());
8744         outXml.startDocument(null, true);
8745         for (int i = 0; i < expectedValues.size(); i++) {
8746             expectedValues.get(i).saveToXml(outXml);
8747         }
8748         outXml.endDocument();
8749         outXml.flush();
8750 
8751         // Read ShareTargets from Xml
8752         ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
8753         TypedXmlPullParser parser = Xml.newFastPullParser();
8754         parser.setInput(new InputStreamReader(inStream));
8755         List<ShareTargetInfo> shareTargets = new ArrayList<>();
8756         int type;
8757         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
8758             if (type == XmlPullParser.START_TAG && parser.getName().equals("share-target")) {
8759                 shareTargets.add(ShareTargetInfo.loadFromXml(parser));
8760             }
8761         }
8762 
8763         // Assert two lists are equal
8764         assertNotNull(shareTargets);
8765         assertEquals(expectedValues.size(), shareTargets.size());
8766 
8767         for (int i = 0; i < expectedValues.size(); i++) {
8768             ShareTargetInfo expected = expectedValues.get(i);
8769             ShareTargetInfo actual = shareTargets.get(i);
8770 
8771             assertEquals(expected.mTargetData.length, actual.mTargetData.length);
8772             for (int j = 0; j < expected.mTargetData.length; j++) {
8773                 assertEquals(expected.mTargetData[j].mScheme, actual.mTargetData[j].mScheme);
8774                 assertEquals(expected.mTargetData[j].mHost, actual.mTargetData[j].mHost);
8775                 assertEquals(expected.mTargetData[j].mPort, actual.mTargetData[j].mPort);
8776                 assertEquals(expected.mTargetData[j].mPath, actual.mTargetData[j].mPath);
8777                 assertEquals(expected.mTargetData[j].mPathPrefix,
8778                         actual.mTargetData[j].mPathPrefix);
8779                 assertEquals(expected.mTargetData[j].mPathPattern,
8780                         actual.mTargetData[j].mPathPattern);
8781                 assertEquals(expected.mTargetData[j].mMimeType, actual.mTargetData[j].mMimeType);
8782             }
8783 
8784             assertEquals(expected.mTargetClass, actual.mTargetClass);
8785 
8786             assertEquals(expected.mCategories.length, actual.mCategories.length);
8787             for (int j = 0; j < expected.mCategories.length; j++) {
8788                 assertEquals(expected.mCategories[j], actual.mCategories[j]);
8789             }
8790         }
8791     }
8792 
testIsSharingShortcut()8793     public void testIsSharingShortcut() throws IntentFilter.MalformedMimeTypeException {
8794         addManifestShortcutResource(
8795                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8796                 R.xml.shortcut_share_targets);
8797         updatePackageVersion(CALLING_PACKAGE_1, 1);
8798         mService.mPackageMonitor.onReceive(getTestContext(),
8799                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8800 
8801         setCaller(CALLING_PACKAGE_1, USER_0);
8802 
8803         final ShortcutInfo s1 = makeShortcutWithCategory("s1",
8804                 set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2"));
8805         final ShortcutInfo s2 = makeShortcutWithCategory("s2",
8806                 set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6"));
8807         final ShortcutInfo s3 = makeShortcut("s3");
8808 
8809         assertTrue(mManager.setDynamicShortcuts(list(s1, s2, s3)));
8810         assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
8811                 "s1", "s2", "s3");
8812 
8813         IntentFilter filter_cat1 = new IntentFilter();
8814         filter_cat1.addDataType("text/plain");
8815         IntentFilter filter_cat5 = new IntentFilter();
8816         filter_cat5.addDataType("video/*");
8817         IntentFilter filter_any = new IntentFilter();
8818         filter_any.addDataType("*/*");
8819 
8820         setCaller(LAUNCHER_1, USER_0);
8821         mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
8822 
8823         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
8824                 filter_cat1));
8825         assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
8826                 filter_cat5));
8827         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
8828                 filter_any));
8829 
8830         assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
8831                 filter_cat1));
8832         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
8833                 filter_cat5));
8834         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
8835                 filter_any));
8836 
8837         assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
8838                 filter_any));
8839         assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s4", USER_0,
8840                 filter_any));
8841     }
8842 
testIsSharingShortcut_PinnedAndCachedOnlyShortcuts()8843     public void testIsSharingShortcut_PinnedAndCachedOnlyShortcuts()
8844             throws IntentFilter.MalformedMimeTypeException {
8845         addManifestShortcutResource(
8846                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
8847                 R.xml.shortcut_share_targets);
8848         updatePackageVersion(CALLING_PACKAGE_1, 1);
8849         mService.mPackageMonitor.onReceive(getTestContext(),
8850                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
8851 
8852         final ShortcutInfo s1 = makeShortcutWithCategory("s1",
8853                 set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2"));
8854         final ShortcutInfo s2 = makeShortcutWithCategory("s2",
8855                 set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6"));
8856         final ShortcutInfo s3 = makeShortcutWithCategory("s3",
8857                 set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6"));
8858         s1.setLongLived();
8859         s2.setLongLived();
8860 
8861         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8862             assertTrue(mManager.setDynamicShortcuts(list(s1, s2, s3)));
8863             assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
8864                     "s1", "s2", "s3");
8865         });
8866 
8867         IntentFilter filter_any = new IntentFilter();
8868         filter_any.addDataType("*/*");
8869 
8870         setCaller(LAUNCHER_1, USER_0);
8871         mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
8872 
8873         // Assert all are sharing shortcuts
8874         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
8875                 filter_any));
8876         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
8877                 filter_any));
8878         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
8879                 filter_any));
8880 
8881         mInjectCheckAccessShortcutsPermission = true;
8882         mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0,
8883                 CACHE_OWNER_0);
8884         mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
8885 
8886         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
8887             // Remove one cached shortcut, and leave one cached-only and pinned-only shortcuts.
8888             mManager.removeLongLivedShortcuts(list("s1"));
8889             mManager.removeDynamicShortcuts(list("s2, s3"));
8890         });
8891 
8892         assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
8893                 filter_any));
8894         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
8895                 filter_any));
8896         assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
8897                 filter_any));
8898     }
8899 
getFileUriFromResource(String fileName, int resId)8900     private Uri getFileUriFromResource(String fileName, int resId) throws IOException {
8901         File file = new File(getTestContext().getFilesDir(), fileName);
8902         // Make sure we are not leaving phantom files behind.
8903         assertFalse(file.exists());
8904         try (InputStream source = getTestContext().getResources().openRawResource(resId);
8905              OutputStream target = new FileOutputStream(file)) {
8906             byte[] buffer = new byte[1024];
8907             for (int len = source.read(buffer); len >= 0; len = source.read(buffer)) {
8908                 target.write(buffer, 0, len);
8909             }
8910         }
8911         assertTrue(file.exists());
8912         return Uri.fromFile(file);
8913     }
8914 
deleteUriFile(String fileName)8915     private void deleteUriFile(String fileName) {
8916         File file = new File(getTestContext().getFilesDir(), fileName);
8917         if (file.exists()) {
8918             file.delete();
8919         }
8920     }
8921 }
8922