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