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