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