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