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