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