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