ShortcutManagerTest1.java revision b1588c0d3955a8574c3ae588568b2c393c7b5665
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();
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            assertShortcutIds(assertAllDynamic(
1919                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
1920                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
1921                                    | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
1922                    "s1", "s2");
1923            assertShortcutIds(assertAllDynamic(
1924                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
1925                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
1926                                    | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
1927                    "s2");
1928
1929            // Now pin some.
1930            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
1931                    list("s1", "s2"), getCallingUser());
1932
1933            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
1934                    list("s1", "s2"), getCallingUser());
1935
1936            assertShortcutIds(assertAllDynamic(
1937                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
1938                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
1939                                    | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
1940                    "s1", "s2");
1941
1942            // S1 was not visible to it, so shouldn't be pinned.
1943            assertShortcutIds(assertAllDynamic(
1944                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
1945                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
1946                                    | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
1947                    "s2");
1948        });
1949
1950        // Re-initialize and load from the files.
1951        mService.saveDirtyInfo();
1952        initService();
1953
1954        // Load from file.
1955        mService.handleUnlockUser(USER_0);
1956
1957        // Make sure package info is restored too.
1958        runWithCaller(LAUNCHER_1, USER_0, () -> {
1959            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
1960                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
1961                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
1962                    "s3");
1963            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
1964                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
1965                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
1966                    "s1", "s2");
1967        });
1968        runWithCaller(LAUNCHER_2, USER_0, () -> {
1969            assertShortcutIds(assertAllDynamic(
1970                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
1971                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
1972                                    | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
1973                    "s1", "s2");
1974            assertShortcutIds(assertAllDynamic(
1975                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
1976                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
1977                                    | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
1978                    "s2");
1979        });
1980
1981        // Delete all dynamic.
1982        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1983            mManager.removeAllDynamicShortcuts();
1984
1985            assertEquals(0, mManager.getDynamicShortcuts().size());
1986            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3");
1987        });
1988        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1989            mManager.removeAllDynamicShortcuts();
1990
1991            assertEquals(0, mManager.getDynamicShortcuts().size());
1992            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s2", "s1");
1993        });
1994
1995        runWithCaller(LAUNCHER_1, USER_0, () -> {
1996            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
1997                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
1998                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
1999                    "s3");
2000
2001            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2002                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2003                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2004                    "s1", "s2");
2005
2006            // from all packages.
2007            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2008                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, null,
2009                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2010                    "s1", "s2", "s3");
2011
2012            // Update pined.  Note s2 and s3 are actually available, but not visible to this
2013            // launcher, so still can't be pinned.
2014            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
2015                    getCallingUser());
2016
2017            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2018                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2019                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2020                    "s3");
2021        });
2022        // Re-publish s1.
2023        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2024            assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
2025
2026            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
2027            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3");
2028        });
2029        runWithCaller(LAUNCHER_1, USER_0, () -> {
2030            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2031                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2032                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2033                    "s3");
2034
2035            // Now "s1" is visible, so can be pinned.
2036            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
2037                    getCallingUser());
2038
2039            assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
2040                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2041                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
2042                    "s1", "s3");
2043        });
2044
2045        // Now clear pinned shortcuts.  First, from launcher 1.
2046        runWithCaller(LAUNCHER_1, USER_0, () -> {
2047            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
2048            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
2049
2050            assertEquals(0,
2051                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2052                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2053            assertEquals(0,
2054                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2055                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2056        });
2057        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2058            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
2059            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2");
2060        });
2061        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2062            assertEquals(0, mManager.getDynamicShortcuts().size());
2063            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s2");
2064        });
2065
2066        // Clear all pins from launcher 2.
2067        runWithCaller(LAUNCHER_2, USER_0, () -> {
2068            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
2069            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
2070
2071            assertEquals(0,
2072                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2073                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2074            assertEquals(0,
2075                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2076                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
2077        });
2078        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2079            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
2080            assertEquals(0, mManager.getPinnedShortcuts().size());
2081        });
2082        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2083            assertEquals(0, mManager.getDynamicShortcuts().size());
2084            assertEquals(0, mManager.getPinnedShortcuts().size());
2085        });
2086    }
2087
2088    public void testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
2089        // Create some shortcuts.
2090        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2091            assertTrue(mManager.setDynamicShortcuts(list(
2092                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2093        });
2094        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2095            assertTrue(mManager.setDynamicShortcuts(list(
2096                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2097        });
2098
2099        mRunningUsers.put(USER_10, true);
2100
2101        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
2102            assertTrue(mManager.setDynamicShortcuts(list(
2103                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
2104                    makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
2105        });
2106
2107        // Pin some shortcuts and see the result.
2108
2109        runWithCaller(LAUNCHER_1, USER_0, () -> {
2110            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2111                    list("s1"), HANDLE_USER_0);
2112
2113            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2114                    list("s1", "s2", "s3"), HANDLE_USER_0);
2115        });
2116
2117        runWithCaller(LAUNCHER_1, USER_P0, () -> {
2118            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2119                    list("s2"), HANDLE_USER_0);
2120
2121            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2122                    list("s2", "s3"), HANDLE_USER_0);
2123        });
2124
2125        runWithCaller(LAUNCHER_2, USER_P0, () -> {
2126            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2127                    list("s3"), HANDLE_USER_0);
2128
2129            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2130                    list("s3"), HANDLE_USER_0);
2131        });
2132
2133        runWithCaller(LAUNCHER_2, USER_10, () -> {
2134            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2135                    list("s1", "s2", "s3"), HANDLE_USER_10);
2136        });
2137
2138        // First, make sure managed profile can't see other profiles.
2139        runWithCaller(LAUNCHER_1, USER_P1, () -> {
2140
2141            final ShortcutQuery q = new ShortcutQuery().setQueryFlags(
2142                    ShortcutQuery.FLAG_MATCH_DYNAMIC | ShortcutQuery.FLAG_MATCH_PINNED
2143                            | ShortcutQuery.FLAG_MATCH_MANIFEST);
2144
2145            // No shortcuts are visible.
2146            assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
2147
2148            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
2149
2150            // Should have no effects.
2151            assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
2152
2153            assertShortcutNotLaunched(CALLING_PACKAGE_1, "s1", USER_0);
2154        });
2155
2156        // Cross profile pinning.
2157        final int PIN_AND_DYNAMIC = ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC;
2158
2159        runWithCaller(LAUNCHER_1, USER_0, () -> {
2160            assertShortcutIds(assertAllPinned(
2161                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2162                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2163                    "s1");
2164            assertShortcutIds(assertAllDynamic(
2165                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2166                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2167                    "s1", "s2", "s3");
2168            assertShortcutIds(assertAllDynamicOrPinned(
2169                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2170                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2171                    "s1", "s2", "s3");
2172
2173            assertShortcutIds(assertAllPinned(
2174                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2175                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2176                    "s1", "s2", "s3");
2177            assertShortcutIds(assertAllDynamic(
2178                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2179                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2180                    "s1", "s2", "s3");
2181            assertShortcutIds(assertAllDynamicOrPinned(
2182                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2183                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2184                    "s1", "s2", "s3");
2185
2186            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2187            assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2188            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2189
2190            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2191            assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2192            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2193
2194            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2195                    SecurityException.class);
2196            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2197                    SecurityException.class);
2198            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2199                    SecurityException.class);
2200            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2201                    SecurityException.class);
2202            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2203                    SecurityException.class);
2204            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2205                    SecurityException.class);
2206        });
2207        runWithCaller(LAUNCHER_1, USER_P0, () -> {
2208            assertShortcutIds(assertAllPinned(
2209                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2210                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2211                    "s2");
2212            assertShortcutIds(assertAllDynamic(
2213                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2214                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2215                    "s1", "s2", "s3");
2216            assertShortcutIds(assertAllDynamicOrPinned(
2217                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2218                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2219                    "s1", "s2", "s3");
2220
2221            assertShortcutIds(assertAllPinned(
2222                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2223                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2224                    "s2", "s3");
2225            assertShortcutIds(assertAllDynamic(
2226                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2227                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2228                    "s1", "s2", "s3");
2229            assertShortcutIds(assertAllDynamicOrPinned(
2230                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2231                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2232                    "s1", "s2", "s3");
2233
2234            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2235            assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2236            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2237
2238            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2239            assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2240            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2241
2242            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2243                    SecurityException.class);
2244            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2245                    SecurityException.class);
2246            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2247                    SecurityException.class);
2248            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2249                    SecurityException.class);
2250            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2251                    SecurityException.class);
2252            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2253                    SecurityException.class);
2254        });
2255        runWithCaller(LAUNCHER_2, USER_P0, () -> {
2256            assertShortcutIds(assertAllPinned(
2257                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2258                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2259                    "s3");
2260            assertShortcutIds(assertAllDynamic(
2261                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2262                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2263                    "s1", "s2", "s3");
2264            assertShortcutIds(assertAllDynamicOrPinned(
2265                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2266                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2267                    "s1", "s2", "s3");
2268
2269            assertShortcutIds(assertAllPinned(
2270                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2271                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2272                    "s3");
2273            assertShortcutIds(assertAllDynamic(
2274                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2275                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2276                    "s1", "s2", "s3");
2277            assertShortcutIds(assertAllDynamicOrPinned(
2278                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2279                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2280                    "s1", "s2", "s3");
2281
2282            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2283            assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2284            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2285
2286            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2287            assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2288            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2289
2290            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2291                    SecurityException.class);
2292            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2293                    SecurityException.class);
2294            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2295                    SecurityException.class);
2296            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2297                    SecurityException.class);
2298            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2299                    SecurityException.class);
2300            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2301                    SecurityException.class);
2302        });
2303        runWithCaller(LAUNCHER_2, USER_10, () -> {
2304            assertShortcutIds(assertAllPinned(
2305                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2306                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
2307                    "s1", "s2", "s3");
2308            assertShortcutIds(assertAllDynamic(
2309                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2310                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
2311                    "s1", "s2", "s3", "s4", "s5", "s6");
2312            assertShortcutIds(assertAllDynamicOrPinned(
2313                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2314                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
2315                    "s1", "s2", "s3", "s4", "s5", "s6");
2316        });
2317
2318        // Remove some dynamic shortcuts.
2319
2320        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2321            assertTrue(mManager.setDynamicShortcuts(list(
2322                    makeShortcut("s1"))));
2323        });
2324        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2325            assertTrue(mManager.setDynamicShortcuts(list(
2326                    makeShortcut("s1"))));
2327        });
2328        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
2329            assertTrue(mManager.setDynamicShortcuts(list(
2330                    makeShortcut("s1"))));
2331        });
2332
2333        runWithCaller(LAUNCHER_1, USER_0, () -> {
2334            assertShortcutIds(assertAllPinned(
2335                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2336                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2337                    "s1");
2338            assertShortcutIds(assertAllDynamic(
2339                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2340                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2341                    "s1");
2342            assertShortcutIds(assertAllDynamicOrPinned(
2343                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2344                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2345                    "s1");
2346
2347            assertShortcutIds(assertAllPinned(
2348                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2349                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2350                    "s1", "s2", "s3");
2351            assertShortcutIds(assertAllDynamic(
2352                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2353                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2354                    "s1");
2355            assertShortcutIds(assertAllDynamicOrPinned(
2356                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2357                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2358                    "s1", "s2", "s3");
2359
2360            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2361            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
2362                    ActivityNotFoundException.class);
2363            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
2364                    ActivityNotFoundException.class);
2365
2366            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2367            assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2368            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2369
2370            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2371                    SecurityException.class);
2372            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2373                    SecurityException.class);
2374            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2375                    SecurityException.class);
2376            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2377                    SecurityException.class);
2378            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2379                    SecurityException.class);
2380            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2381                    SecurityException.class);
2382        });
2383        runWithCaller(LAUNCHER_1, USER_P0, () -> {
2384            assertShortcutIds(assertAllPinned(
2385                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2386                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2387                    "s2");
2388            assertShortcutIds(assertAllDynamic(
2389                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2390                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2391                    "s1");
2392            assertShortcutIds(assertAllDynamicOrPinned(
2393                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2394                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2395                    "s1", "s2");
2396
2397            assertShortcutIds(assertAllPinned(
2398                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2399                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2400                    "s2", "s3");
2401            assertShortcutIds(assertAllDynamic(
2402                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2403                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2404                    "s1");
2405            assertShortcutIds(assertAllDynamicOrPinned(
2406                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2407                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2408                    "s1", "s2", "s3");
2409
2410            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2411            assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2412            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
2413                    ActivityNotFoundException.class);
2414
2415            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2416            assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2417            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2418
2419            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2420                    SecurityException.class);
2421            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2422                    SecurityException.class);
2423            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2424                    SecurityException.class);
2425            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2426                    SecurityException.class);
2427            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2428                    SecurityException.class);
2429            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2430                    SecurityException.class);
2431        });
2432        runWithCaller(LAUNCHER_2, USER_P0, () -> {
2433            assertShortcutIds(assertAllPinned(
2434                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2435                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2436                    "s3");
2437            assertShortcutIds(assertAllDynamic(
2438                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2439                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2440                    "s1");
2441            assertShortcutIds(assertAllDynamicOrPinned(
2442                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2443                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2444                    "s1", "s3");
2445
2446            assertShortcutIds(assertAllPinned(
2447                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2448                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2449                    "s3");
2450            assertShortcutIds(assertAllDynamic(
2451                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2452                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2453                    "s1");
2454            assertShortcutIds(assertAllDynamicOrPinned(
2455                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2456                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2457                    "s1", "s3");
2458
2459            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2460            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
2461                    ActivityNotFoundException.class);
2462            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2463
2464            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2465            assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
2466                    ActivityNotFoundException.class);
2467            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2468
2469            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2470                    SecurityException.class);
2471            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2472                    SecurityException.class);
2473            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2474                    SecurityException.class);
2475            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2476                    SecurityException.class);
2477            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2478                    SecurityException.class);
2479            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2480                    SecurityException.class);
2481        });
2482        runWithCaller(LAUNCHER_2, USER_10, () -> {
2483            assertShortcutIds(assertAllPinned(
2484                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2485                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
2486                    "s1", "s2", "s3");
2487            assertShortcutIds(assertAllDynamic(
2488                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2489                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
2490                    "s1");
2491            assertShortcutIds(assertAllDynamicOrPinned(
2492                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2493                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
2494                    "s1", "s2", "s3");
2495
2496            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
2497                    SecurityException.class);
2498            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
2499                    SecurityException.class);
2500            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
2501                    SecurityException.class);
2502
2503            assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s1", USER_0,
2504                    SecurityException.class);
2505            assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
2506                    SecurityException.class);
2507            assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s3", USER_0,
2508                    SecurityException.class);
2509
2510            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
2511            assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
2512            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
2513            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2514                    ActivityNotFoundException.class);
2515            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2516                    ActivityNotFoundException.class);
2517            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2518                    ActivityNotFoundException.class);
2519        });
2520
2521        // Save & load and make sure we still have the same information.
2522        mService.saveDirtyInfo();
2523        initService();
2524        mService.handleUnlockUser(USER_0);
2525
2526        runWithCaller(LAUNCHER_1, USER_0, () -> {
2527            assertShortcutIds(assertAllPinned(
2528                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2529                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2530                    "s1");
2531            assertShortcutIds(assertAllDynamic(
2532                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2533                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2534                    "s1");
2535            assertShortcutIds(assertAllDynamicOrPinned(
2536                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2537                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2538                    "s1");
2539
2540            assertShortcutIds(assertAllPinned(
2541                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2542                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2543                    "s1", "s2", "s3");
2544            assertShortcutIds(assertAllDynamic(
2545                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2546                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2547                    "s1");
2548            assertShortcutIds(assertAllDynamicOrPinned(
2549                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2550                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2551                    "s1", "s2", "s3");
2552
2553            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2554            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
2555                    ActivityNotFoundException.class);
2556            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
2557                    ActivityNotFoundException.class);
2558
2559            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2560            assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2561            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2562
2563            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2564                    SecurityException.class);
2565            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2566                    SecurityException.class);
2567            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2568                    SecurityException.class);
2569            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2570                    SecurityException.class);
2571            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2572                    SecurityException.class);
2573            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2574                    SecurityException.class);
2575        });
2576        runWithCaller(LAUNCHER_1, USER_P0, () -> {
2577            assertShortcutIds(assertAllPinned(
2578                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2579                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2580                    "s2");
2581            assertShortcutIds(assertAllDynamic(
2582                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2583                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2584                    "s1");
2585            assertShortcutIds(assertAllDynamicOrPinned(
2586                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2587                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2588                    "s1", "s2");
2589
2590            assertShortcutIds(assertAllPinned(
2591                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2592                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2593                    "s2", "s3");
2594            assertShortcutIds(assertAllDynamic(
2595                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2596                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2597                    "s1");
2598            assertShortcutIds(assertAllDynamicOrPinned(
2599                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2600                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2601                    "s1", "s2", "s3");
2602
2603            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2604            assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
2605            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
2606                    ActivityNotFoundException.class);
2607
2608            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2609            assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
2610            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2611
2612            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2613                    SecurityException.class);
2614            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2615                    SecurityException.class);
2616            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2617                    SecurityException.class);
2618            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2619                    SecurityException.class);
2620            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2621                    SecurityException.class);
2622            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2623                    SecurityException.class);
2624        });
2625        runWithCaller(LAUNCHER_2, USER_P0, () -> {
2626            assertShortcutIds(assertAllPinned(
2627                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2628                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2629                    "s3");
2630            assertShortcutIds(assertAllDynamic(
2631                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2632                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2633                    "s1");
2634            assertShortcutIds(assertAllDynamicOrPinned(
2635                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
2636                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2637                    "s1", "s3");
2638
2639            assertShortcutIds(assertAllPinned(
2640                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2641                    /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
2642                    "s3");
2643            assertShortcutIds(assertAllDynamic(
2644                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2645                    /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
2646                    "s1");
2647            assertShortcutIds(assertAllDynamicOrPinned(
2648                    mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
2649                    /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
2650                    "s1", "s3");
2651
2652            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
2653            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
2654                    ActivityNotFoundException.class);
2655            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2656
2657            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
2658            assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
2659                    ActivityNotFoundException.class);
2660            assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
2661
2662            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
2663                    SecurityException.class);
2664            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
2665                    SecurityException.class);
2666            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
2667                    SecurityException.class);
2668            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
2669                    SecurityException.class);
2670            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
2671                    SecurityException.class);
2672            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
2673                    SecurityException.class);
2674        });
2675    }
2676
2677    public void testStartShortcut() {
2678        // Create some shortcuts.
2679        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2680            final ShortcutInfo s1_1 = makeShortcut(
2681                    "s1",
2682                    "Title 1",
2683                    makeComponent(ShortcutActivity.class),
2684                    /* icon =*/ null,
2685                    new Intent[]{makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
2686                            "key1", "val1", "nest", makeBundle("key", 123))
2687                            .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
2688                            new Intent("act2").setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)},
2689                    /* rank */ 10);
2690
2691            final ShortcutInfo s1_2 = makeShortcut(
2692                    "s2",
2693                    "Title 2",
2694            /* activity */ null,
2695            /* icon =*/ null,
2696                    makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
2697            /* rank */ 12);
2698
2699            final ShortcutInfo s1_3 = makeShortcut("s3");
2700
2701            assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3)));
2702        });
2703
2704        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2705            final ShortcutInfo s2_1 = makeShortcut(
2706                    "s1",
2707                    "ABC",
2708                    makeComponent(ShortcutActivity.class),
2709                    /* icon =*/ null,
2710                    makeIntent(Intent.ACTION_ANSWER, ShortcutActivity.class,
2711                            "key1", "val1", "nest", makeBundle("key", 123)),
2712                    /* weight */ 10);
2713            assertTrue(mManager.setDynamicShortcuts(list(s2_1)));
2714        });
2715
2716        // Pin some.
2717        runWithCaller(LAUNCHER_1, USER_0, () -> {
2718            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
2719                    list("s1", "s2"), getCallingUser());
2720
2721            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
2722                    list("s1"), getCallingUser());
2723        });
2724
2725        // Just to make it complicated, delete some.
2726        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2727            mManager.removeDynamicShortcuts(list("s2"));
2728        });
2729
2730        runWithCaller(LAUNCHER_1, USER_0, () -> {
2731            final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_0);
2732            assertEquals(ShortcutActivity2.class.getName(),
2733                    intents[0].getComponent().getClassName());
2734            assertEquals(Intent.ACTION_ASSIST,
2735                    intents[0].getAction());
2736            assertEquals(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK,
2737                    intents[0].getFlags());
2738
2739            assertEquals("act2",
2740                    intents[1].getAction());
2741            assertEquals(Intent.FLAG_ACTIVITY_NO_ANIMATION,
2742                    intents[1].getFlags());
2743
2744            assertEquals(
2745                    ShortcutActivity3.class.getName(),
2746                    launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_0)
2747                            .getComponent().getClassName());
2748            assertEquals(
2749                    ShortcutActivity.class.getName(),
2750                    launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_0)
2751                            .getComponent().getClassName());
2752
2753            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
2754
2755            assertShortcutNotLaunched("no-such-package", "s2", USER_0);
2756            assertShortcutNotLaunched(CALLING_PACKAGE_1, "xxxx", USER_0);
2757        });
2758
2759        // LAUNCHER_1 is no longer the default launcher
2760        setDefaultLauncherChecker((pkg, userId) -> false);
2761
2762        runWithCaller(LAUNCHER_1, USER_0, () -> {
2763            // Not the default launcher, but pinned shortcuts are still lauchable.
2764            final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_0);
2765            assertEquals(ShortcutActivity2.class.getName(),
2766                    intents[0].getComponent().getClassName());
2767            assertEquals(Intent.ACTION_ASSIST,
2768                    intents[0].getAction());
2769            assertEquals(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK,
2770                    intents[0].getFlags());
2771
2772            assertEquals("act2",
2773                    intents[1].getAction());
2774            assertEquals(Intent.FLAG_ACTIVITY_NO_ANIMATION,
2775                    intents[1].getFlags());
2776            assertEquals(
2777                    ShortcutActivity3.class.getName(),
2778                    launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_0)
2779                            .getComponent().getClassName());
2780            assertEquals(
2781                    ShortcutActivity.class.getName(),
2782                    launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_0)
2783                            .getComponent().getClassName());
2784
2785            // Not pinned, so not lauchable.
2786        });
2787
2788        // Test inner errors.
2789        runWithCaller(LAUNCHER_1, USER_0, () -> {
2790            // Not launchable.
2791            doReturn(ActivityManager.START_CLASS_NOT_FOUND)
2792                    .when(mMockActivityManagerInternal).startActivitiesAsPackage(
2793                    anyStringOrNull(), anyInt(),
2794                    anyOrNull(Intent[].class), anyOrNull(Bundle.class));
2795            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
2796                    ActivityNotFoundException.class);
2797
2798            // Still not launchable.
2799            doReturn(ActivityManager.START_CLASS_NOT_FOUND)
2800                    .when(mMockActivityManagerInternal)
2801                    .startActivitiesAsPackage(
2802                            anyStringOrNull(), anyInt(),
2803                            anyOrNull(Intent[].class), anyOrNull(Bundle.class));
2804            assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
2805                    ActivityNotFoundException.class);
2806        });
2807
2808
2809        // TODO Check extra, etc
2810    }
2811
2812    public void testLauncherCallback() throws Throwable {
2813        // Disable throttling for this test.
2814        mService.updateConfigurationLocked(
2815                ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
2816                        + ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
2817        );
2818
2819        setCaller(LAUNCHER_1, USER_0);
2820
2821        assertForLauncherCallback(mLauncherApps, () -> {
2822            runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2823                assertTrue(mManager.setDynamicShortcuts(list(
2824                        makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2825            });
2826        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
2827                .haveIds("s1", "s2", "s3")
2828                .areAllWithKeyFieldsOnly()
2829                .areAllDynamic();
2830
2831        // From different package.
2832        assertForLauncherCallback(mLauncherApps, () -> {
2833            runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
2834                assertTrue(mManager.setDynamicShortcuts(list(
2835                        makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2836            });
2837        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_0)
2838                .haveIds("s1", "s2", "s3")
2839                .areAllWithKeyFieldsOnly()
2840                .areAllDynamic();
2841
2842        mRunningUsers.put(USER_10, true);
2843
2844        // Different user, callback shouldn't be called.
2845        assertForLauncherCallback(mLauncherApps, () -> {
2846            runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
2847                assertTrue(mManager.setDynamicShortcuts(list(
2848                        makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
2849            });
2850        }).assertNoCallbackCalled();
2851
2852
2853        // Test for addDynamicShortcuts.
2854        assertForLauncherCallback(mLauncherApps, () -> {
2855            runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2856                assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s4"))));
2857            });
2858        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
2859                .haveIds("s1", "s2", "s3", "s4")
2860                .areAllWithKeyFieldsOnly()
2861                .areAllDynamic();
2862
2863        // Test for remove
2864        assertForLauncherCallback(mLauncherApps, () -> {
2865            runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2866                mManager.removeDynamicShortcuts(list("s1"));
2867            });
2868        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
2869                .haveIds("s2", "s3", "s4")
2870                .areAllWithKeyFieldsOnly()
2871                .areAllDynamic();
2872
2873        // Test for update
2874        assertForLauncherCallback(mLauncherApps, () -> {
2875            runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2876                assertTrue(mManager.updateShortcuts(list(
2877                        makeShortcut("s1"), makeShortcut("s2"))));
2878            });
2879        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
2880                // All remaining shortcuts will be passed regardless of what's been updated.
2881                .haveIds("s2", "s3", "s4")
2882                .areAllWithKeyFieldsOnly()
2883                .areAllDynamic();
2884
2885        // Test for deleteAll
2886        assertForLauncherCallback(mLauncherApps, () -> {
2887            runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2888                mManager.removeAllDynamicShortcuts();
2889            });
2890        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
2891                .isEmpty();
2892
2893        // Update package1 with manifest shortcuts
2894        assertForLauncherCallback(mLauncherApps, () -> {
2895            addManifestShortcutResource(
2896                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
2897                    R.xml.shortcut_2);
2898            updatePackageVersion(CALLING_PACKAGE_1, 1);
2899            mService.mPackageMonitor.onReceive(getTestContext(),
2900                    genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
2901        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
2902                .areAllManifest()
2903                .areAllWithKeyFieldsOnly()
2904                .haveIds("ms1", "ms2");
2905
2906        // Make sure pinned shortcuts are passed too.
2907        // 1. Add dynamic shortcuts.
2908        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
2909            assertTrue(mManager.setDynamicShortcuts(list(
2910                    makeShortcut("s1"), makeShortcut("s2"))));
2911        });
2912
2913        // 2. Pin some.
2914        runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> {
2915            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_0);
2916        });
2917        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
2918            assertWith(getCallerShortcuts())
2919                    .haveIds("ms1", "ms2", "s1", "s2")
2920                    .areAllEnabled()
2921
2922                    .selectByIds("ms1", "ms2")
2923                    .areAllManifest()
2924
2925                    .revertToOriginalList()
2926                    .selectByIds("s1", "s2")
2927                    .areAllDynamic()
2928            ;
2929        });
2930
2931        // 3 Update the app with no manifest shortcuts.  (Pinned one will survive.)
2932        addManifestShortcutResource(
2933                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
2934                R.xml.shortcut_0);
2935        updatePackageVersion(CALLING_PACKAGE_1, 1);
2936        mService.mPackageMonitor.onReceive(getTestContext(),
2937                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
2938
2939        assertForLauncherCallback(mLauncherApps, () -> {
2940            runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
2941                mManager.removeDynamicShortcuts(list("s2"));
2942
2943                assertWith(getCallerShortcuts())
2944                        .haveIds("ms2", "s1", "s2")
2945
2946                        .selectByIds("ms2")
2947                        .areAllNotManifest()
2948                        .areAllPinned()
2949                        .areAllImmutable()
2950                        .areAllDisabled()
2951
2952                        .revertToOriginalList()
2953                        .selectByIds("s1")
2954                        .areAllDynamic()
2955                        .areAllNotPinned()
2956                        .areAllEnabled()
2957
2958                        .revertToOriginalList()
2959                        .selectByIds("s2")
2960                        .areAllNotDynamic()
2961                        .areAllPinned()
2962                        .areAllEnabled()
2963                ;
2964            });
2965        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
2966                .haveIds("ms2", "s1", "s2")
2967                .areAllWithKeyFieldsOnly();
2968
2969        // Remove CALLING_PACKAGE_2
2970        assertForLauncherCallback(mLauncherApps, () -> {
2971            uninstallPackage(USER_0, CALLING_PACKAGE_2);
2972            mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_0, USER_0,
2973                    /* appStillExists = */ false);
2974        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_0)
2975                .isEmpty();
2976    }
2977
2978    public void testLauncherCallback_crossProfile() throws Throwable {
2979        prepareCrossProfileDataSet();
2980
2981        final Handler h = new Handler(Looper.getMainLooper());
2982
2983        final LauncherApps.Callback c0_1 = mock(LauncherApps.Callback.class);
2984        final LauncherApps.Callback c0_2 = mock(LauncherApps.Callback.class);
2985        final LauncherApps.Callback c0_3 = mock(LauncherApps.Callback.class);
2986        final LauncherApps.Callback c0_4 = mock(LauncherApps.Callback.class);
2987
2988        final LauncherApps.Callback cP0_1 = mock(LauncherApps.Callback.class);
2989        final LauncherApps.Callback cP1_1 = mock(LauncherApps.Callback.class);
2990        final LauncherApps.Callback c10_1 = mock(LauncherApps.Callback.class);
2991        final LauncherApps.Callback c10_2 = mock(LauncherApps.Callback.class);
2992        final LauncherApps.Callback c11_1 = mock(LauncherApps.Callback.class);
2993
2994        final List<LauncherApps.Callback> all =
2995                list(c0_1, c0_2, c0_3, c0_4, cP0_1, c10_1, c11_1);
2996
2997        setDefaultLauncherChecker((pkg, userId) -> {
2998            switch (userId) {
2999                case USER_0:
3000                    return LAUNCHER_2.equals(pkg);
3001                case USER_P0:
3002                    return LAUNCHER_1.equals(pkg);
3003                case USER_P1:
3004                    return LAUNCHER_1.equals(pkg);
3005                case USER_10:
3006                    return LAUNCHER_1.equals(pkg);
3007                case USER_11:
3008                    return LAUNCHER_1.equals(pkg);
3009                default:
3010                    return false;
3011            }
3012        });
3013
3014        runWithCaller(LAUNCHER_1, USER_0, () -> mLauncherApps.registerCallback(c0_1, h));
3015        runWithCaller(LAUNCHER_2, USER_0, () -> mLauncherApps.registerCallback(c0_2, h));
3016        runWithCaller(LAUNCHER_3, USER_0, () -> mLauncherApps.registerCallback(c0_3, h));
3017        runWithCaller(LAUNCHER_4, USER_0, () -> mLauncherApps.registerCallback(c0_4, h));
3018        runWithCaller(LAUNCHER_1, USER_P0, () -> mLauncherApps.registerCallback(cP0_1, h));
3019        runWithCaller(LAUNCHER_1, USER_P1, () -> mLauncherApps.registerCallback(cP1_1, h));
3020        runWithCaller(LAUNCHER_1, USER_10, () -> mLauncherApps.registerCallback(c10_1, h));
3021        runWithCaller(LAUNCHER_2, USER_10, () -> mLauncherApps.registerCallback(c10_2, h));
3022        runWithCaller(LAUNCHER_1, USER_11, () -> mLauncherApps.registerCallback(c11_1, h));
3023
3024        // User 0.
3025
3026        resetAll(all);
3027        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3028            mManager.removeDynamicShortcuts(list());
3029        });
3030        waitOnMainThread();
3031
3032        assertCallbackNotReceived(c0_1);
3033        assertCallbackNotReceived(c0_3);
3034        assertCallbackNotReceived(c0_4);
3035        assertCallbackNotReceived(c10_1);
3036        assertCallbackNotReceived(c10_2);
3037        assertCallbackNotReceived(c11_1);
3038        assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3");
3039        assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
3040        assertCallbackNotReceived(cP1_1);
3041
3042        // User 0, different package.
3043
3044        resetAll(all);
3045        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
3046            mManager.removeDynamicShortcuts(list());
3047        });
3048        waitOnMainThread();
3049
3050        assertCallbackNotReceived(c0_1);
3051        assertCallbackNotReceived(c0_3);
3052        assertCallbackNotReceived(c0_4);
3053        assertCallbackNotReceived(c10_1);
3054        assertCallbackNotReceived(c10_2);
3055        assertCallbackNotReceived(c11_1);
3056        assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_3, "s1", "s2", "s3", "s4");
3057        assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_3,
3058                "s1", "s2", "s3", "s4", "s5", "s6");
3059        assertCallbackNotReceived(cP1_1);
3060
3061        // Work profile.
3062        resetAll(all);
3063        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
3064            mManager.removeDynamicShortcuts(list());
3065        });
3066        waitOnMainThread();
3067
3068        assertCallbackNotReceived(c0_1);
3069        assertCallbackNotReceived(c0_3);
3070        assertCallbackNotReceived(c0_4);
3071        assertCallbackNotReceived(c10_1);
3072        assertCallbackNotReceived(c10_2);
3073        assertCallbackNotReceived(c11_1);
3074        assertCallbackReceived(c0_2, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s5");
3075        assertCallbackReceived(cP0_1, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
3076        assertCallbackNotReceived(cP1_1);
3077
3078        // Normal secondary user.
3079        mRunningUsers.put(USER_10, true);
3080
3081        resetAll(all);
3082        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3083            mManager.removeDynamicShortcuts(list());
3084        });
3085        waitOnMainThread();
3086
3087        assertCallbackNotReceived(c0_1);
3088        assertCallbackNotReceived(c0_2);
3089        assertCallbackNotReceived(c0_3);
3090        assertCallbackNotReceived(c0_4);
3091        assertCallbackNotReceived(cP0_1);
3092        assertCallbackNotReceived(c10_2);
3093        assertCallbackNotReceived(c11_1);
3094        assertCallbackReceived(c10_1, HANDLE_USER_10, CALLING_PACKAGE_1,
3095                "x1", "x2", "x3", "x4", "x5");
3096        assertCallbackNotReceived(cP1_1);
3097    }
3098
3099    // === Test for persisting ===
3100
3101    public void testSaveAndLoadUser_empty() {
3102        assertTrue(mManager.setDynamicShortcuts(list()));
3103
3104        Log.i(TAG, "Saved state");
3105        dumpsysOnLogcat();
3106        dumpUserFile(0);
3107
3108        // Restore.
3109        mService.saveDirtyInfo();
3110        initService();
3111
3112        assertEquals(0, mManager.getDynamicShortcuts().size());
3113    }
3114
3115    /**
3116     * Try save and load, also stop/start the user.
3117     */
3118    public void testSaveAndLoadUser() {
3119        // First, create some shortcuts and save.
3120        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
3121            final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
3122            final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
3123                    getTestContext().getResources(), R.drawable.icon2));
3124
3125            final ShortcutInfo si1 = makeShortcut(
3126                    "s1",
3127                    "title1-1",
3128                    makeComponent(ShortcutActivity.class),
3129                    icon1,
3130                    makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
3131                            "key1", "val1", "nest", makeBundle("key", 123)),
3132                        /* weight */ 10);
3133
3134            final ShortcutInfo si2 = makeShortcut(
3135                    "s2",
3136                    "title1-2",
3137                        /* activity */ null,
3138                    icon2,
3139                    makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
3140                        /* weight */ 12);
3141
3142            assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
3143
3144            assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
3145            assertEquals(2, mManager.getRemainingCallCount());
3146        });
3147        runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
3148            final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_16x64);
3149            final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
3150                    getTestContext().getResources(), R.drawable.icon2));
3151
3152            final ShortcutInfo si1 = makeShortcut(
3153                    "s1",
3154                    "title2-1",
3155                    makeComponent(ShortcutActivity.class),
3156                    icon1,
3157                    makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
3158                            "key1", "val1", "nest", makeBundle("key", 123)),
3159                        /* weight */ 10);
3160
3161            final ShortcutInfo si2 = makeShortcut(
3162                    "s2",
3163                    "title2-2",
3164                        /* activity */ null,
3165                    icon2,
3166                    makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
3167                        /* weight */ 12);
3168
3169            assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
3170
3171            assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
3172            assertEquals(2, mManager.getRemainingCallCount());
3173        });
3174
3175        mRunningUsers.put(USER_10, true);
3176
3177        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3178            final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
3179            final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
3180                    getTestContext().getResources(), R.drawable.icon2));
3181
3182            final ShortcutInfo si1 = makeShortcut(
3183                    "s1",
3184                    "title10-1-1",
3185                    makeComponent(ShortcutActivity.class),
3186                    icon1,
3187                    makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
3188                            "key1", "val1", "nest", makeBundle("key", 123)),
3189                        /* weight */ 10);
3190
3191            final ShortcutInfo si2 = makeShortcut(
3192                    "s2",
3193                    "title10-1-2",
3194                        /* activity */ null,
3195                    icon2,
3196                    makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
3197                        /* weight */ 12);
3198
3199            assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
3200
3201            assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
3202            assertEquals(2, mManager.getRemainingCallCount());
3203        });
3204
3205        mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM).setLauncher(
3206                new ComponentName("pkg1", "class"));
3207
3208        // Restore.
3209        mService.saveDirtyInfo();
3210        initService();
3211
3212        // Before the load, the map should be empty.
3213        assertEquals(0, mService.getShortcutsForTest().size());
3214
3215        // this will pre-load the per-user info.
3216        mService.handleUnlockUser(UserHandle.USER_SYSTEM);
3217
3218        // Now it's loaded.
3219        assertEquals(1, mService.getShortcutsForTest().size());
3220
3221        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
3222            assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
3223                    mManager.getDynamicShortcuts()))), "s1", "s2");
3224            assertEquals(2, mManager.getRemainingCallCount());
3225
3226            assertEquals("title1-1", getCallerShortcut("s1").getTitle());
3227            assertEquals("title1-2", getCallerShortcut("s2").getTitle());
3228        });
3229        runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
3230            assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
3231                    mManager.getDynamicShortcuts()))), "s1", "s2");
3232            assertEquals(2, mManager.getRemainingCallCount());
3233
3234            assertEquals("title2-1", getCallerShortcut("s1").getTitle());
3235            assertEquals("title2-2", getCallerShortcut("s2").getTitle());
3236        });
3237
3238        assertEquals("pkg1", mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM)
3239                .getLastKnownLauncher().getPackageName());
3240
3241        // Start another user
3242        mService.handleUnlockUser(USER_10);
3243
3244        // Now the size is 2.
3245        assertEquals(2, mService.getShortcutsForTest().size());
3246
3247        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3248            assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
3249                    mManager.getDynamicShortcuts()))), "s1", "s2");
3250            assertEquals(2, mManager.getRemainingCallCount());
3251
3252            assertEquals("title10-1-1", getCallerShortcut("s1").getTitle());
3253            assertEquals("title10-1-2", getCallerShortcut("s2").getTitle());
3254        });
3255        assertNull(mService.getShortcutsForTest().get(USER_10).getLastKnownLauncher());
3256
3257        // Try stopping the user
3258        mService.handleStopUser(USER_10);
3259
3260        // Now it's unloaded.
3261        assertEquals(1, mService.getShortcutsForTest().size());
3262
3263        // TODO Check all other fields
3264    }
3265
3266    public void testCleanupPackage() {
3267        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3268            assertTrue(mManager.setDynamicShortcuts(list(
3269                    makeShortcut("s0_1"))));
3270        });
3271        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
3272            assertTrue(mManager.setDynamicShortcuts(list(
3273                    makeShortcut("s0_2"))));
3274        });
3275        runWithCaller(LAUNCHER_1, USER_0, () -> {
3276            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
3277                    HANDLE_USER_0);
3278            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
3279                    HANDLE_USER_0);
3280        });
3281        runWithCaller(LAUNCHER_2, USER_0, () -> {
3282            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
3283                    HANDLE_USER_0);
3284            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
3285                    HANDLE_USER_0);
3286        });
3287
3288        mRunningUsers.put(USER_10, true);
3289
3290        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3291            assertTrue(mManager.setDynamicShortcuts(list(
3292                    makeShortcut("s10_1"))));
3293        });
3294        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
3295            assertTrue(mManager.setDynamicShortcuts(list(
3296                    makeShortcut("s10_2"))));
3297        });
3298        runWithCaller(LAUNCHER_1, USER_10, () -> {
3299            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
3300                    HANDLE_USER_10);
3301            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
3302                    HANDLE_USER_10);
3303        });
3304        runWithCaller(LAUNCHER_2, USER_10, () -> {
3305            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
3306                    HANDLE_USER_10);
3307            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
3308                    HANDLE_USER_10);
3309        });
3310
3311        // Remove all dynamic shortcuts; now all shortcuts are just pinned.
3312        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3313            mManager.removeAllDynamicShortcuts();
3314        });
3315        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
3316            mManager.removeAllDynamicShortcuts();
3317        });
3318        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3319            mManager.removeAllDynamicShortcuts();
3320        });
3321        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
3322            mManager.removeAllDynamicShortcuts();
3323        });
3324
3325
3326        final SparseArray<ShortcutUser> users = mService.getShortcutsForTest();
3327        assertEquals(2, users.size());
3328        assertEquals(USER_0, users.keyAt(0));
3329        assertEquals(USER_10, users.keyAt(1));
3330
3331        final ShortcutUser user0 = users.get(USER_0);
3332        final ShortcutUser user10 = users.get(USER_10);
3333
3334
3335        // Check the registered packages.
3336        dumpsysOnLogcat();
3337        assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
3338                hashSet(user0.getAllPackagesForTest().keySet()));
3339        assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
3340                hashSet(user10.getAllPackagesForTest().keySet()));
3341        assertEquals(
3342                set(PackageWithUser.of(USER_0, LAUNCHER_1),
3343                        PackageWithUser.of(USER_0, LAUNCHER_2)),
3344                hashSet(user0.getAllLaunchersForTest().keySet()));
3345        assertEquals(
3346                set(PackageWithUser.of(USER_10, LAUNCHER_1),
3347                        PackageWithUser.of(USER_10, LAUNCHER_2)),
3348                hashSet(user10.getAllLaunchersForTest().keySet()));
3349        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
3350                "s0_1", "s0_2");
3351        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
3352                "s0_1", "s0_2");
3353        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
3354                "s10_1", "s10_2");
3355        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
3356                "s10_1", "s10_2");
3357        assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_0);
3358        assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
3359        assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
3360        assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
3361
3362        mService.saveDirtyInfo();
3363
3364        // Nonexistent package.
3365        uninstallPackage(USER_0, "abc");
3366        mService.cleanUpPackageLocked("abc", USER_0, USER_0, /* appStillExists = */ false);
3367
3368        // No changes.
3369        assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
3370                hashSet(user0.getAllPackagesForTest().keySet()));
3371        assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
3372                hashSet(user10.getAllPackagesForTest().keySet()));
3373        assertEquals(
3374                set(PackageWithUser.of(USER_0, LAUNCHER_1),
3375                        PackageWithUser.of(USER_0, LAUNCHER_2)),
3376                hashSet(user0.getAllLaunchersForTest().keySet()));
3377        assertEquals(
3378                set(PackageWithUser.of(USER_10, LAUNCHER_1),
3379                        PackageWithUser.of(USER_10, LAUNCHER_2)),
3380                hashSet(user10.getAllLaunchersForTest().keySet()));
3381        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
3382                "s0_1", "s0_2");
3383        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
3384                "s0_1", "s0_2");
3385        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
3386                "s10_1", "s10_2");
3387        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
3388                "s10_1", "s10_2");
3389        assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_0);
3390        assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
3391        assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
3392        assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
3393
3394        mService.saveDirtyInfo();
3395
3396        // Remove a package.
3397        uninstallPackage(USER_0, CALLING_PACKAGE_1);
3398        mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0, USER_0,
3399                /* appStillExists = */ false);
3400
3401        assertEquals(set(CALLING_PACKAGE_2),
3402                hashSet(user0.getAllPackagesForTest().keySet()));
3403        assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
3404                hashSet(user10.getAllPackagesForTest().keySet()));
3405        assertEquals(
3406                set(PackageWithUser.of(USER_0, LAUNCHER_1),
3407                        PackageWithUser.of(USER_0, LAUNCHER_2)),
3408                hashSet(user0.getAllLaunchersForTest().keySet()));
3409        assertEquals(
3410                set(PackageWithUser.of(USER_10, LAUNCHER_1),
3411                        PackageWithUser.of(USER_10, LAUNCHER_2)),
3412                hashSet(user10.getAllLaunchersForTest().keySet()));
3413        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
3414                "s0_2");
3415        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
3416                "s0_2");
3417        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
3418                "s10_1", "s10_2");
3419        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
3420                "s10_1", "s10_2");
3421        assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
3422        assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
3423        assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
3424        assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
3425
3426        mService.saveDirtyInfo();
3427
3428        // Remove a launcher.
3429        uninstallPackage(USER_10, LAUNCHER_1);
3430        mService.cleanUpPackageLocked(LAUNCHER_1, USER_10, USER_10, /* appStillExists = */ false);
3431
3432        assertEquals(set(CALLING_PACKAGE_2),
3433                hashSet(user0.getAllPackagesForTest().keySet()));
3434        assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
3435                hashSet(user10.getAllPackagesForTest().keySet()));
3436        assertEquals(
3437                set(PackageWithUser.of(USER_0, LAUNCHER_1),
3438                        PackageWithUser.of(USER_0, LAUNCHER_2)),
3439                hashSet(user0.getAllLaunchersForTest().keySet()));
3440        assertEquals(
3441                set(PackageWithUser.of(USER_10, LAUNCHER_2)),
3442                hashSet(user10.getAllLaunchersForTest().keySet()));
3443        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
3444                "s0_2");
3445        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
3446                "s0_2");
3447        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
3448                "s10_1", "s10_2");
3449        assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
3450        assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
3451        assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
3452        assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
3453
3454        mService.saveDirtyInfo();
3455
3456        // Remove a package.
3457        uninstallPackage(USER_10, CALLING_PACKAGE_2);
3458        mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_10, USER_10,
3459                /* appStillExists = */ false);
3460
3461        assertEquals(set(CALLING_PACKAGE_2),
3462                hashSet(user0.getAllPackagesForTest().keySet()));
3463        assertEquals(set(CALLING_PACKAGE_1),
3464                hashSet(user10.getAllPackagesForTest().keySet()));
3465        assertEquals(
3466                set(PackageWithUser.of(USER_0, LAUNCHER_1),
3467                        PackageWithUser.of(USER_0, LAUNCHER_2)),
3468                hashSet(user0.getAllLaunchersForTest().keySet()));
3469        assertEquals(
3470                set(PackageWithUser.of(USER_10, LAUNCHER_2)),
3471                hashSet(user10.getAllLaunchersForTest().keySet()));
3472        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
3473                "s0_2");
3474        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
3475                "s0_2");
3476        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
3477                "s10_1");
3478        assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
3479        assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
3480        assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
3481        assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
3482
3483        mService.saveDirtyInfo();
3484
3485        // Remove the other launcher from user 10 too.
3486        uninstallPackage(USER_10, LAUNCHER_2);
3487        mService.cleanUpPackageLocked(LAUNCHER_2, USER_10, USER_10,
3488                /* appStillExists = */ false);
3489
3490        assertEquals(set(CALLING_PACKAGE_2),
3491                hashSet(user0.getAllPackagesForTest().keySet()));
3492        assertEquals(set(CALLING_PACKAGE_1),
3493                hashSet(user10.getAllPackagesForTest().keySet()));
3494        assertEquals(
3495                set(PackageWithUser.of(USER_0, LAUNCHER_1),
3496                        PackageWithUser.of(USER_0, LAUNCHER_2)),
3497                hashSet(user0.getAllLaunchersForTest().keySet()));
3498        assertEquals(
3499                set(),
3500                hashSet(user10.getAllLaunchersForTest().keySet()));
3501        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
3502                "s0_2");
3503        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
3504                "s0_2");
3505
3506        // Note the pinned shortcuts on user-10 no longer referred, so they should both be removed.
3507        assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
3508        assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
3509        assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_10);
3510        assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
3511
3512        mService.saveDirtyInfo();
3513
3514        // More remove.
3515        uninstallPackage(USER_10, CALLING_PACKAGE_1);
3516        mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_10, USER_10,
3517                /* appStillExists = */ false);
3518
3519        assertEquals(set(CALLING_PACKAGE_2),
3520                hashSet(user0.getAllPackagesForTest().keySet()));
3521        assertEquals(set(),
3522                hashSet(user10.getAllPackagesForTest().keySet()));
3523        assertEquals(
3524                set(PackageWithUser.of(USER_0, LAUNCHER_1),
3525                        PackageWithUser.of(USER_0, LAUNCHER_2)),
3526                hashSet(user0.getAllLaunchersForTest().keySet()));
3527        assertEquals(set(),
3528                hashSet(user10.getAllLaunchersForTest().keySet()));
3529        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
3530                "s0_2");
3531        assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
3532                "s0_2");
3533
3534        // Note the pinned shortcuts on user-10 no longer referred, so they should both be removed.
3535        assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
3536        assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
3537        assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_10);
3538        assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
3539
3540        mService.saveDirtyInfo();
3541    }
3542
3543    public void testCleanupPackage_republishManifests() {
3544        addManifestShortcutResource(
3545                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
3546                R.xml.shortcut_2);
3547        updatePackageVersion(CALLING_PACKAGE_1, 1);
3548        mService.mPackageMonitor.onReceive(getTestContext(),
3549                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
3550
3551        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3552            assertTrue(mManager.setDynamicShortcuts(list(
3553                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3554        });
3555        runWithCaller(LAUNCHER_1, USER_0, () -> {
3556            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
3557                    list("s2", "s3", "ms1", "ms2"), HANDLE_USER_0);
3558        });
3559
3560        // Remove ms2 from manifest.
3561        addManifestShortcutResource(
3562                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
3563                R.xml.shortcut_1);
3564        updatePackageVersion(CALLING_PACKAGE_1, 1);
3565        mService.mPackageMonitor.onReceive(getTestContext(),
3566                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
3567
3568        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3569            assertTrue(mManager.setDynamicShortcuts(list(
3570                    makeShortcut("s1"), makeShortcut("s2"))));
3571
3572            // Make sure the shortcuts are in the intended state.
3573            assertWith(getCallerShortcuts())
3574                    .haveIds("ms1", "ms2", "s1", "s2", "s3")
3575
3576                    .selectByIds("ms1")
3577                    .areAllManifest()
3578                    .areAllPinned()
3579
3580                    .revertToOriginalList()
3581                    .selectByIds("ms2")
3582                    .areAllNotManifest()
3583                    .areAllPinned()
3584
3585                    .revertToOriginalList()
3586                    .selectByIds("s1")
3587                    .areAllDynamic()
3588                    .areAllNotPinned()
3589
3590                    .revertToOriginalList()
3591                    .selectByIds("s2")
3592                    .areAllDynamic()
3593                    .areAllPinned()
3594
3595                    .revertToOriginalList()
3596                    .selectByIds("s3")
3597                    .areAllNotDynamic()
3598                    .areAllPinned();
3599        });
3600
3601        // Clean up + re-publish manifests.
3602        mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0, USER_0,
3603                /* appStillExists = */ true);
3604        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3605            assertWith(getCallerShortcuts())
3606                    .haveIds("ms1")
3607                    .areAllManifest();
3608        });
3609    }
3610
3611    public void testHandleGonePackage_crossProfile() {
3612        // Create some shortcuts.
3613        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3614            assertTrue(mManager.setDynamicShortcuts(list(
3615                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3616        });
3617        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
3618            assertTrue(mManager.setDynamicShortcuts(list(
3619                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3620        });
3621        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
3622            assertTrue(mManager.setDynamicShortcuts(list(
3623                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3624        });
3625
3626        mRunningUsers.put(USER_10, true);
3627
3628        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
3629            assertTrue(mManager.setDynamicShortcuts(list(
3630                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
3631        });
3632
3633        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3634        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3635        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3636
3637        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3638        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3639        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3640
3641        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3642        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3643        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3644
3645        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3646        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3647        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3648
3649        // Pin some.
3650
3651        runWithCaller(LAUNCHER_1, USER_0, () -> {
3652            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
3653                    list("s1"), HANDLE_USER_0);
3654
3655            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
3656                    list("s2"), UserHandle.of(USER_P0));
3657
3658            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
3659                    list("s3"), HANDLE_USER_0);
3660        });
3661
3662        runWithCaller(LAUNCHER_1, USER_P0, () -> {
3663            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
3664                    list("s2"), HANDLE_USER_0);
3665
3666            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
3667                    list("s3"), UserHandle.of(USER_P0));
3668
3669            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
3670                    list("s1"), HANDLE_USER_0);
3671        });
3672
3673        runWithCaller(LAUNCHER_1, USER_10, () -> {
3674            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
3675                    list("s3"), HANDLE_USER_10);
3676        });
3677
3678        // Check the state.
3679
3680        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3681        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3682        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3683
3684        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3685        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3686        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3687
3688        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3689        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3690        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3691
3692        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3693        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3694        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3695
3696        // Make sure all the information is persisted.
3697        mService.saveDirtyInfo();
3698        initService();
3699        mService.handleUnlockUser(USER_0);
3700        mService.handleUnlockUser(USER_P0);
3701        mService.handleUnlockUser(USER_10);
3702
3703        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3704        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3705        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3706
3707        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3708        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3709        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3710
3711        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3712        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3713        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3714
3715        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3716        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3717        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3718
3719        // Start uninstalling.
3720        uninstallPackage(USER_10, LAUNCHER_1);
3721        mService.checkPackageChanges(USER_10);
3722
3723        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3724        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3725        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3726
3727        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3728        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3729        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3730
3731        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3732        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3733        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3734
3735        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3736        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3737        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3738
3739        // Uninstall.
3740        uninstallPackage(USER_10, CALLING_PACKAGE_1);
3741        mService.checkPackageChanges(USER_10);
3742
3743        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3744        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3745        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3746
3747        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3748        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3749        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3750
3751        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3752        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3753        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3754
3755        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3756        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3757        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3758
3759        uninstallPackage(USER_P0, LAUNCHER_1);
3760        mService.checkPackageChanges(USER_0);
3761
3762        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3763        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3764        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3765
3766        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3767        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3768        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3769
3770        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3771        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3772        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3773
3774        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3775        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3776        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3777
3778        mService.checkPackageChanges(USER_P0);
3779
3780        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3781        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3782        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3783
3784        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3785        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3786        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3787
3788        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3789        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3790        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3791
3792        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3793        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3794        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3795
3796        uninstallPackage(USER_P0, CALLING_PACKAGE_1);
3797
3798        mService.saveDirtyInfo();
3799        initService();
3800        mService.handleUnlockUser(USER_0);
3801        mService.handleUnlockUser(USER_P0);
3802        mService.handleUnlockUser(USER_10);
3803
3804        assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3805        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3806        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3807
3808        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3809        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3810        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3811
3812        assertDynamicOnly(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        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3817        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3818        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3819
3820        // Uninstall
3821        uninstallPackage(USER_0, LAUNCHER_1);
3822
3823        mService.saveDirtyInfo();
3824        initService();
3825        mService.handleUnlockUser(USER_0);
3826        mService.handleUnlockUser(USER_P0);
3827        mService.handleUnlockUser(USER_10);
3828
3829        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3830        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3831        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3832
3833        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3834        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3835        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3836
3837        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3838        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3839        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3840
3841        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3842        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3843        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3844
3845        uninstallPackage(USER_0, CALLING_PACKAGE_2);
3846
3847        mService.saveDirtyInfo();
3848        initService();
3849        mService.handleUnlockUser(USER_0);
3850        mService.handleUnlockUser(USER_P0);
3851        mService.handleUnlockUser(USER_10);
3852
3853        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
3854        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
3855        assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
3856
3857        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
3858        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
3859        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
3860
3861        assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
3862        assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
3863        assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
3864
3865        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
3866        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
3867        assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
3868    }
3869
3870    protected void checkCanRestoreTo(int expected, ShortcutPackageInfo spi,
3871            boolean anyVersionOk, int version, boolean nowBackupAllowed, String... signatures) {
3872        final PackageInfo pi = genPackage("dummy", /* uid */ 0, version, signatures);
3873        if (!nowBackupAllowed) {
3874            pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP;
3875        }
3876        assertEquals(expected, spi.canRestoreTo(mService, pi, anyVersionOk));
3877    }
3878
3879    public void testCanRestoreTo() {
3880        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
3881        addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 10, "sig1", "sig2");
3882        addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 10, "sig1");
3883
3884        updatePackageInfo(CALLING_PACKAGE_3,
3885                pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
3886
3887        final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackageForTest(
3888                mService, CALLING_PACKAGE_1, USER_0);
3889        final ShortcutPackageInfo spi2 = ShortcutPackageInfo.generateForInstalledPackageForTest(
3890                mService, CALLING_PACKAGE_2, USER_0);
3891        final ShortcutPackageInfo spi3 = ShortcutPackageInfo.generateForInstalledPackageForTest(
3892                mService, CALLING_PACKAGE_3, USER_0);
3893
3894        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "sig1");
3895        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "x", "sig1");
3896        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "sig1", "y");
3897        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "x", "sig1", "y");
3898        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 11, true, "sig1");
3899
3900        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true/* empty */);
3901        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x");
3902        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x", "y");
3903        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH, spi1, false, 10, true, "x");
3904        checkCanRestoreTo(DISABLED_REASON_VERSION_LOWER, spi1, false, 9, true, "sig1");
3905
3906        // Any version okay.
3907        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, true, 9, true, "sig1");
3908        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, true, 9, true, "sig1");
3909
3910        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig1", "sig2");
3911        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig2", "sig1");
3912        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig1", "sig2");
3913        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig2", "sig1");
3914        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig1", "sig2", "y");
3915        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "sig2", "sig1", "y");
3916        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig1", "sig2", "y");
3917        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 10, true, "x", "sig2", "sig1", "y");
3918        checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi2, false, 11, true, "x", "sig2", "sig1", "y");
3919
3920        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3921                spi2, false, 10, true, "sig1", "sig2x");
3922        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3923                spi2, false, 10, true, "sig2", "sig1x");
3924        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3925                spi2, false, 10, true, "x", "sig1x", "sig2");
3926        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3927                spi2, false, 10, true, "x", "sig2x", "sig1");
3928        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3929                spi2, false, 10, true, "sig1", "sig2x", "y");
3930        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3931                spi2, false, 10, true, "sig2", "sig1x", "y");
3932        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3933                spi2, false, 10, true, "x", "sig1x", "sig2", "y");
3934        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3935                spi2, false, 10, true, "x", "sig2x", "sig1", "y");
3936        checkCanRestoreTo(DISABLED_REASON_SIGNATURE_MISMATCH,
3937                spi2, false, 11, true, "x", "sig2x", "sig1", "y");
3938
3939        checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi1, true, 10, false, "sig1");
3940        checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi3, true, 10, true, "sig1");
3941    }
3942
3943    public void testHandlePackageDelete() {
3944        checkHandlePackageDeleteInner((userId, packageName) -> {
3945            uninstallPackage(userId, packageName);
3946            mService.mPackageMonitor.onReceive(getTestContext(),
3947                    genPackageDeleteIntent(packageName, userId));
3948        });
3949    }
3950
3951    public void testHandlePackageDisable() {
3952        checkHandlePackageDeleteInner((userId, packageName) -> {
3953            disablePackage(userId, packageName);
3954            mService.mPackageMonitor.onReceive(getTestContext(),
3955                    genPackageChangedIntent(packageName, userId));
3956        });
3957    }
3958
3959    private void checkHandlePackageDeleteInner(BiConsumer<Integer, String> remover) {
3960        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
3961                getTestContext().getResources(), R.drawable.black_32x32));
3962        setCaller(CALLING_PACKAGE_1, USER_0);
3963        assertTrue(mManager.addDynamicShortcuts(list(
3964                makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
3965        )));
3966        // Also add a manifest shortcut, which should be removed too.
3967        addManifestShortcutResource(
3968                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
3969                R.xml.shortcut_1);
3970        updatePackageVersion(CALLING_PACKAGE_1, 1);
3971        mService.mPackageMonitor.onReceive(getTestContext(),
3972                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
3973        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
3974            assertWith(getCallerShortcuts())
3975                    .haveIds("s1", "s2", "ms1")
3976
3977                    .selectManifest()
3978                    .haveIds("ms1");
3979        });
3980
3981        setCaller(CALLING_PACKAGE_2, USER_0);
3982        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
3983
3984        setCaller(CALLING_PACKAGE_3, USER_0);
3985        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
3986
3987        mRunningUsers.put(USER_10, true);
3988
3989        setCaller(CALLING_PACKAGE_1, USER_10);
3990        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
3991
3992        setCaller(CALLING_PACKAGE_2, USER_10);
3993        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
3994
3995        setCaller(CALLING_PACKAGE_3, USER_10);
3996        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
3997
3998        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
3999        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4000        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4001        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4002        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4003        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4004
4005        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4006        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4007        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4008        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4009        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4010        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4011
4012        remover.accept(USER_0, CALLING_PACKAGE_1);
4013
4014        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4015        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4016        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4017        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4018        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4019        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4020
4021        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4022        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4023        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4024        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4025        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4026        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4027
4028        mRunningUsers.put(USER_10, true);
4029
4030        remover.accept(USER_10, CALLING_PACKAGE_2);
4031
4032        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4033        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4034        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4035        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4036        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4037        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4038
4039        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4040        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4041        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4042        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4043        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4044        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4045
4046        mInjectedPackages.remove(CALLING_PACKAGE_1);
4047        mInjectedPackages.remove(CALLING_PACKAGE_3);
4048
4049        mService.checkPackageChanges(USER_0);
4050
4051        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4052        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4053        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));  // ---------------
4054        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4055        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4056        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4057
4058        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4059        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4060        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4061        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4062        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4063        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4064
4065        mService.checkPackageChanges(USER_10);
4066
4067        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4068        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4069        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4070        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4071        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4072        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4073
4074        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4075        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4076        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4077        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4078        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4079        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4080    }
4081
4082    /** Almost ame as testHandlePackageDelete, except it doesn't uninstall packages. */
4083    public void testHandlePackageClearData() {
4084        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
4085                getTestContext().getResources(), R.drawable.black_32x32));
4086        setCaller(CALLING_PACKAGE_1, USER_0);
4087        assertTrue(mManager.addDynamicShortcuts(list(
4088                makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
4089        )));
4090
4091        setCaller(CALLING_PACKAGE_2, USER_0);
4092        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4093
4094        setCaller(CALLING_PACKAGE_3, USER_0);
4095        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4096
4097        mRunningUsers.put(USER_10, true);
4098
4099        setCaller(CALLING_PACKAGE_1, USER_10);
4100        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4101
4102        setCaller(CALLING_PACKAGE_2, USER_10);
4103        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4104
4105        setCaller(CALLING_PACKAGE_3, USER_10);
4106        assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
4107
4108        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4109        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4110        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4111        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4112        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4113        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4114
4115        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4116        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4117        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4118        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4119        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4120        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4121
4122        mService.mPackageMonitor.onReceive(getTestContext(),
4123                genPackageDataClear(CALLING_PACKAGE_1, USER_0));
4124
4125        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4126        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4127        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4128        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4129        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4130        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4131
4132        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4133        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4134        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4135        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4136        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4137        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4138
4139        mRunningUsers.put(USER_10, true);
4140
4141        mService.mPackageMonitor.onReceive(getTestContext(),
4142                genPackageDataClear(CALLING_PACKAGE_2, USER_10));
4143
4144        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
4145        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
4146        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
4147        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
4148        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
4149        assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
4150
4151        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
4152        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
4153        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
4154        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
4155        assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
4156        assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
4157    }
4158
4159    public void testHandlePackageClearData_manifestRepublished() {
4160
4161        mRunningUsers.put(USER_10, true);
4162
4163        // Add two manifests and two dynamics.
4164        addManifestShortcutResource(
4165                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
4166                R.xml.shortcut_2);
4167        updatePackageVersion(CALLING_PACKAGE_1, 1);
4168        mService.mPackageMonitor.onReceive(getTestContext(),
4169                genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
4170
4171        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4172            assertTrue(mManager.addDynamicShortcuts(list(
4173                    makeShortcut("s1"), makeShortcut("s2"))));
4174        });
4175        runWithCaller(LAUNCHER_1, USER_10, () -> {
4176            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_10);
4177        });
4178
4179        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4180            assertWith(getCallerShortcuts())
4181                    .haveIds("ms1", "ms2", "s1", "s2")
4182                    .areAllEnabled()
4183
4184                    .selectPinned()
4185                    .haveIds("ms2", "s2");
4186        });
4187
4188        // Clear data
4189        mService.mPackageMonitor.onReceive(getTestContext(),
4190                genPackageDataClear(CALLING_PACKAGE_1, USER_10));
4191
4192        // Only manifest shortcuts will remain, and are no longer pinned.
4193        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4194            assertWith(getCallerShortcuts())
4195                    .haveIds("ms1", "ms2")
4196                    .areAllEnabled()
4197                    .areAllNotPinned();
4198        });
4199    }
4200
4201    public void testHandlePackageUpdate() throws Throwable {
4202        // Set up shortcuts and launchers.
4203
4204        final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
4205        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
4206                getTestContext().getResources(), R.drawable.black_32x32));
4207
4208        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4209            assertTrue(mManager.setDynamicShortcuts(list(
4210                    makeShortcut("s1"),
4211                    makeShortcutWithIcon("s2", res32x32),
4212                    makeShortcutWithIcon("s3", res32x32),
4213                    makeShortcutWithIcon("s4", bmp32x32))));
4214        });
4215        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4216            assertTrue(mManager.setDynamicShortcuts(list(
4217                    makeShortcut("s1"),
4218                    makeShortcutWithIcon("s2", bmp32x32))));
4219        });
4220        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
4221            assertTrue(mManager.setDynamicShortcuts(list(
4222                    makeShortcutWithIcon("s1", res32x32))));
4223        });
4224
4225        mRunningUsers.put(USER_10, true);
4226
4227        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4228            assertTrue(mManager.setDynamicShortcuts(list(
4229                    makeShortcutWithIcon("s1", res32x32),
4230                    makeShortcutWithIcon("s2", res32x32))));
4231        });
4232        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
4233            assertTrue(mManager.setDynamicShortcuts(list(
4234                    makeShortcutWithIcon("s1", bmp32x32),
4235                    makeShortcutWithIcon("s2", bmp32x32))));
4236        });
4237
4238        LauncherApps.Callback c0 = mock(LauncherApps.Callback.class);
4239        LauncherApps.Callback c10 = mock(LauncherApps.Callback.class);
4240
4241        runWithCaller(LAUNCHER_1, USER_0, () -> {
4242            mLauncherApps.registerCallback(c0, new Handler(Looper.getMainLooper()));
4243        });
4244        runWithCaller(LAUNCHER_1, USER_10, () -> {
4245            mLauncherApps.registerCallback(c10, new Handler(Looper.getMainLooper()));
4246        });
4247
4248        mInjectedCurrentTimeMillis = START_TIME + 100;
4249
4250        ArgumentCaptor<List> shortcuts;
4251
4252        // Update the version info for package 1.
4253        reset(c0);
4254        reset(c10);
4255        updatePackageVersion(CALLING_PACKAGE_1, 1);
4256
4257        // Then send the broadcast, to only user-0.
4258        mService.mPackageMonitor.onReceive(getTestContext(),
4259                genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
4260
4261        waitOnMainThread();
4262
4263        // User-0 should get the notification.
4264        shortcuts = ArgumentCaptor.forClass(List.class);
4265        verify(c0).onShortcutsChanged(
4266                eq(CALLING_PACKAGE_1),
4267                shortcuts.capture(),
4268                eq(HANDLE_USER_0));
4269
4270        // User-10 shouldn't yet get the notification.
4271        verify(c10, times(0)).onShortcutsChanged(
4272                eq(CALLING_PACKAGE_1),
4273                any(List.class),
4274                any(UserHandle.class));
4275        assertShortcutIds(shortcuts.getValue(), "s1", "s2", "s3", "s4");
4276        assertEquals(START_TIME,
4277                findShortcut(shortcuts.getValue(), "s1").getLastChangedTimestamp());
4278        assertEquals(START_TIME + 100,
4279                findShortcut(shortcuts.getValue(), "s2").getLastChangedTimestamp());
4280        assertEquals(START_TIME + 100,
4281                findShortcut(shortcuts.getValue(), "s3").getLastChangedTimestamp());
4282        assertEquals(START_TIME,
4283                findShortcut(shortcuts.getValue(), "s4").getLastChangedTimestamp());
4284
4285        // Next, send an unlock event on user-10.  Now we scan packages on this user and send a
4286        // notification to the launcher.
4287        mInjectedCurrentTimeMillis = START_TIME + 200;
4288
4289        mRunningUsers.put(USER_10, true);
4290        mUnlockedUsers.put(USER_10, true);
4291
4292        reset(c0);
4293        reset(c10);
4294        setPackageLastUpdateTime(CALLING_PACKAGE_1, mInjectedCurrentTimeMillis);
4295        mService.handleUnlockUser(USER_10);
4296        mService.checkPackageChanges(USER_10);
4297
4298        waitOnMainThread();
4299
4300        shortcuts = ArgumentCaptor.forClass(List.class);
4301        verify(c0, times(0)).onShortcutsChanged(
4302                eq(CALLING_PACKAGE_1),
4303                any(List.class),
4304                any(UserHandle.class));
4305
4306        verify(c10).onShortcutsChanged(
4307                eq(CALLING_PACKAGE_1),
4308                shortcuts.capture(),
4309                eq(HANDLE_USER_10));
4310
4311        assertShortcutIds(shortcuts.getValue(), "s1", "s2");
4312        assertEquals(START_TIME + 200,
4313                findShortcut(shortcuts.getValue(), "s1").getLastChangedTimestamp());
4314        assertEquals(START_TIME + 200,
4315                findShortcut(shortcuts.getValue(), "s2").getLastChangedTimestamp());
4316
4317
4318        // Do the same thing for package 2, which doesn't have resource icons.
4319        mInjectedCurrentTimeMillis = START_TIME + 300;
4320
4321        reset(c0);
4322        reset(c10);
4323        updatePackageVersion(CALLING_PACKAGE_2, 10);
4324
4325        // Then send the broadcast, to only user-0.
4326        mService.mPackageMonitor.onReceive(getTestContext(),
4327                genPackageUpdateIntent(CALLING_PACKAGE_2, USER_0));
4328
4329        waitOnMainThread();
4330
4331        verify(c0, times(0)).onShortcutsChanged(
4332                eq(CALLING_PACKAGE_1),
4333                any(List.class),
4334                any(UserHandle.class));
4335
4336        verify(c10, times(0)).onShortcutsChanged(
4337                eq(CALLING_PACKAGE_1),
4338                any(List.class),
4339                any(UserHandle.class));
4340
4341        // Do the same thing for package 3
4342        mInjectedCurrentTimeMillis = START_TIME + 400;
4343
4344        reset(c0);
4345        reset(c10);
4346        updatePackageVersion(CALLING_PACKAGE_3, 100);
4347
4348        // Then send the broadcast, to only user-0.
4349        mService.mPackageMonitor.onReceive(getTestContext(),
4350                genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0));
4351        mService.checkPackageChanges(USER_10);
4352
4353        waitOnMainThread();
4354
4355        shortcuts = ArgumentCaptor.forClass(List.class);
4356        verify(c0).onShortcutsChanged(
4357                eq(CALLING_PACKAGE_3),
4358                shortcuts.capture(),
4359                eq(HANDLE_USER_0));
4360
4361        // User 10 doesn't have package 3, so no callback.
4362        verify(c10, times(0)).onShortcutsChanged(
4363                eq(CALLING_PACKAGE_3),
4364                any(List.class),
4365                any(UserHandle.class));
4366
4367        assertShortcutIds(shortcuts.getValue(), "s1");
4368        assertEquals(START_TIME + 400,
4369                findShortcut(shortcuts.getValue(), "s1").getLastChangedTimestamp());
4370    }
4371
4372    /**
4373     * Test the case where an updated app has resource IDs changed.
4374     */
4375    public void testHandlePackageUpdate_resIdChanged() throws Exception {
4376        final Icon icon1 = Icon.createWithResource(getTestContext(), /* res ID */ 1000);
4377        final Icon icon2 = Icon.createWithResource(getTestContext(), /* res ID */ 1001);
4378
4379        // Set up shortcuts.
4380        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4381            // Note resource strings are not officially supported (they're hidden), but
4382            // should work.
4383
4384            final ShortcutInfo s1 = new ShortcutInfo.Builder(mClientContext)
4385                    .setId("s1")
4386                    .setActivity(makeComponent(ShortcutActivity.class))
4387                    .setIntent(new Intent(Intent.ACTION_VIEW))
4388                    .setIcon(icon1)
4389                    .setTitleResId(10000)
4390                    .setTextResId(10001)
4391                    .setDisabledMessageResId(10002)
4392                    .build();
4393
4394            final ShortcutInfo s2 = new ShortcutInfo.Builder(mClientContext)
4395                    .setId("s2")
4396                    .setActivity(makeComponent(ShortcutActivity.class))
4397                    .setIntent(new Intent(Intent.ACTION_VIEW))
4398                    .setIcon(icon2)
4399                    .setTitleResId(20000)
4400                    .build();
4401
4402            assertTrue(mManager.setDynamicShortcuts(list(s1, s2)));
4403        });
4404
4405        // Verify.
4406        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4407            final ShortcutInfo s1 = getCallerShortcut("s1");
4408            final ShortcutInfo s2 = getCallerShortcut("s2");
4409
4410            assertEquals(1000, s1.getIconResourceId());
4411            assertEquals(10000, s1.getTitleResId());
4412            assertEquals(10001, s1.getTextResId());
4413            assertEquals(10002, s1.getDisabledMessageResourceId());
4414
4415            assertEquals(1001, s2.getIconResourceId());
4416            assertEquals(20000, s2.getTitleResId());
4417            assertEquals(0, s2.getTextResId());
4418            assertEquals(0, s2.getDisabledMessageResourceId());
4419        });
4420
4421        mService.saveDirtyInfo();
4422        initService();
4423
4424        // Set up the mock resources again, with an "adjustment".
4425        // When the package is updated, the service will fetch the updated res-IDs with res-names,
4426        // and the new IDs will have this offset.
4427        setUpAppResources(10);
4428
4429        // Update the package.
4430        updatePackageVersion(CALLING_PACKAGE_1, 1);
4431        mService.mPackageMonitor.onReceive(getTestContext(),
4432                genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
4433
4434        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4435            final ShortcutInfo s1 = getCallerShortcut("s1");
4436            final ShortcutInfo s2 = getCallerShortcut("s2");
4437
4438            assertEquals(1010, s1.getIconResourceId());
4439            assertEquals(10010, s1.getTitleResId());
4440            assertEquals(10011, s1.getTextResId());
4441            assertEquals(10012, s1.getDisabledMessageResourceId());
4442
4443            assertEquals(1011, s2.getIconResourceId());
4444            assertEquals(20010, s2.getTitleResId());
4445            assertEquals(0, s2.getTextResId());
4446            assertEquals(0, s2.getDisabledMessageResourceId());
4447        });
4448    }
4449
4450    public void testHandlePackageUpdate_systemAppUpdate() {
4451
4452        // Package1 is a system app.  Package 2 is not a system app, so it's not scanned
4453        // in this test at all.
4454        mSystemPackages.add(CALLING_PACKAGE_1);
4455
4456        // Initial state: no shortcuts.
4457        mService.checkPackageChanges(USER_0);
4458
4459        assertEquals(mInjectedCurrentTimeMillis,
4460                mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
4461        assertEquals(mInjectedBuildFingerprint,
4462                mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
4463
4464        // They have no shortcuts.
4465        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4466            assertWith(getCallerShortcuts())
4467                    .isEmpty();
4468        });
4469
4470        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4471            assertWith(getCallerShortcuts())
4472                    .isEmpty();
4473        });
4474
4475        // Next.
4476        // Update the packages -- now they have 1 manifest shortcut.
4477        // But checkPackageChanges() don't notice it, since their version code / timestamp haven't
4478        // changed.
4479        addManifestShortcutResource(
4480                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
4481                R.xml.shortcut_1);
4482        addManifestShortcutResource(
4483                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
4484                R.xml.shortcut_1);
4485        mInjectedCurrentTimeMillis += 1000;
4486        mService.checkPackageChanges(USER_0);
4487
4488        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4489            assertWith(getCallerShortcuts())
4490                    .isEmpty();
4491        });
4492        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4493            assertWith(getCallerShortcuts())
4494                    .isEmpty();
4495        });
4496
4497        // Next.
4498        // Update the build finger print.  All apps will be scanned now.
4499        mInjectedBuildFingerprint = "update1";
4500        mInjectedCurrentTimeMillis += 1000;
4501        mService.checkPackageChanges(USER_0);
4502
4503        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4504            assertWith(getCallerShortcuts())
4505                    .haveIds("ms1");
4506        });
4507        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4508            assertWith(getCallerShortcuts())
4509                    .haveIds("ms1");
4510        });
4511
4512        // Next.
4513        // Update manifest shortcuts.
4514        addManifestShortcutResource(
4515                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
4516                R.xml.shortcut_2);
4517        addManifestShortcutResource(
4518                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
4519                R.xml.shortcut_2);
4520        mInjectedCurrentTimeMillis += 1000;
4521        mService.checkPackageChanges(USER_0);
4522
4523        // Fingerprint hasn't changed, so there packages weren't scanned.
4524        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4525            assertWith(getCallerShortcuts())
4526                    .haveIds("ms1");
4527        });
4528        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4529            assertWith(getCallerShortcuts())
4530                    .haveIds("ms1");
4531        });
4532
4533        // Update the fingerprint.  CALLING_PACKAGE_1's version code hasn't changed, but we scan
4534        // all apps anyway.
4535        mInjectedBuildFingerprint = "update2";
4536        mInjectedCurrentTimeMillis += 1000;
4537        mService.checkPackageChanges(USER_0);
4538
4539        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4540            assertWith(getCallerShortcuts())
4541                    .haveIds("ms1", "ms2");
4542        });
4543        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4544            assertWith(getCallerShortcuts())
4545                    .haveIds("ms1", "ms2");
4546        });
4547
4548        // Make sure getLastAppScanTime / getLastAppScanOsFingerprint are persisted.
4549        initService();
4550        assertEquals(mInjectedCurrentTimeMillis,
4551                mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
4552        assertEquals(mInjectedBuildFingerprint,
4553                mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
4554    }
4555
4556    public void testHandlePackageChanged() {
4557        final ComponentName ACTIVITY1 = new ComponentName(CALLING_PACKAGE_1, "act1");
4558        final ComponentName ACTIVITY2 = new ComponentName(CALLING_PACKAGE_1, "act2");
4559
4560        addManifestShortcutResource(ACTIVITY1, R.xml.shortcut_1);
4561        addManifestShortcutResource(ACTIVITY2, R.xml.shortcut_1_alt);
4562
4563        mRunningUsers.put(USER_10, true);
4564
4565        updatePackageVersion(CALLING_PACKAGE_1, 1);
4566        mService.mPackageMonitor.onReceive(getTestContext(),
4567                genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
4568
4569        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4570            assertTrue(mManager.addDynamicShortcuts(list(
4571                    makeShortcutWithActivity("s1", ACTIVITY1),
4572                    makeShortcutWithActivity("s2", ACTIVITY2)
4573            )));
4574        });
4575        runWithCaller(LAUNCHER_1, USER_10, () -> {
4576            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1-alt", "s2"), HANDLE_USER_10);
4577        });
4578
4579        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4580            assertWith(getCallerShortcuts())
4581                    .haveIds("ms1", "ms1-alt", "s1", "s2")
4582                    .areAllEnabled()
4583
4584                    .selectPinned()
4585                    .haveIds("ms1-alt", "s2")
4586
4587                    .revertToOriginalList()
4588                    .selectByIds("ms1", "s1")
4589                    .areAllWithActivity(ACTIVITY1)
4590
4591                    .revertToOriginalList()
4592                    .selectByIds("ms1-alt", "s2")
4593                    .areAllWithActivity(ACTIVITY2)
4594            ;
4595        });
4596
4597        // First, no changes.
4598        mService.mPackageMonitor.onReceive(getTestContext(),
4599                genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
4600
4601        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4602            assertWith(getCallerShortcuts())
4603                    .haveIds("ms1", "ms1-alt", "s1", "s2")
4604                    .areAllEnabled()
4605
4606                    .selectPinned()
4607                    .haveIds("ms1-alt", "s2")
4608
4609                    .revertToOriginalList()
4610                    .selectByIds("ms1", "s1")
4611                    .areAllWithActivity(ACTIVITY1)
4612
4613                    .revertToOriginalList()
4614                    .selectByIds("ms1-alt", "s2")
4615                    .areAllWithActivity(ACTIVITY2)
4616            ;
4617        });
4618
4619        // Disable activity 1
4620        mEnabledActivityChecker = (activity, userId) -> !ACTIVITY1.equals(activity);
4621        mService.mPackageMonitor.onReceive(getTestContext(),
4622                genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
4623
4624        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4625            assertWith(getCallerShortcuts())
4626                    .haveIds("ms1-alt", "s2")
4627                    .areAllEnabled()
4628
4629                    .selectPinned()
4630                    .haveIds("ms1-alt", "s2")
4631
4632                    .revertToOriginalList()
4633                    .selectByIds("ms1-alt", "s2")
4634                    .areAllWithActivity(ACTIVITY2)
4635            ;
4636        });
4637
4638        // Re-enable activity 1.
4639        // Manifest shortcuts will be re-published, but dynamic ones are not.
4640        mEnabledActivityChecker = (activity, userId) -> true;
4641        mService.mPackageMonitor.onReceive(getTestContext(),
4642                genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
4643
4644        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4645            assertWith(getCallerShortcuts())
4646                    .haveIds("ms1", "ms1-alt", "s2")
4647                    .areAllEnabled()
4648
4649                    .selectPinned()
4650                    .haveIds("ms1-alt", "s2")
4651
4652                    .revertToOriginalList()
4653                    .selectByIds("ms1")
4654                    .areAllWithActivity(ACTIVITY1)
4655
4656                    .revertToOriginalList()
4657                    .selectByIds("ms1-alt", "s2")
4658                    .areAllWithActivity(ACTIVITY2)
4659            ;
4660        });
4661
4662        // Disable activity 2
4663        // Because "ms1-alt" and "s2" are both pinned, they will remain, but disabled.
4664        mEnabledActivityChecker = (activity, userId) -> !ACTIVITY2.equals(activity);
4665        mService.mPackageMonitor.onReceive(getTestContext(),
4666                genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
4667
4668        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
4669            assertWith(getCallerShortcuts())
4670                    .haveIds("ms1", "ms1-alt", "s2")
4671
4672                    .selectDynamic().isEmpty().revertToOriginalList() // no dynamics.
4673
4674                    .selectPinned()
4675                    .haveIds("ms1-alt", "s2")
4676                    .areAllDisabled()
4677
4678                    .revertToOriginalList()
4679                    .selectByIds("ms1")
4680                    .areAllWithActivity(ACTIVITY1)
4681                    .areAllEnabled()
4682            ;
4683        });
4684    }
4685
4686    public void testHandlePackageUpdate_activityNoLongerMain() throws Throwable {
4687        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4688            assertTrue(mManager.setDynamicShortcuts(list(
4689                    makeShortcutWithActivity("s1a",
4690                            new ComponentName(getCallingPackage(), "act1")),
4691                    makeShortcutWithActivity("s1b",
4692                            new ComponentName(getCallingPackage(), "act1")),
4693                    makeShortcutWithActivity("s2a",
4694                            new ComponentName(getCallingPackage(), "act2")),
4695                    makeShortcutWithActivity("s2b",
4696                            new ComponentName(getCallingPackage(), "act2")),
4697                    makeShortcutWithActivity("s3a",
4698                            new ComponentName(getCallingPackage(), "act3")),
4699                    makeShortcutWithActivity("s3b",
4700                            new ComponentName(getCallingPackage(), "act3"))
4701            )));
4702            assertWith(getCallerShortcuts())
4703                    .haveIds("s1a", "s1b", "s2a", "s2b", "s3a", "s3b")
4704                    .areAllDynamic();
4705        });
4706        runWithCaller(LAUNCHER_1, USER_0, () -> {
4707            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
4708                    list("s1b", "s2b", "s3b"),
4709                    HANDLE_USER_0);
4710        });
4711        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4712            assertWith(getCallerShortcuts())
4713                    .haveIds("s1a", "s1b", "s2a", "s2b", "s3a", "s3b")
4714                    .areAllDynamic()
4715
4716                    .selectByIds("s1b", "s2b", "s3b")
4717                    .areAllPinned();
4718        });
4719
4720        // Update the app and act2 and act3 are no longer main.
4721        mMainActivityChecker = (activity, userId) -> {
4722            return activity.getClassName().equals("act1");
4723        };
4724
4725        setCaller(LAUNCHER_1, USER_0);
4726        assertForLauncherCallback(mLauncherApps, () -> {
4727            updatePackageVersion(CALLING_PACKAGE_1, 1);
4728            mService.mPackageMonitor.onReceive(getTestContext(),
4729                    genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
4730        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
4731                // Make sure the launcher gets callbacks.
4732                .haveIds("s1a", "s1b", "s2b", "s3b")
4733                .areAllWithKeyFieldsOnly();
4734
4735        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4736            // s2a and s3a are gone, but s2b and s3b will remain because they're pinned, and
4737            // disabled.
4738            assertWith(getCallerShortcuts())
4739                    .haveIds("s1a", "s1b", "s2b", "s3b")
4740
4741                    .selectByIds("s1a", "s1b")
4742                    .areAllDynamic()
4743                    .areAllEnabled()
4744
4745                    .revertToOriginalList()
4746                    .selectByIds("s2b", "s3b")
4747                    .areAllNotDynamic()
4748                    .areAllDisabled()
4749                    .areAllPinned()
4750            ;
4751        });
4752    }
4753
4754    protected void prepareForBackupTest() {
4755        prepareCrossProfileDataSet();
4756
4757        backupAndRestore();
4758    }
4759
4760    /**
4761     * Make sure the backup data doesn't have the following information:
4762     * - Launchers on other users.
4763     * - Non-backup app information.
4764     *
4765     * But restores all other infomation.
4766     *
4767     * It also omits the following pieces of information, but that's tested in
4768     * {@link ShortcutManagerTest2#testShortcutInfoSaveAndLoad_forBackup}.
4769     * - Unpinned dynamic shortcuts
4770     * - Bitmaps
4771     */
4772    public void testBackupAndRestore() {
4773
4774        assertFileNotExists("user-0/shortcut_dump/restore-0-start.txt");
4775        assertFileNotExists("user-0/shortcut_dump/restore-1-payload.xml");
4776        assertFileNotExists("user-0/shortcut_dump/restore-2.txt");
4777        assertFileNotExists("user-0/shortcut_dump/restore-3.txt");
4778        assertFileNotExists("user-0/shortcut_dump/restore-4.txt");
4779        assertFileNotExists("user-0/shortcut_dump/restore-5-finish.txt");
4780
4781        prepareForBackupTest();
4782
4783        assertFileExistsWithContent("user-0/shortcut_dump/restore-0-start.txt");
4784        assertFileExistsWithContent("user-0/shortcut_dump/restore-1-payload.xml");
4785        assertFileExistsWithContent("user-0/shortcut_dump/restore-2.txt");
4786        assertFileExistsWithContent("user-0/shortcut_dump/restore-3.txt");
4787        assertFileExistsWithContent("user-0/shortcut_dump/restore-4.txt");
4788        assertFileExistsWithContent("user-0/shortcut_dump/restore-5-finish.txt");
4789
4790        checkBackupAndRestore_success(/*firstRestore=*/ true);
4791    }
4792
4793    public void testBackupAndRestore_backupRestoreTwice() {
4794        prepareForBackupTest();
4795
4796        checkBackupAndRestore_success(/*firstRestore=*/ true);
4797
4798        // Run a backup&restore again. Note the shortcuts that weren't restored in the previous
4799        // restore are disabled, so they won't be restored again.
4800        dumpsysOnLogcat("Before second backup&restore");
4801
4802        backupAndRestore();
4803
4804        dumpsysOnLogcat("After second backup&restore");
4805
4806        checkBackupAndRestore_success(/*firstRestore=*/ false);
4807    }
4808
4809    public void testBackupAndRestore_restoreToNewVersion() {
4810        prepareForBackupTest();
4811
4812        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 2);
4813        addPackage(LAUNCHER_1, LAUNCHER_UID_1, 5);
4814
4815        checkBackupAndRestore_success(/*firstRestore=*/ true);
4816    }
4817
4818    public void testBackupAndRestore_restoreToSuperSetSignatures() {
4819        prepareForBackupTest();
4820
4821        // Change package signatures.
4822        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1, "sigx", CALLING_PACKAGE_1);
4823        addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4, LAUNCHER_1, "sigy");
4824
4825        checkBackupAndRestore_success(/*firstRestore=*/ true);
4826    }
4827
4828    protected void checkBackupAndRestore_success(boolean firstRestore) {
4829        // Make sure non-system user is not restored.
4830        final ShortcutUser userP0 = mService.getUserShortcutsLocked(USER_P0);
4831        assertEquals(0, userP0.getAllPackagesForTest().size());
4832        assertEquals(0, userP0.getAllLaunchersForTest().size());
4833
4834        // Make sure only "allowBackup" apps are restored, and are shadow.
4835        final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
4836        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
4837        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
4838
4839        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
4840        assertExistsAndShadow(user0.getAllLaunchersForTest().get(
4841                PackageWithUser.of(USER_0, LAUNCHER_1)));
4842        assertExistsAndShadow(user0.getAllLaunchersForTest().get(
4843                PackageWithUser.of(USER_0, LAUNCHER_2)));
4844
4845        assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_0, LAUNCHER_3)));
4846        assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_P0, LAUNCHER_1)));
4847
4848        installPackage(USER_0, CALLING_PACKAGE_1);
4849        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4850            assertWith(getCallerVisibleShortcuts())
4851                    .selectDynamic()
4852                    .isEmpty()
4853
4854                    .revertToOriginalList()
4855                    .selectPinned()
4856                    .haveIds("s1", "s2")
4857                    .areAllEnabled();
4858        });
4859
4860        installPackage(USER_0, LAUNCHER_1);
4861        runWithCaller(LAUNCHER_1, USER_0, () -> {
4862            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
4863                    .areAllPinned()
4864                    .haveIds("s1")
4865                    .areAllEnabled();
4866
4867            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
4868                    .isEmpty();
4869
4870            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
4871                    .isEmpty();
4872
4873            assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
4874                    .isEmpty();
4875        });
4876
4877        installPackage(USER_0, CALLING_PACKAGE_2);
4878        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
4879            assertWith(getCallerVisibleShortcuts())
4880                    .selectDynamic()
4881                    .isEmpty()
4882
4883                    .revertToOriginalList()
4884                    .selectPinned()
4885                    .haveIds("s1", "s2", "s3")
4886                    .areAllEnabled();
4887        });
4888
4889        runWithCaller(LAUNCHER_1, USER_0, () -> {
4890            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
4891                    .areAllPinned()
4892                    .haveIds("s1")
4893                    .areAllEnabled();
4894
4895            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
4896                    .areAllPinned()
4897                    .haveIds("s1", "s2")
4898                    .areAllEnabled();
4899
4900            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
4901                    .isEmpty();
4902
4903            assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
4904                    .isEmpty();
4905        });
4906
4907        // 3 shouldn't be backed up, so no pinned shortcuts.
4908        installPackage(USER_0, CALLING_PACKAGE_3);
4909        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
4910            assertWith(getCallerVisibleShortcuts())
4911                    .isEmpty();
4912        });
4913
4914        // Launcher on a different profile shouldn't be restored.
4915        runWithCaller(LAUNCHER_1, USER_P0, () -> {
4916            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
4917                    .isEmpty();
4918            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
4919                    .isEmpty();
4920            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
4921                    .isEmpty();
4922        });
4923
4924        // Package on a different profile, no restore.
4925        installPackage(USER_P0, CALLING_PACKAGE_1);
4926        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
4927            assertWith(getCallerVisibleShortcuts())
4928                    .isEmpty();
4929        });
4930
4931        // Restore launcher 2 on user 0.
4932        installPackage(USER_0, LAUNCHER_2);
4933        runWithCaller(LAUNCHER_2, USER_0, () -> {
4934            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
4935                    .areAllPinned()
4936                    .haveIds("s2")
4937                    .areAllEnabled();
4938
4939            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
4940                    .areAllPinned()
4941                    .haveIds("s2", "s3")
4942                    .areAllEnabled();
4943
4944            if (firstRestore) {
4945                assertWith(
4946                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
4947                        .haveIds("s2", "s3", "s4")
4948                        .areAllDisabled()
4949                        .areAllPinned()
4950                        .areAllNotDynamic()
4951                        .areAllWithDisabledReason(
4952                                ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
4953            } else {
4954                assertWith(
4955                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
4956                        .isEmpty();
4957            }
4958
4959            assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
4960                    .isEmpty();
4961        });
4962
4963
4964        // Restoration of launcher2 shouldn't affect other packages; so do the same checks and
4965        // make sure they still have the same result.
4966        installPackage(USER_0, CALLING_PACKAGE_1);
4967        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
4968            assertWith(getCallerVisibleShortcuts())
4969                    .areAllPinned()
4970                    .haveIds("s1", "s2");
4971        });
4972
4973        installPackage(USER_0, LAUNCHER_1);
4974        runWithCaller(LAUNCHER_1, USER_0, () -> {
4975            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
4976                    .areAllPinned()
4977                    .haveIds("s1")
4978                    .areAllEnabled();
4979
4980            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
4981                    .areAllPinned()
4982                    .haveIds("s1", "s2")
4983                    .areAllEnabled();
4984
4985            if (firstRestore) {
4986                assertWith(
4987                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
4988                        .haveIds("s1", "s2", "s3")
4989                        .areAllDisabled()
4990                        .areAllPinned()
4991                        .areAllNotDynamic()
4992                        .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
4993            } else {
4994                assertWith(
4995                        mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
4996                        .isEmpty();
4997            }
4998
4999            assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
5000                    .isEmpty();
5001        });
5002
5003        installPackage(USER_0, CALLING_PACKAGE_2);
5004        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5005            assertWith(getCallerVisibleShortcuts())
5006                    .areAllPinned()
5007                    .haveIds("s1", "s2", "s3")
5008                    .areAllEnabled();
5009        });
5010    }
5011
5012    public void testBackupAndRestore_publisherLowerVersion() {
5013        prepareForBackupTest();
5014
5015        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 0); // Lower version
5016
5017        checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_VERSION_LOWER);
5018    }
5019
5020    public void testBackupAndRestore_publisherWrongSignature() {
5021        prepareForBackupTest();
5022
5023        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sigx"); // different signature
5024
5025        checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH);
5026    }
5027
5028    public void testBackupAndRestore_publisherNoLongerBackupTarget() {
5029        prepareForBackupTest();
5030
5031        updatePackageInfo(CALLING_PACKAGE_1,
5032                pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
5033
5034        checkBackupAndRestore_publisherNotRestored(
5035                ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5036    }
5037
5038    protected void checkBackupAndRestore_publisherNotRestored(
5039            int package1DisabledReason) {
5040        installPackage(USER_0, CALLING_PACKAGE_1);
5041        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5042            assertEquals(0, mManager.getDynamicShortcuts().size());
5043            assertEquals(0, mManager.getPinnedShortcuts().size());
5044        });
5045        assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
5046                .getPackageInfo().isShadow());
5047
5048
5049        installPackage(USER_0, CALLING_PACKAGE_2);
5050        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5051            assertEquals(0, mManager.getDynamicShortcuts().size());
5052            assertShortcutIds(assertAllPinned(
5053                    mManager.getPinnedShortcuts()),
5054                    "s1", "s2", "s3");
5055        });
5056        assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, USER_0)
5057                .getPackageInfo().isShadow());
5058
5059        installPackage(USER_0, LAUNCHER_1);
5060        runWithCaller(LAUNCHER_1, USER_0, () -> {
5061            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5062                    .haveIds("s1")
5063                    .areAllPinned()
5064                    .areAllDisabled()
5065                    .areAllWithDisabledReason(package1DisabledReason)
5066                    .forAllShortcuts(si -> {
5067                        switch (package1DisabledReason) {
5068                            case ShortcutInfo.DISABLED_REASON_VERSION_LOWER:
5069                                assertEquals("This shortcut requires latest app",
5070                                        si.getDisabledMessage());
5071                                break;
5072                            case ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH:
5073                                assertEquals(
5074                                        "Couldn\u2019t restore shortcut because of app"
5075                                        + " signature mismatch",
5076                                        si.getDisabledMessage());
5077                                break;
5078                            case ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED:
5079                                assertEquals(
5080                                        "Couldn\u2019t restore shortcut because app"
5081                                        + " doesn\u2019t support backup and restore",
5082                                        si.getDisabledMessage());
5083                                break;
5084                            default:
5085                                fail("Unhandled disabled reason: " + package1DisabledReason);
5086                        }
5087                    });
5088            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5089                    .haveIds("s1", "s2")
5090                    .areAllPinned()
5091                    .areAllEnabled();
5092            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5093                    .isEmpty();
5094        });
5095        installPackage(USER_0, LAUNCHER_2);
5096        runWithCaller(LAUNCHER_2, USER_0, () -> {
5097            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5098                    .haveIds("s2")
5099                    .areAllPinned()
5100                    .areAllDisabled()
5101                    .areAllWithDisabledReason(package1DisabledReason);
5102            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5103                    .haveIds("s2", "s3")
5104                    .areAllPinned()
5105                    .areAllEnabled();
5106            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5107                    .isEmpty();
5108        });
5109
5110        installPackage(USER_0, CALLING_PACKAGE_3);
5111        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5112            assertEquals(0, mManager.getDynamicShortcuts().size());
5113            assertEquals(0, mManager.getPinnedShortcuts().size());
5114        });
5115
5116        runWithCaller(LAUNCHER_1, USER_0, () -> {
5117            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5118                    .haveIds("s1")
5119                    .areAllPinned()
5120                    .areAllDisabled()
5121                    .areAllWithDisabledReason(package1DisabledReason);
5122            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5123                    .haveIds("s1", "s2")
5124                    .areAllPinned()
5125                    .areAllEnabled();
5126            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5127                    .haveIds("s1", "s2", "s3")
5128                    .areAllPinned()
5129                    .areAllDisabled()
5130                    .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5131        });
5132        runWithCaller(LAUNCHER_2, USER_0, () -> {
5133            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5134                    .haveIds("s2")
5135                    .areAllPinned()
5136                    .areAllDisabled()
5137                    .areAllWithDisabledReason(package1DisabledReason);
5138            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5139                    .haveIds("s2", "s3")
5140                    .areAllPinned()
5141                    .areAllEnabled();
5142            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5143                    .haveIds("s2", "s3", "s4")
5144                    .areAllPinned()
5145                    .areAllDisabled()
5146                    .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5147        });
5148    }
5149
5150    public void testBackupAndRestore_launcherLowerVersion() {
5151        prepareForBackupTest();
5152
5153        addPackage(LAUNCHER_1, LAUNCHER_UID_1, 0); // Lower version
5154
5155        // Note, we restore pinned shortcuts even if the launcher is of a lower version.
5156        checkBackupAndRestore_success(/*firstRestore=*/ true);
5157    }
5158
5159    public void testBackupAndRestore_launcherWrongSignature() {
5160        prepareForBackupTest();
5161
5162        addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "sigx"); // different signature
5163
5164        checkBackupAndRestore_launcherNotRestored();
5165    }
5166
5167    public void testBackupAndRestore_launcherNoLongerBackupTarget() {
5168        prepareForBackupTest();
5169
5170        updatePackageInfo(LAUNCHER_1,
5171                pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
5172
5173        checkBackupAndRestore_launcherNotRestored();
5174    }
5175
5176    protected void checkBackupAndRestore_launcherNotRestored() {
5177        installPackage(USER_0, CALLING_PACKAGE_1);
5178        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5179            assertEquals(0, mManager.getDynamicShortcuts().size());
5180
5181            // s1 was pinned by launcher 1, which is not restored, yet, so we still see "s1" here.
5182            assertShortcutIds(assertAllPinned(
5183                    mManager.getPinnedShortcuts()),
5184                    "s1", "s2");
5185        });
5186
5187        installPackage(USER_0, CALLING_PACKAGE_2);
5188        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5189            assertEquals(0, mManager.getDynamicShortcuts().size());
5190            assertShortcutIds(assertAllPinned(
5191                    mManager.getPinnedShortcuts()),
5192                    "s1", "s2", "s3");
5193        });
5194
5195        // Now we try to restore launcher 1.  Then we realize it's not restorable, so L1 has no pinned
5196        // shortcuts.
5197        installPackage(USER_0, LAUNCHER_1);
5198        runWithCaller(LAUNCHER_1, USER_0, () -> {
5199            assertShortcutIds(assertAllPinned(
5200                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5201                    /* empty */);
5202            assertShortcutIds(assertAllPinned(
5203                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5204                    /* empty */);
5205            assertShortcutIds(assertAllPinned(
5206                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5207                    /* empty */);
5208        });
5209        assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
5210                .getPackageInfo().isShadow());
5211
5212        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5213            assertEquals(0, mManager.getDynamicShortcuts().size());
5214
5215            // Now CALLING_PACKAGE_1 realizes "s1" is no longer pinned.
5216            assertShortcutIds(assertAllPinned(
5217                    mManager.getPinnedShortcuts()),
5218                    "s2");
5219        });
5220
5221        installPackage(USER_0, LAUNCHER_2);
5222        runWithCaller(LAUNCHER_2, USER_0, () -> {
5223            assertShortcutIds(assertAllPinned(
5224                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0)),
5225                    "s2");
5226            assertShortcutIds(assertAllPinned(
5227                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
5228                    "s2", "s3");
5229            assertShortcutIds(assertAllPinned(
5230                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5231                    /* empty */);
5232        });
5233        assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_2, USER_0)
5234                .getPackageInfo().isShadow());
5235
5236        installPackage(USER_0, CALLING_PACKAGE_3);
5237        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5238            assertEquals(0, mManager.getDynamicShortcuts().size());
5239            assertEquals(0, mManager.getPinnedShortcuts().size());
5240        });
5241
5242        runWithCaller(LAUNCHER_1, USER_0, () -> {
5243            assertShortcutIds(assertAllPinned(
5244                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5245                    /* empty */);
5246            assertShortcutIds(assertAllPinned(
5247                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5248                    /* empty */);
5249            assertShortcutIds(assertAllPinned(
5250                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5251                    /* empty */);
5252        });
5253        runWithCaller(LAUNCHER_2, USER_0, () -> {
5254            assertShortcutIds(assertAllPinned(
5255                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0)),
5256                    "s2");
5257            assertShortcutIds(assertAllPinned(
5258                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
5259                    "s2", "s3");
5260        });
5261    }
5262
5263    public void testBackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
5264        prepareForBackupTest();
5265
5266        updatePackageInfo(CALLING_PACKAGE_1,
5267                pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
5268
5269        updatePackageInfo(LAUNCHER_1,
5270                pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
5271
5272        checkBackupAndRestore_publisherAndLauncherNotRestored();
5273    }
5274
5275    protected void checkBackupAndRestore_publisherAndLauncherNotRestored() {
5276        installPackage(USER_0, CALLING_PACKAGE_1);
5277        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5278            assertEquals(0, mManager.getDynamicShortcuts().size());
5279            assertEquals(0, mManager.getPinnedShortcuts().size());
5280        });
5281
5282        installPackage(USER_0, CALLING_PACKAGE_2);
5283        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5284            assertEquals(0, mManager.getDynamicShortcuts().size());
5285            assertShortcutIds(assertAllPinned(
5286                    mManager.getPinnedShortcuts()),
5287                    "s1", "s2", "s3");
5288        });
5289
5290        installPackage(USER_0, LAUNCHER_1);
5291        runWithCaller(LAUNCHER_1, USER_0, () -> {
5292            assertShortcutIds(assertAllPinned(
5293                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5294                    /* empty */);
5295            assertShortcutIds(assertAllPinned(
5296                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5297                    /* empty */);
5298            assertShortcutIds(assertAllPinned(
5299                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5300                    /* empty */);
5301        });
5302        installPackage(USER_0, LAUNCHER_2);
5303        runWithCaller(LAUNCHER_2, USER_0, () -> {
5304            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5305                    .areAllPinned()
5306                    .haveIds("s2")
5307                    .areAllDisabled();
5308            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5309                    .areAllPinned()
5310                    .haveIds("s2", "s3");
5311            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5312                    .isEmpty();
5313        });
5314
5315        // Because launcher 1 wasn't restored, "s1" is no longer pinned.
5316        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5317            assertEquals(0, mManager.getDynamicShortcuts().size());
5318            assertShortcutIds(assertAllPinned(
5319                    mManager.getPinnedShortcuts()),
5320                    "s2", "s3");
5321        });
5322
5323        installPackage(USER_0, CALLING_PACKAGE_3);
5324        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5325            assertEquals(0, mManager.getDynamicShortcuts().size());
5326            assertEquals(0, mManager.getPinnedShortcuts().size());
5327        });
5328
5329        runWithCaller(LAUNCHER_1, USER_0, () -> {
5330            assertShortcutIds(assertAllPinned(
5331                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5332                    /* empty */);
5333            assertShortcutIds(assertAllPinned(
5334                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5335                    /* empty */);
5336            assertShortcutIds(assertAllPinned(
5337                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5338                    /* empty */);
5339        });
5340        runWithCaller(LAUNCHER_2, USER_0, () -> {
5341            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5342                    .areAllPinned()
5343                    .haveIds("s2")
5344                    .areAllDisabled();
5345            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5346                    .areAllPinned()
5347                    .haveIds("s2", "s3");
5348            assertWith(
5349                    mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5350                    .haveIds("s2", "s3", "s4")
5351                    .areAllDisabled()
5352                    .areAllPinned()
5353                    .areAllNotDynamic()
5354                    .areAllWithDisabledReason(
5355                            ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
5356        });
5357    }
5358
5359    public void testBackupAndRestore_disabled() {
5360        prepareCrossProfileDataSet();
5361
5362        // Before doing backup & restore, disable s1.
5363        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5364            mManager.disableShortcuts(list("s1"));
5365        });
5366
5367        backupAndRestore();
5368
5369        // Below is copied from checkBackupAndRestore_success.
5370
5371        // Make sure non-system user is not restored.
5372        final ShortcutUser userP0 = mService.getUserShortcutsLocked(USER_P0);
5373        assertEquals(0, userP0.getAllPackagesForTest().size());
5374        assertEquals(0, userP0.getAllLaunchersForTest().size());
5375
5376        // Make sure only "allowBackup" apps are restored, and are shadow.
5377        final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
5378        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
5379        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
5380        assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
5381        assertExistsAndShadow(user0.getAllLaunchersForTest().get(
5382                PackageWithUser.of(USER_0, LAUNCHER_1)));
5383        assertExistsAndShadow(user0.getAllLaunchersForTest().get(
5384                PackageWithUser.of(USER_0, LAUNCHER_2)));
5385
5386        assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_0, LAUNCHER_3)));
5387        assertNull(user0.getAllLaunchersForTest().get(PackageWithUser.of(USER_P0, LAUNCHER_1)));
5388
5389        installPackage(USER_0, CALLING_PACKAGE_1);
5390        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5391            assertWith(getCallerVisibleShortcuts())
5392                    .areAllEnabled() // disabled shortcuts shouldn't be restored.
5393
5394                    .selectDynamic()
5395                    .isEmpty()
5396
5397                    .revertToOriginalList()
5398                    .selectPinned()
5399                    // s1 is not restored.
5400                    .haveIds("s2");
5401        });
5402
5403        installPackage(USER_0, LAUNCHER_1);
5404        runWithCaller(LAUNCHER_1, USER_0, () -> {
5405            // Note, s1 was pinned by launcher 1, but was disabled, so isn't restored.
5406            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
5407                    .isEmpty();
5408
5409            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
5410                    .isEmpty();
5411
5412            assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
5413                    .isEmpty();
5414
5415            assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
5416                    .isEmpty();
5417        });
5418    }
5419
5420
5421    public void testBackupAndRestore_manifestRePublished() {
5422        // Publish two manifest shortcuts.
5423        addManifestShortcutResource(
5424                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5425                R.xml.shortcut_2);
5426        updatePackageVersion(CALLING_PACKAGE_1, 1);
5427        mService.mPackageMonitor.onReceive(mServiceContext,
5428                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
5429
5430        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5431            assertTrue(mManager.setDynamicShortcuts(list(
5432                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
5433        });
5434
5435        // Pin from launcher 1.
5436        runWithCaller(LAUNCHER_1, USER_0, () -> {
5437            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
5438                    list("ms1", "ms2", "s1", "s2"), HANDLE_USER_0);
5439        });
5440
5441        // Update and now ms2 is gone -> disabled.
5442        addManifestShortcutResource(
5443                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5444                R.xml.shortcut_1);
5445        updatePackageVersion(CALLING_PACKAGE_1, 1);
5446        mService.mPackageMonitor.onReceive(mServiceContext,
5447                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
5448
5449        // Make sure the manifest shortcuts have been published.
5450        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5451            assertWith(getCallerShortcuts())
5452                    .selectManifest()
5453                    .haveIds("ms1")
5454
5455                    .revertToOriginalList()
5456                    .selectDynamic()
5457                    .haveIds("s1", "s2", "s3")
5458
5459                    .revertToOriginalList()
5460                    .selectPinned()
5461                    .haveIds("ms1", "ms2", "s1", "s2")
5462
5463                    .revertToOriginalList()
5464                    .selectByIds("ms1")
5465                    .areAllManifest()
5466                    .areAllEnabled()
5467
5468                    .revertToOriginalList()
5469                    .selectByIds("ms2")
5470                    .areAllNotManifest()
5471                    .areAllDisabled();
5472        });
5473
5474        backupAndRestore();
5475
5476        // When re-installing the app, the manifest shortcut should be re-published.
5477        mService.mPackageMonitor.onReceive(mServiceContext,
5478                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
5479        mService.mPackageMonitor.onReceive(mServiceContext,
5480                genPackageAddIntent(LAUNCHER_1, USER_0));
5481
5482        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5483            assertWith(getCallerVisibleShortcuts())
5484                    .selectPinned()
5485                    // ms2 was disabled, so not restored.
5486                    .haveIds("ms1", "s1", "s2")
5487                    .areAllEnabled()
5488
5489                    .revertToOriginalList()
5490                    .selectByIds("ms1")
5491                    .areAllManifest()
5492
5493                    .revertToOriginalList()
5494                    .selectByIds("s1", "s2")
5495                    .areAllNotDynamic()
5496            ;
5497        });
5498    }
5499
5500    /**
5501     * It's the case with preintalled apps -- when applyRestore() is called, the system
5502     * apps are already installed, so manifest shortcuts need to be re-published.
5503     *
5504     * Also, when a restore target app is already installed, and
5505     * - if it has allowBackup=true, we'll restore normally, so all existing shortcuts will be
5506     * replaced. (but manifest shortcuts will be re-published anyway.)  We log a warning on
5507     * logcat.
5508     * - if it has allowBackup=false, we don't touch any of the existing shortcuts.
5509     */
5510    public void testBackupAndRestore_appAlreadyInstalledWhenRestored() {
5511        // Pre-backup.  Same as testBackupAndRestore_manifestRePublished().
5512
5513        // Publish two manifest shortcuts.
5514        addManifestShortcutResource(
5515                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5516                R.xml.shortcut_2);
5517        updatePackageVersion(CALLING_PACKAGE_1, 1);
5518        mService.mPackageMonitor.onReceive(mServiceContext,
5519                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
5520
5521        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5522            assertTrue(mManager.setDynamicShortcuts(list(
5523                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
5524        });
5525
5526        // Pin from launcher 1.
5527        runWithCaller(LAUNCHER_1, USER_0, () -> {
5528            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
5529                    list("ms1", "ms2", "s1", "s2"), HANDLE_USER_0);
5530        });
5531
5532        // Update and now ms2 is gone -> disabled.
5533        addManifestShortcutResource(
5534                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5535                R.xml.shortcut_1);
5536        updatePackageVersion(CALLING_PACKAGE_1, 1);
5537        mService.mPackageMonitor.onReceive(mServiceContext,
5538                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
5539
5540        // Set up shortcuts for package 3, which won't be backed up / restored.
5541        addManifestShortcutResource(
5542                new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
5543                R.xml.shortcut_1);
5544        updatePackageVersion(CALLING_PACKAGE_3, 1);
5545        mService.mPackageMonitor.onReceive(mServiceContext,
5546                genPackageAddIntent(CALLING_PACKAGE_3, USER_0));
5547
5548        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5549            assertTrue(getManager().setDynamicShortcuts(list(
5550                    makeShortcut("s1"))));
5551        });
5552
5553        // Make sure the manifest shortcuts have been published.
5554        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5555            assertWith(getCallerShortcuts())
5556                    .selectManifest()
5557                    .haveIds("ms1")
5558
5559                    .revertToOriginalList()
5560                    .selectDynamic()
5561                    .haveIds("s1", "s2", "s3")
5562
5563                    .revertToOriginalList()
5564                    .selectPinned()
5565                    .haveIds("ms1", "ms2", "s1", "s2")
5566
5567                    .revertToOriginalList()
5568                    .selectByIds("ms1")
5569                    .areAllManifest()
5570                    .areAllEnabled()
5571
5572                    .revertToOriginalList()
5573                    .selectByIds("ms2")
5574                    .areAllNotManifest()
5575                    .areAllDisabled();
5576        });
5577
5578        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5579            assertWith(getCallerShortcuts())
5580                    .haveIds("s1", "ms1");
5581        });
5582
5583        // Backup and *without restarting the service, just call applyRestore()*.
5584        {
5585            int prevUid = mInjectedCallingUid;
5586            mInjectedCallingUid = Process.SYSTEM_UID; // Only system can call it.
5587
5588            dumpsysOnLogcat("Before backup");
5589
5590            final byte[] payload = mService.getBackupPayload(USER_0);
5591            if (ENABLE_DUMP) {
5592                final String xml = new String(payload);
5593                Log.v(TAG, "Backup payload:");
5594                for (String line : xml.split("\n")) {
5595                    Log.v(TAG, line);
5596                }
5597            }
5598            mService.applyRestore(payload, USER_0);
5599
5600            dumpsysOnLogcat("After restore");
5601
5602            mInjectedCallingUid = prevUid;
5603        }
5604
5605        // The check is also the same as testBackupAndRestore_manifestRePublished().
5606        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5607            assertWith(getCallerVisibleShortcuts())
5608                    .selectPinned()
5609                    // ms2 was disabled, so not restored.
5610                    .haveIds("ms1", "s1", "s2")
5611                    .areAllEnabled()
5612
5613                    .revertToOriginalList()
5614                    .selectByIds("ms1")
5615                    .areAllManifest()
5616
5617                    .revertToOriginalList()
5618                    .selectByIds("s1", "s2")
5619                    .areAllNotDynamic()
5620            ;
5621        });
5622
5623        // Package 3 still has the same shortcuts.
5624        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5625            assertWith(getCallerShortcuts())
5626                    .haveIds("s1", "ms1");
5627        });
5628    }
5629
5630
5631    /**
5632     * Restored to a lower version with no manifest shortcuts. All shortcuts are now invisible,
5633     * and all calls from the publisher should ignore them.
5634     */
5635    public void testBackupAndRestore_disabledShortcutsAreIgnored() {
5636        // Publish two manifest shortcuts.
5637        addManifestShortcutResource(
5638                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5639                R.xml.shortcut_5_altalt);
5640        updatePackageVersion(CALLING_PACKAGE_1, 1);
5641        mService.mPackageMonitor.onReceive(mServiceContext,
5642                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
5643
5644        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5645            assertTrue(mManager.setDynamicShortcuts(list(
5646                    makeShortcutWithShortLabel("s1", "original-title"),
5647                    makeShortcut("s2"), makeShortcut("s3"))));
5648        });
5649
5650        // Pin from launcher 1.
5651        runWithCaller(LAUNCHER_1, USER_0, () -> {
5652            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
5653                    list("ms1", "ms2", "ms3", "ms4", "s1", "s2"), HANDLE_USER_0);
5654        });
5655
5656        backupAndRestore();
5657
5658        // Lower the version and remove the manifest shortcuts.
5659        addManifestShortcutResource(
5660                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
5661                R.xml.shortcut_0);
5662        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 0); // Lower version
5663
5664        // When re-installing the app, the manifest shortcut should be re-published.
5665        mService.mPackageMonitor.onReceive(mServiceContext,
5666                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
5667        mService.mPackageMonitor.onReceive(mServiceContext,
5668                genPackageAddIntent(LAUNCHER_1, USER_0));
5669
5670        // No shortcuts should be visible to the publisher.
5671        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5672            assertWith(getCallerVisibleShortcuts())
5673                    .isEmpty();
5674        });
5675
5676        final Runnable checkAllDisabledForLauncher = () -> {
5677            runWithCaller(LAUNCHER_1, USER_0, () -> {
5678                assertWith(getShortcutAsLauncher(USER_0))
5679                        .areAllPinned()
5680                        .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
5681                        .areAllDisabled()
5682                        .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_VERSION_LOWER)
5683
5684                        .forShortcutWithId("s1", si -> {
5685                            assertEquals("original-title", si.getShortLabel());
5686                        })
5687                        .forShortcutWithId("ms1", si -> {
5688                            assertEquals("string-com.android.test.1-user:0-res:"
5689                                            + R.string.shortcut_title1 + "/en"
5690                                    , si.getShortLabel());
5691                        })
5692                        .forShortcutWithId("ms2", si -> {
5693                            assertEquals("string-com.android.test.1-user:0-res:"
5694                                            + R.string.shortcut_title2 + "/en"
5695                                    , si.getShortLabel());
5696                        })
5697                        .forShortcutWithId("ms3", si -> {
5698                            assertEquals("string-com.android.test.1-user:0-res:"
5699                                            + R.string.shortcut_title1 + "/en"
5700                                    , si.getShortLabel());
5701                            assertEquals("string-com.android.test.1-user:0-res:"
5702                                            + R.string.shortcut_title2 + "/en"
5703                                    , si.getLongLabel());
5704                        })
5705                        .forShortcutWithId("ms4", si -> {
5706                            assertEquals("string-com.android.test.1-user:0-res:"
5707                                            + R.string.shortcut_title2 + "/en"
5708                                    , si.getShortLabel());
5709                            assertEquals("string-com.android.test.1-user:0-res:"
5710                                            + R.string.shortcut_title2 + "/en"
5711                                    , si.getLongLabel());
5712                        });
5713            });
5714        };
5715
5716        checkAllDisabledForLauncher.run();
5717
5718        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5719
5720            makeCallerForeground(); // CALLING_PACKAGE_1 is now in the foreground.
5721
5722            // All changing API calls should be ignored.
5723
5724            getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
5725            checkAllDisabledForLauncher.run();
5726
5727            getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
5728            checkAllDisabledForLauncher.run();
5729
5730            getManager().enableShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
5731            checkAllDisabledForLauncher.run();
5732
5733            getManager().removeAllDynamicShortcuts();
5734            getManager().removeDynamicShortcuts(list("ms1", "ms2", "ms3", "ms4", "s1", "s2"));
5735            checkAllDisabledForLauncher.run();
5736
5737            getManager().updateShortcuts(list(makeShortcutWithShortLabel("s1", "new-title")));
5738            checkAllDisabledForLauncher.run();
5739
5740
5741            // Add a shortcut -- even though ms1 was immutable, it will succeed.
5742            assertTrue(getManager().addDynamicShortcuts(list(
5743                    makeShortcutWithShortLabel("ms1", "original-title"))));
5744
5745            runWithCaller(LAUNCHER_1, USER_0, () -> {
5746                assertWith(getShortcutAsLauncher(USER_0))
5747                        .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
5748
5749                        .selectByIds("ms1")
5750                        .areAllEnabled()
5751                        .areAllDynamic()
5752                        .areAllPinned()
5753                        .forAllShortcuts(si -> {
5754                            assertEquals("original-title", si.getShortLabel());
5755                        })
5756
5757                        // The rest still exist and disabled.
5758                        .revertToOriginalList()
5759                        .selectByIds("ms2", "ms3", "ms4", "s1", "s2")
5760                        .areAllDisabled()
5761                        .areAllPinned()
5762                ;
5763            });
5764
5765            assertTrue(getManager().setDynamicShortcuts(list(
5766                    makeShortcutWithShortLabel("ms2", "new-title-2"))));
5767
5768            runWithCaller(LAUNCHER_1, USER_0, () -> {
5769                assertWith(getShortcutAsLauncher(USER_0))
5770                        .haveIds("ms1", "ms2", "ms3", "ms4", "s1", "s2")
5771
5772                        .selectByIds("ms1")
5773                        .areAllEnabled()
5774                        .areAllNotDynamic() // ms1 was not in the list, so no longer dynamic.
5775                        .areAllPinned()
5776                        .areAllMutable()
5777                        .forAllShortcuts(si -> {
5778                            assertEquals("original-title", si.getShortLabel());
5779                        })
5780
5781                        .revertToOriginalList()
5782                        .selectByIds("ms2")
5783                        .areAllEnabled()
5784                        .areAllDynamic()
5785                        .areAllPinned()
5786                        .areAllMutable()
5787                        .forAllShortcuts(si -> {
5788                            assertEquals("new-title-2", si.getShortLabel());
5789                        })
5790
5791                        // The rest still exist and disabled.
5792                        .revertToOriginalList()
5793                        .selectByIds("ms3", "ms4", "s1", "s2")
5794                        .areAllDisabled()
5795                        .areAllPinned()
5796                ;
5797            });
5798
5799            // Prepare for requestPinShortcut().
5800            setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_1, USER_0));
5801            mPinConfirmActivityFetcher = (packageName, userId) ->
5802                    new ComponentName(packageName, PIN_CONFIRM_ACTIVITY_CLASS);
5803
5804            mManager.requestPinShortcut(
5805                    makeShortcutWithShortLabel("ms3", "new-title-3"),
5806                    /*PendingIntent=*/ null);
5807
5808            // Note this was pinned, so it'll be accepted right away.
5809            runWithCaller(LAUNCHER_1, USER_0, () -> {
5810                assertWith(getShortcutAsLauncher(USER_0))
5811                        .selectByIds("ms3")
5812                        .areAllEnabled()
5813                        .areAllNotDynamic()
5814                        .areAllPinned()
5815                        .areAllMutable()
5816                        .forAllShortcuts(si -> {
5817                            assertEquals("new-title-3", si.getShortLabel());
5818                            // The new one replaces the old manifest shortcut, so the long label
5819                            // should be gone now.
5820                            assertNull(si.getLongLabel());
5821                        });
5822            });
5823
5824            // Now, change the launcher to launcher2, and request pin again.
5825            setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_2, USER_0));
5826
5827            reset(mServiceContext);
5828
5829            assertTrue(mManager.isRequestPinShortcutSupported());
5830            mManager.requestPinShortcut(
5831                    makeShortcutWithShortLabel("ms4", "new-title-4"),
5832                    /*PendingIntent=*/ null);
5833
5834            // Initially there should be no pinned shortcuts for L2.
5835            runWithCaller(LAUNCHER_2, USER_0, () -> {
5836                assertWith(getShortcutAsLauncher(USER_0))
5837                        .selectPinned()
5838                        .isEmpty();
5839
5840                final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
5841
5842                verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
5843
5844                assertEquals(LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT,
5845                        intent.getValue().getAction());
5846                assertEquals(LAUNCHER_2, intent.getValue().getComponent().getPackageName());
5847
5848                // Check the request object.
5849                final PinItemRequest request = mLauncherApps.getPinItemRequest(intent.getValue());
5850
5851                assertNotNull(request);
5852                assertEquals(PinItemRequest.REQUEST_TYPE_SHORTCUT, request.getRequestType());
5853
5854                assertWith(request.getShortcutInfo())
5855                        .haveIds("ms4")
5856                        .areAllOrphan()
5857                        .forAllShortcuts(si -> {
5858                            assertEquals("new-title-4", si.getShortLabel());
5859                            // The new one replaces the old manifest shortcut, so the long label
5860                            // should be gone now.
5861                            assertNull(si.getLongLabel());
5862                        });
5863                assertTrue(request.accept());
5864
5865                assertWith(getShortcutAsLauncher(USER_0))
5866                        .selectPinned()
5867                        .haveIds("ms4")
5868                        .areAllEnabled();
5869            });
5870        });
5871    }
5872
5873    /**
5874     * Test for restoring the pre-P backup format.
5875     */
5876    public void testBackupAndRestore_api27format() throws Exception {
5877        final byte[] payload = readTestAsset("shortcut/shortcut_api27_backup.xml").getBytes();
5878
5879        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "22222");
5880        addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "11111");
5881
5882        runWithSystemUid(() -> mService.applyRestore(payload, USER_0));
5883
5884        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5885            assertWith(getCallerShortcuts())
5886                    .areAllPinned()
5887                    .haveIds("s1")
5888                    .areAllEnabled();
5889        });
5890
5891        runWithCaller(LAUNCHER_1, USER_0, () -> {
5892            assertWith(getShortcutAsLauncher(USER_0))
5893                    .areAllPinned()
5894                    .haveIds("s1")
5895                    .areAllEnabled();
5896        });
5897        // Make sure getBackupSourceVersionCode and isBackupSourceBackupAllowed
5898        // are correct. We didn't have them in the old format.
5899        assertEquals(8, mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
5900                .getPackageInfo().getBackupSourceVersionCode());
5901        assertTrue(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
5902                .getPackageInfo().isBackupSourceBackupAllowed());
5903
5904        assertEquals(9, mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
5905                .getPackageInfo().getBackupSourceVersionCode());
5906        assertTrue(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
5907                .getPackageInfo().isBackupSourceBackupAllowed());
5908
5909    }
5910
5911    public void testSaveAndLoad_crossProfile() {
5912        prepareCrossProfileDataSet();
5913
5914        dumpsysOnLogcat("Before save & load");
5915
5916        mService.saveDirtyInfo();
5917        initService();
5918
5919        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
5920            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
5921                    "s1", "s2", "s3");
5922            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
5923                    "s1", "s2", "s3", "s4");
5924        });
5925        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
5926            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
5927                    "s1", "s2", "s3");
5928            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
5929                    "s1", "s2", "s3", "s4", "s5");
5930        });
5931        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
5932            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
5933                    "s1", "s2", "s3");
5934            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
5935                    "s1", "s2", "s3", "s4", "s5", "s6");
5936        });
5937        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
5938            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts())
5939                    /* empty */);
5940            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts())
5941                    /* empty */);
5942        });
5943        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
5944            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
5945                    "s1", "s2", "s3");
5946            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
5947                    "s1", "s2", "s3", "s4", "s5", "s6");
5948        });
5949        runWithCaller(CALLING_PACKAGE_2, USER_P0, () -> {
5950            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts())
5951                    /* empty */);
5952            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts())
5953                    /* empty */);
5954        });
5955        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
5956            assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
5957                    "x1", "x2", "x3");
5958            assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
5959                    "x4", "x5");
5960        });
5961        runWithCaller(LAUNCHER_1, USER_0, () -> {
5962            assertShortcutIds(
5963                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
5964                    "s1");
5965            assertShortcutIds(
5966                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
5967                    "s1", "s2");
5968            assertShortcutIds(
5969                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
5970                    "s1", "s2", "s3");
5971            assertShortcutIds(
5972                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
5973                    /* empty */);
5974            assertShortcutIds(
5975                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
5976                    "s1", "s4");
5977            assertShortcutIds(
5978                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
5979                    /* empty */);
5980            assertExpectException(
5981                    SecurityException.class, "", () -> {
5982                        mLauncherApps.getShortcuts(
5983                                buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10);
5984                    });
5985        });
5986        runWithCaller(LAUNCHER_2, USER_0, () -> {
5987            assertShortcutIds(
5988                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
5989                    "s2");
5990            assertShortcutIds(
5991                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
5992                    "s2", "s3");
5993            assertShortcutIds(
5994                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
5995                    "s2", "s3", "s4");
5996            assertShortcutIds(
5997                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
5998                    /* empty */);
5999            assertShortcutIds(
6000                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
6001                    "s2", "s5");
6002            assertShortcutIds(
6003                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
6004                    /* empty */);
6005        });
6006        runWithCaller(LAUNCHER_3, USER_0, () -> {
6007            assertShortcutIds(
6008                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
6009                    "s3");
6010            assertShortcutIds(
6011                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
6012                    "s3", "s4");
6013            assertShortcutIds(
6014                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
6015                    "s3", "s4", "s5");
6016            assertShortcutIds(
6017                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
6018                    /* empty */);
6019            assertShortcutIds(
6020                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
6021                    "s3", "s6");
6022            assertShortcutIds(
6023                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
6024                    /* empty */);
6025        });
6026        runWithCaller(LAUNCHER_4, USER_0, () -> {
6027            assertShortcutIds(
6028                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0)
6029                    /* empty */);
6030            assertShortcutIds(
6031                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0)
6032                    /* empty */);
6033            assertShortcutIds(
6034                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0)
6035                    /* empty */);
6036            assertShortcutIds(
6037                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
6038                    /* empty */);
6039            assertShortcutIds(
6040                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0)
6041                    /* empty */);
6042            assertShortcutIds(
6043                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
6044                    /* empty */);
6045        });
6046        runWithCaller(LAUNCHER_1, USER_P0, () -> {
6047            assertShortcutIds(
6048                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
6049                    "s3", "s4");
6050            assertShortcutIds(
6051                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
6052                    "s3", "s4", "s5");
6053            assertShortcutIds(
6054                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
6055                    "s3", "s4", "s5", "s6");
6056            assertShortcutIds(
6057                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
6058                    "s1", "s4");
6059            assertExpectException(
6060                    SecurityException.class, "unrelated profile", () -> {
6061                        mLauncherApps.getShortcuts(
6062                                buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10);
6063                    });
6064        });
6065        runWithCaller(LAUNCHER_1, USER_10, () -> {
6066            assertShortcutIds(
6067                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10),
6068                    "x4", "x5");
6069            assertShortcutIds(
6070                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10)
6071                    /* empty */);
6072            assertShortcutIds(
6073                    mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10)
6074                    /* empty */);
6075            assertExpectException(
6076                    SecurityException.class, "unrelated profile", () -> {
6077                        mLauncherApps.getShortcuts(
6078                                buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0);
6079                    });
6080            assertExpectException(
6081                    SecurityException.class, "unrelated profile", () -> {
6082                        mLauncherApps.getShortcuts(
6083                                buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_P0);
6084                    });
6085        });
6086        // Check the user-IDs.
6087        assertEquals(USER_0,
6088                mService.getUserShortcutsLocked(USER_0).getPackageShortcuts(CALLING_PACKAGE_1)
6089                        .getOwnerUserId());
6090        assertEquals(USER_0,
6091                mService.getUserShortcutsLocked(USER_0).getPackageShortcuts(CALLING_PACKAGE_1)
6092                        .getPackageUserId());
6093        assertEquals(USER_P0,
6094                mService.getUserShortcutsLocked(USER_P0).getPackageShortcuts(CALLING_PACKAGE_1)
6095                        .getOwnerUserId());
6096        assertEquals(USER_P0,
6097                mService.getUserShortcutsLocked(USER_P0).getPackageShortcuts(CALLING_PACKAGE_1)
6098                        .getPackageUserId());
6099
6100        assertEquals(USER_0,
6101                mService.getUserShortcutsLocked(USER_0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6102                        .getOwnerUserId());
6103        assertEquals(USER_0,
6104                mService.getUserShortcutsLocked(USER_0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6105                        .getPackageUserId());
6106        assertEquals(USER_P0,
6107                mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6108                        .getOwnerUserId());
6109        assertEquals(USER_0,
6110                mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_0)
6111                        .getPackageUserId());
6112    }
6113
6114    public void testOnApplicationActive_permission() {
6115        assertExpectException(SecurityException.class, "Missing permission", () ->
6116                mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0));
6117
6118        // Has permission, now it should pass.
6119        mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
6120        mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
6121    }
6122
6123    public void testDumpsys_crossProfile() {
6124        prepareCrossProfileDataSet();
6125        dumpsysOnLogcat("test1", /* force= */ true);
6126    }
6127
6128    public void testDumpsys_withIcons() throws IOException {
6129        testIcons();
6130        // Dump after having some icons.
6131        dumpsysOnLogcat("test1", /* force= */ true);
6132    }
6133
6134    public void testManifestShortcut_publishOnUnlockUser() {
6135        addManifestShortcutResource(
6136                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6137                R.xml.shortcut_1);
6138        addManifestShortcutResource(
6139                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
6140                R.xml.shortcut_2);
6141        addManifestShortcutResource(
6142                new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
6143                R.xml.shortcut_5);
6144
6145        // Unlock user-0.
6146        mInjectedCurrentTimeMillis += 100;
6147        mService.handleUnlockUser(USER_0);
6148
6149        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6150            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6151                    mManager.getManifestShortcuts()))),
6152                    "ms1");
6153            assertEmpty(mManager.getPinnedShortcuts());
6154        });
6155
6156        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6157            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6158                    mManager.getManifestShortcuts()))),
6159                    "ms1", "ms2");
6160            assertEmpty(mManager.getPinnedShortcuts());
6161        });
6162
6163        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6164            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6165                    mManager.getManifestShortcuts()))),
6166                    "ms1", "ms2", "ms3", "ms4", "ms5");
6167            assertEmpty(mManager.getPinnedShortcuts());
6168        });
6169
6170        // Try on another user, with some packages uninstalled.
6171        mRunningUsers.put(USER_10, true);
6172
6173        uninstallPackage(USER_10, CALLING_PACKAGE_1);
6174        uninstallPackage(USER_10, CALLING_PACKAGE_3);
6175
6176        mInjectedCurrentTimeMillis += 100;
6177        mService.handleUnlockUser(USER_10);
6178
6179        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
6180            assertEmpty(mManager.getManifestShortcuts());
6181            assertEmpty(mManager.getPinnedShortcuts());
6182        });
6183
6184        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
6185            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6186                    mManager.getManifestShortcuts()))),
6187                    "ms1", "ms2");
6188            assertEmpty(mManager.getPinnedShortcuts());
6189        });
6190
6191        runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
6192            assertEmpty(mManager.getManifestShortcuts());
6193            assertEmpty(mManager.getPinnedShortcuts());
6194        });
6195
6196        // Now change the resources for package 1, and unlock again.
6197        // But we still see *old* shortcuts, because the package version and install time
6198        // hasn't changed.
6199        shutdownServices();
6200
6201        mInjectedCurrentTimeMillis += 100;
6202
6203        addManifestShortcutResource(
6204                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6205                R.xml.shortcut_5);
6206        addManifestShortcutResource(
6207                new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
6208                R.xml.shortcut_1);
6209
6210        initService();
6211        mService.handleUnlockUser(USER_0);
6212
6213        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6214            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( // FAIL
6215                    mManager.getManifestShortcuts()))),
6216                    "ms1");
6217            assertEmpty(mManager.getPinnedShortcuts());
6218        });
6219
6220        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6221            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6222                    mManager.getManifestShortcuts()))),
6223                    "ms1", "ms2");
6224            assertEmpty(mManager.getPinnedShortcuts());
6225        });
6226
6227        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6228            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6229                    mManager.getManifestShortcuts()))),
6230                    "ms1", "ms2", "ms3", "ms4", "ms5");
6231            assertEmpty(mManager.getPinnedShortcuts());
6232        });
6233
6234        // Do it again, but this time we change the app version, so we do detect the changes.
6235        shutdownServices();
6236
6237        mInjectedCurrentTimeMillis += 100;
6238
6239        updatePackageVersion(CALLING_PACKAGE_1, 1);
6240        updatePackageLastUpdateTime(CALLING_PACKAGE_3, 1);
6241
6242        initService();
6243        mService.handleUnlockUser(USER_0);
6244
6245        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6246            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6247                    mManager.getManifestShortcuts()))),
6248                    "ms1", "ms2", "ms3", "ms4", "ms5");
6249            assertEmpty(mManager.getPinnedShortcuts());
6250        });
6251
6252        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6253            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6254                    mManager.getManifestShortcuts()))),
6255                    "ms1", "ms2");
6256            assertEmpty(mManager.getPinnedShortcuts());
6257        });
6258
6259        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6260            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6261                    mManager.getManifestShortcuts()))),
6262                    "ms1");
6263            assertEmpty(mManager.getPinnedShortcuts());
6264        });
6265
6266        // Next, try removing all shortcuts, with some of them pinned.
6267        runWithCaller(LAUNCHER_1, USER_0, () -> {
6268            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms3"), HANDLE_USER_0);
6269            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2"), HANDLE_USER_0);
6270            mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("ms1"), HANDLE_USER_0);
6271        });
6272        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6273            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6274                    mManager.getManifestShortcuts()))),
6275                    "ms1", "ms2", "ms3", "ms4", "ms5");
6276            assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllManifest(
6277                    assertAllEnabled(mManager.getPinnedShortcuts())))),
6278                    "ms3");
6279        });
6280
6281        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6282            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6283                    mManager.getManifestShortcuts()))),
6284                    "ms1", "ms2");
6285            assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllManifest(
6286                    assertAllEnabled(mManager.getPinnedShortcuts())))),
6287                    "ms2");
6288        });
6289
6290        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6291            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6292                    mManager.getManifestShortcuts()))),
6293                    "ms1");
6294            assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllManifest(
6295                    assertAllEnabled(mManager.getPinnedShortcuts())))),
6296                    "ms1");
6297        });
6298
6299        shutdownServices();
6300
6301        mInjectedCurrentTimeMillis += 100;
6302
6303        addManifestShortcutResource(
6304                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6305                R.xml.shortcut_0);
6306        addManifestShortcutResource(
6307                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
6308                R.xml.shortcut_1);
6309        addManifestShortcutResource(
6310                new ComponentName(CALLING_PACKAGE_3, ShortcutActivity.class.getName()),
6311                R.xml.shortcut_0);
6312
6313        updatePackageVersion(CALLING_PACKAGE_1, 1);
6314        updatePackageVersion(CALLING_PACKAGE_2, 1);
6315        updatePackageVersion(CALLING_PACKAGE_3, 1);
6316
6317        initService();
6318        mService.handleUnlockUser(USER_0);
6319
6320        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6321            assertEmpty(mManager.getManifestShortcuts());
6322            assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
6323                    assertAllDisabled(mManager.getPinnedShortcuts())))),
6324                    "ms3");
6325        });
6326
6327        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6328            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6329                    mManager.getManifestShortcuts()))),
6330                    "ms1");
6331            assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
6332                    assertAllDisabled(mManager.getPinnedShortcuts())))),
6333                    "ms2");
6334        });
6335
6336        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6337            assertEmpty(mManager.getManifestShortcuts());
6338            assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
6339                    assertAllDisabled(mManager.getPinnedShortcuts())))),
6340                    "ms1");
6341        });
6342
6343        // Make sure we don't have ShortcutPackage for packages that don't have shortcuts.
6344        assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_4, USER_0));
6345        assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_0));
6346    }
6347
6348    public void testManifestShortcut_publishOnBroadcast() {
6349        // First, no packages are installed.
6350        uninstallPackage(USER_0, CALLING_PACKAGE_1);
6351        uninstallPackage(USER_0, CALLING_PACKAGE_2);
6352        uninstallPackage(USER_0, CALLING_PACKAGE_3);
6353        uninstallPackage(USER_0, CALLING_PACKAGE_4);
6354        uninstallPackage(USER_10, CALLING_PACKAGE_1);
6355        uninstallPackage(USER_10, CALLING_PACKAGE_2);
6356        uninstallPackage(USER_10, CALLING_PACKAGE_3);
6357        uninstallPackage(USER_10, CALLING_PACKAGE_4);
6358
6359        mService.handleUnlockUser(USER_0);
6360
6361        mRunningUsers.put(USER_10, true);
6362        mService.handleUnlockUser(USER_10);
6363
6364        // Originally no manifest shortcuts.
6365        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6366            assertEmpty(mManager.getManifestShortcuts());
6367            assertEmpty(mManager.getPinnedShortcuts());
6368        });
6369
6370        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6371            assertEmpty(mManager.getManifestShortcuts());
6372            assertEmpty(mManager.getPinnedShortcuts());
6373        });
6374
6375        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
6376            assertEmpty(mManager.getManifestShortcuts());
6377            assertEmpty(mManager.getPinnedShortcuts());
6378        });
6379
6380        // Package 1 updated, with manifest shortcuts.
6381        addManifestShortcutResource(
6382                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6383                R.xml.shortcut_1);
6384        updatePackageVersion(CALLING_PACKAGE_1, 1);
6385                mService.mPackageMonitor.onReceive(getTestContext(),
6386                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6387
6388        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6389            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6390                    mManager.getManifestShortcuts()))),
6391                    "ms1");
6392            assertEmpty(mManager.getPinnedShortcuts());
6393        });
6394
6395        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6396            assertEmpty(mManager.getManifestShortcuts());
6397            assertEmpty(mManager.getPinnedShortcuts());
6398        });
6399
6400        // Package 2 updated, with manifest shortcuts.
6401
6402        addManifestShortcutResource(
6403                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
6404                R.xml.shortcut_5_altalt);
6405        updatePackageVersion(CALLING_PACKAGE_2, 1);
6406                mService.mPackageMonitor.onReceive(getTestContext(),
6407                genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
6408
6409        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6410            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6411                    mManager.getManifestShortcuts()))),
6412                    "ms1");
6413            assertEmpty(mManager.getPinnedShortcuts());
6414        });
6415
6416        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6417            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6418                    mManager.getManifestShortcuts()))),
6419                    "ms1", "ms2", "ms3", "ms4", "ms5");
6420            assertWith(getCallerShortcuts()).selectManifest()
6421                    .selectByActivity(
6422                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
6423                    .haveRanksInOrder("ms1", "ms2", "ms3", "ms4", "ms5");
6424            assertEmpty(mManager.getPinnedShortcuts());
6425        });
6426
6427        // Package 2 updated, with less manifest shortcuts.
6428        // This time we use updatePackageLastUpdateTime() instead of updatePackageVersion().
6429
6430        dumpsysOnLogcat("Before pinning");
6431
6432        // Also pin some.
6433        runWithCaller(LAUNCHER_1, USER_0, () -> {
6434            mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2", "ms3"), HANDLE_USER_0);
6435        });
6436
6437        dumpsysOnLogcat("After pinning");
6438
6439        addManifestShortcutResource(
6440                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
6441                R.xml.shortcut_2);
6442        updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
6443                mService.mPackageMonitor.onReceive(getTestContext(),
6444                genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
6445
6446        dumpsysOnLogcat("After updating package 2");
6447
6448        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6449            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6450                    mManager.getManifestShortcuts()))),
6451                    "ms1");
6452            assertEmpty(mManager.getPinnedShortcuts());
6453        });
6454
6455        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6456            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6457                    mManager.getManifestShortcuts()))),
6458                    "ms1", "ms2");
6459            assertWith(getCallerShortcuts()).selectManifest()
6460                    .selectByActivity(
6461                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
6462                    .haveRanksInOrder("ms1", "ms2");
6463            assertShortcutIds(assertAllImmutable(assertAllPinned(
6464                    mManager.getPinnedShortcuts())),
6465                    "ms2", "ms3");
6466            // ms3 is no longer in manifest, so should be disabled.
6467            // but ms1 and ms2 should be enabled.
6468            assertWith(getCallerShortcuts())
6469                    .selectByIds("ms1", "ms2")
6470                    .areAllEnabled()
6471
6472                    .revertToOriginalList()
6473                    .selectByIds("ms3")
6474                    .areAllDisabled()
6475                    .areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_APP_CHANGED);
6476        });
6477
6478        // Make sure the launcher see the correct disabled reason.
6479        runWithCaller(LAUNCHER_1, USER_0, () -> {
6480            assertWith(getShortcutAsLauncher(USER_0))
6481                    .forShortcutWithId("ms3", si -> {
6482                        assertEquals("string-com.android.test.2-user:0-res:"
6483                                        + R.string.shortcut_disabled_message3 + "/en",
6484                                si.getDisabledMessage());
6485                    });
6486        });
6487
6488
6489        // Package 2 on user 10 has no shortcuts yet.
6490        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
6491            assertEmpty(mManager.getManifestShortcuts());
6492            assertEmpty(mManager.getPinnedShortcuts());
6493        });
6494        // Send add broadcast, but the user is not running, so should be ignored.
6495        mService.handleStopUser(USER_10);
6496        mRunningUsers.put(USER_10, false);
6497        mUnlockedUsers.put(USER_10, false);
6498
6499        mService.mPackageMonitor.onReceive(getTestContext(),
6500                genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
6501        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
6502            // Don't use the mManager APIs to get shortcuts, because they'll trigger the package
6503            // update check.
6504            // So look the internal data directly using getCallerShortcuts().
6505            assertEmpty(getCallerShortcuts());
6506        });
6507
6508        // Try again, but the user is locked, so still ignored.
6509        mRunningUsers.put(USER_10, true);
6510                mService.mPackageMonitor.onReceive(getTestContext(),
6511                genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
6512        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
6513            // Don't use the mManager APIs to get shortcuts, because they'll trigger the package
6514            // update check.
6515            // So look the internal data directly using getCallerShortcuts().
6516            assertEmpty(getCallerShortcuts());
6517        });
6518
6519        // Unlock the user, now it should work.
6520        mUnlockedUsers.put(USER_10, true);
6521
6522        // Send PACKAGE_ADD broadcast to have Package 2 on user-10 publish manifest shortcuts.
6523                mService.mPackageMonitor.onReceive(getTestContext(),
6524                genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
6525
6526        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
6527            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6528                    mManager.getManifestShortcuts()))),
6529                    "ms1", "ms2");
6530            assertWith(getCallerShortcuts()).selectManifest()
6531                    .selectByActivity(
6532                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
6533                    .haveRanksInOrder("ms1", "ms2");
6534            assertEmpty(mManager.getPinnedShortcuts());
6535        });
6536
6537        // But it shouldn't affect user-0.
6538        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6539            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6540                    mManager.getManifestShortcuts()))),
6541                    "ms1", "ms2");
6542            assertWith(getCallerShortcuts()).selectManifest()
6543                    .selectByActivity(
6544                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
6545                    .haveRanksInOrder("ms1", "ms2");
6546            assertShortcutIds(assertAllImmutable(assertAllPinned(
6547                    mManager.getPinnedShortcuts())),
6548                    "ms2", "ms3");
6549            assertAllEnabled(list(getCallerShortcut("ms1")));
6550            assertAllEnabled(list(getCallerShortcut("ms2")));
6551            assertAllDisabled(list(getCallerShortcut("ms3")));
6552        });
6553
6554        // Multiple activities.
6555        // Add shortcuts on activity 2 for package 2.
6556        addManifestShortcutResource(
6557                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
6558                R.xml.shortcut_5_alt);
6559        addManifestShortcutResource(
6560                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()),
6561                R.xml.shortcut_5_reverse);
6562
6563        updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
6564                mService.mPackageMonitor.onReceive(getTestContext(),
6565                genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
6566
6567        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6568            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6569                    mManager.getManifestShortcuts()))),
6570                    "ms1", "ms2", "ms3", "ms4", "ms5",
6571                    "ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
6572
6573            // Make sure they have the correct ranks, regardless of their ID's alphabetical order.
6574            assertWith(getCallerShortcuts()).selectManifest()
6575                    .selectByActivity(
6576                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
6577                    .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
6578            assertWith(getCallerShortcuts()).selectManifest()
6579                    .selectByActivity(
6580                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()))
6581                    .haveRanksInOrder("ms5", "ms4", "ms3", "ms2", "ms1");
6582        });
6583
6584        // Package 2 now has no manifest shortcuts.
6585        addManifestShortcutResource(
6586                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
6587                R.xml.shortcut_0);
6588        addManifestShortcutResource(
6589                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()),
6590                R.xml.shortcut_0);
6591        updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
6592                mService.mPackageMonitor.onReceive(getTestContext(),
6593                genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
6594
6595        // No manifest shortcuts, and pinned ones are disabled.
6596        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
6597            assertEmpty(mManager.getManifestShortcuts());
6598            assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllDisabled(
6599                    mManager.getPinnedShortcuts()))),
6600                    "ms2", "ms3");
6601        });
6602    }
6603
6604    public void testManifestShortcuts_missingMandatoryFields() {
6605        // Start with no apps installed.
6606        uninstallPackage(USER_0, CALLING_PACKAGE_1);
6607        uninstallPackage(USER_0, CALLING_PACKAGE_2);
6608        uninstallPackage(USER_0, CALLING_PACKAGE_3);
6609        uninstallPackage(USER_0, CALLING_PACKAGE_4);
6610
6611        mService.handleUnlockUser(USER_0);
6612
6613        // Make sure no manifest shortcuts.
6614        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6615            assertEmpty(mManager.getManifestShortcuts());
6616        });
6617
6618        // Package 1 updated, which has one valid manifest shortcut and one invalid.
6619        addManifestShortcutResource(
6620                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6621                R.xml.shortcut_error_1);
6622        updatePackageVersion(CALLING_PACKAGE_1, 1);
6623                mService.mPackageMonitor.onReceive(getTestContext(),
6624                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6625
6626        // Only the valid one is published.
6627        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6628            assertWith(getCallerShortcuts())
6629                    .areAllManifest()
6630                    .areAllImmutable()
6631                    .areAllEnabled()
6632                    .haveIds("x1");
6633        });
6634
6635        // Package 1 updated, which has one valid manifest shortcut and one invalid.
6636        addManifestShortcutResource(
6637                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6638                R.xml.shortcut_error_2);
6639        updatePackageVersion(CALLING_PACKAGE_1, 1);
6640                mService.mPackageMonitor.onReceive(getTestContext(),
6641                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6642
6643        // Only the valid one is published.
6644        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6645            assertWith(getCallerShortcuts())
6646                    .areAllManifest()
6647                    .areAllImmutable()
6648                    .areAllEnabled()
6649                    .haveIds("x2");
6650        });
6651
6652        // Package 1 updated, which has one valid manifest shortcut and one invalid.
6653        addManifestShortcutResource(
6654                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6655                R.xml.shortcut_error_3);
6656        updatePackageVersion(CALLING_PACKAGE_1, 1);
6657                mService.mPackageMonitor.onReceive(getTestContext(),
6658                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6659
6660        // Only the valid one is published.
6661        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6662            assertWith(getCallerShortcuts())
6663                    .areAllManifest()
6664                    .areAllImmutable()
6665                    .areAllEnabled()
6666                    .haveIds("x3")
6667                    .forShortcutWithId("x3", si -> {
6668                        assertEquals(set("cat2"), si.getCategories());
6669                     });
6670        });
6671    }
6672
6673    public void testManifestShortcuts_intentDefinitions() {
6674        addManifestShortcutResource(
6675                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6676                R.xml.shortcut_error_4);
6677        updatePackageVersion(CALLING_PACKAGE_1, 1);
6678                mService.mPackageMonitor.onReceive(getTestContext(),
6679                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6680
6681        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6682            // Make sure invalid ones are not published.
6683            // Note that at this point disabled ones don't show up because they weren't pinned.
6684            assertWith(getCallerShortcuts())
6685                    .haveIds("ms1", "ms2")
6686                    .areAllManifest()
6687                    .areAllNotDynamic()
6688                    .areAllNotPinned()
6689                    .areAllImmutable()
6690                    .areAllEnabled()
6691                    .forShortcutWithId("ms1", si -> {
6692                        assertTrue(si.isEnabled());
6693                        assertEquals(1, si.getIntents().length);
6694
6695                        assertEquals("action1", si.getIntent().getAction());
6696                        assertEquals("value1", si.getIntent().getStringExtra("key1"));
6697                        assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK |
6698                                Intent.FLAG_ACTIVITY_CLEAR_TASK |
6699                                Intent.FLAG_ACTIVITY_TASK_ON_HOME, si.getIntent().getFlags());
6700
6701                        assertEquals("action1", si.getIntents()[0].getAction());
6702                        assertEquals("value1", si.getIntents()[0].getStringExtra("key1"));
6703                        assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK |
6704                                Intent.FLAG_ACTIVITY_CLEAR_TASK |
6705                                Intent.FLAG_ACTIVITY_TASK_ON_HOME, si.getIntents()[0].getFlags());
6706                    })
6707                    .forShortcutWithId("ms2", si -> {
6708                        assertTrue(si.isEnabled());
6709                        assertEquals(2, si.getIntents().length);
6710
6711                        // getIntent will return the last one.
6712                        assertEquals("action2_2", si.getIntent().getAction());
6713                        assertEquals("value2", si.getIntent().getStringExtra("key2"));
6714                        assertEquals(0, si.getIntent().getFlags());
6715
6716                        final Intent i1 = si.getIntents()[0];
6717                        final Intent i2 = si.getIntents()[1];
6718
6719                        assertEquals("action2_1", i1.getAction());
6720                        assertEquals("value1", i1.getStringExtra("key1"));
6721                        assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK |
6722                                        Intent.FLAG_ACTIVITY_CLEAR_TASK |
6723                                        Intent.FLAG_ACTIVITY_TASK_ON_HOME, i1.getFlags());
6724
6725                        assertEquals("action2_2", i2.getAction());
6726                        assertEquals("value2", i2.getStringExtra("key2"));
6727                        assertEquals(0, i2.getFlags());
6728                    });
6729        });
6730
6731        // Publish 5 enabled to pin some, so we can later test disabled manfiest shortcuts..
6732        addManifestShortcutResource(
6733                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6734                R.xml.shortcut_5);
6735        updatePackageVersion(CALLING_PACKAGE_1, 1);
6736                mService.mPackageMonitor.onReceive(getTestContext(),
6737                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6738
6739        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6740            // Make sure 5 manifest shortcuts are published.
6741            assertWith(getCallerShortcuts())
6742                    .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
6743                    .areAllManifest()
6744                    .areAllNotDynamic()
6745                    .areAllNotPinned()
6746                    .areAllImmutable()
6747                    .areAllEnabled();
6748        });
6749
6750        runWithCaller(LAUNCHER_1, USER_0, () -> {
6751            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
6752                    list("ms3", "ms4", "ms5"), HANDLE_USER_0);
6753        });
6754
6755        // Make sure they're pinned.
6756        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6757            assertWith(getCallerShortcuts())
6758                    .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
6759                    .selectByIds("ms1", "ms2")
6760                    .areAllNotPinned()
6761                    .areAllEnabled()
6762
6763                    .revertToOriginalList()
6764                    .selectByIds("ms3", "ms4", "ms5")
6765                    .areAllPinned()
6766                    .areAllEnabled();
6767        });
6768
6769        // Update the app.
6770        addManifestShortcutResource(
6771                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6772                R.xml.shortcut_error_4);
6773        updatePackageVersion(CALLING_PACKAGE_1, 1);
6774                mService.mPackageMonitor.onReceive(getTestContext(),
6775                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6776
6777        // Make sure 3, 4 and 5 still exist but disabled.
6778        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6779            assertWith(getCallerShortcuts())
6780                    .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
6781                    .areAllNotDynamic()
6782                    .areAllImmutable()
6783
6784                    .selectByIds("ms1", "ms2")
6785                    .areAllManifest()
6786                    .areAllNotPinned()
6787                    .areAllEnabled()
6788
6789                    .revertToOriginalList()
6790                    .selectByIds("ms3", "ms4", "ms5")
6791                    .areAllNotManifest()
6792                    .areAllPinned()
6793                    .areAllDisabled()
6794
6795                    .revertToOriginalList()
6796                    .forShortcutWithId("ms1", si -> {
6797                        assertEquals(si.getId(), "action1", si.getIntent().getAction());
6798                    })
6799                    .forShortcutWithId("ms2", si -> {
6800                        // getIntent returns the last one.
6801                        assertEquals(si.getId(), "action2_2", si.getIntent().getAction());
6802                    })
6803                    .forShortcutWithId("ms3", si -> {
6804                        assertEquals(si.getId(), Intent.ACTION_VIEW, si.getIntent().getAction());
6805                    })
6806                    .forShortcutWithId("ms4", si -> {
6807                        assertEquals(si.getId(), Intent.ACTION_VIEW, si.getIntent().getAction());
6808                    })
6809                    .forShortcutWithId("ms5", si -> {
6810                        assertEquals(si.getId(), "action", si.getIntent().getAction());
6811                    });
6812        });
6813    }
6814
6815    public void testManifestShortcuts_checkAllFields() {
6816        mService.handleUnlockUser(USER_0);
6817
6818        // Package 1 updated, which has one valid manifest shortcut and one invalid.
6819        addManifestShortcutResource(
6820                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6821                R.xml.shortcut_5);
6822        updatePackageVersion(CALLING_PACKAGE_1, 1);
6823                mService.mPackageMonitor.onReceive(getTestContext(),
6824                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6825
6826        // Only the valid one is published.
6827        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6828            assertWith(getCallerShortcuts())
6829                    .haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
6830                    .areAllManifest()
6831                    .areAllImmutable()
6832                    .areAllEnabled()
6833                    .areAllNotPinned()
6834                    .areAllNotDynamic()
6835
6836                    .forShortcutWithId("ms1", si -> {
6837                        assertEquals(R.drawable.icon1, si.getIconResourceId());
6838                        assertEquals(new ComponentName(CALLING_PACKAGE_1,
6839                                ShortcutActivity.class.getName()),
6840                                si.getActivity());
6841
6842                        assertEquals(R.string.shortcut_title1, si.getTitleResId());
6843                        assertEquals("r" + R.string.shortcut_title1, si.getTitleResName());
6844                        assertEquals(R.string.shortcut_text1, si.getTextResId());
6845                        assertEquals("r" + R.string.shortcut_text1, si.getTextResName());
6846                        assertEquals(R.string.shortcut_disabled_message1,
6847                                si.getDisabledMessageResourceId());
6848                        assertEquals("r" + R.string.shortcut_disabled_message1,
6849                                si.getDisabledMessageResName());
6850
6851                        assertEquals(set("android.shortcut.conversation", "android.shortcut.media"),
6852                                si.getCategories());
6853                        assertEquals("action1", si.getIntent().getAction());
6854                        assertEquals(Uri.parse("http://a.b.c/1"), si.getIntent().getData());
6855                    })
6856
6857                    .forShortcutWithId("ms2", si -> {
6858                        assertEquals("ms2", si.getId());
6859                        assertEquals(R.drawable.icon2, si.getIconResourceId());
6860
6861                        assertEquals(R.string.shortcut_title2, si.getTitleResId());
6862                        assertEquals("r" + R.string.shortcut_title2, si.getTitleResName());
6863                        assertEquals(R.string.shortcut_text2, si.getTextResId());
6864                        assertEquals("r" + R.string.shortcut_text2, si.getTextResName());
6865                        assertEquals(R.string.shortcut_disabled_message2,
6866                                si.getDisabledMessageResourceId());
6867                        assertEquals("r" + R.string.shortcut_disabled_message2,
6868                                si.getDisabledMessageResName());
6869
6870                        assertEquals(set("android.shortcut.conversation"), si.getCategories());
6871                        assertEquals("action2", si.getIntent().getAction());
6872                        assertEquals(null, si.getIntent().getData());
6873                    })
6874
6875                    .forShortcutWithId("ms3", si -> {
6876                        assertEquals(0, si.getIconResourceId());
6877                        assertEquals(R.string.shortcut_title1, si.getTitleResId());
6878                        assertEquals("r" + R.string.shortcut_title1, si.getTitleResName());
6879
6880                        assertEquals(0, si.getTextResId());
6881                        assertEquals(null, si.getTextResName());
6882                        assertEquals(0, si.getDisabledMessageResourceId());
6883                        assertEquals(null, si.getDisabledMessageResName());
6884
6885                        assertEmpty(si.getCategories());
6886                        assertEquals("android.intent.action.VIEW", si.getIntent().getAction());
6887                        assertEquals(null, si.getIntent().getData());
6888                    })
6889
6890                    .forShortcutWithId("ms4", si -> {
6891                        assertEquals(0, si.getIconResourceId());
6892                        assertEquals(R.string.shortcut_title2, si.getTitleResId());
6893                        assertEquals("r" + R.string.shortcut_title2, si.getTitleResName());
6894
6895                        assertEquals(0, si.getTextResId());
6896                        assertEquals(null, si.getTextResName());
6897                        assertEquals(0, si.getDisabledMessageResourceId());
6898                        assertEquals(null, si.getDisabledMessageResName());
6899
6900                        assertEquals(set("cat"), si.getCategories());
6901                        assertEquals("android.intent.action.VIEW2", si.getIntent().getAction());
6902                        assertEquals(null, si.getIntent().getData());
6903                    })
6904
6905                    .forShortcutWithId("ms5", si -> {
6906                        si = getCallerShortcut("ms5");
6907                        assertEquals("action", si.getIntent().getAction());
6908                        assertEquals("http://www/", si.getIntent().getData().toString());
6909                        assertEquals("foo/bar", si.getIntent().getType());
6910                        assertEquals(
6911                                new ComponentName("abc", ".xyz"), si.getIntent().getComponent());
6912
6913                        assertEquals(set("cat1", "cat2"), si.getIntent().getCategories());
6914                        assertEquals("value1", si.getIntent().getStringExtra("key1"));
6915                        assertEquals("value2", si.getIntent().getStringExtra("key2"));
6916                    });
6917        });
6918    }
6919
6920    public void testManifestShortcuts_localeChange() throws InterruptedException {
6921        mService.handleUnlockUser(USER_0);
6922
6923        // Package 1 updated, which has one valid manifest shortcut and one invalid.
6924        addManifestShortcutResource(
6925                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
6926                R.xml.shortcut_2);
6927        updatePackageVersion(CALLING_PACKAGE_1, 1);
6928                mService.mPackageMonitor.onReceive(getTestContext(),
6929                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
6930
6931        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6932            mManager.setDynamicShortcuts(list(makeShortcutWithTitle("s1", "title")));
6933
6934            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
6935                    mManager.getManifestShortcuts()))),
6936                    "ms1", "ms2");
6937
6938            // check first shortcut.
6939            ShortcutInfo si = getCallerShortcut("ms1");
6940
6941            assertEquals("ms1", si.getId());
6942            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title1 + "/en",
6943                    si.getTitle());
6944            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text1 + "/en",
6945                    si.getText());
6946            assertEquals("string-com.android.test.1-user:0-res:"
6947                            + R.string.shortcut_disabled_message1 + "/en",
6948                    si.getDisabledMessage());
6949            assertEquals(START_TIME, si.getLastChangedTimestamp());
6950
6951            // check another
6952            si = getCallerShortcut("ms2");
6953
6954            assertEquals("ms2", si.getId());
6955            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title2 + "/en",
6956                    si.getTitle());
6957            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text2 + "/en",
6958                    si.getText());
6959            assertEquals("string-com.android.test.1-user:0-res:"
6960                            + R.string.shortcut_disabled_message2 + "/en",
6961                    si.getDisabledMessage());
6962            assertEquals(START_TIME, si.getLastChangedTimestamp());
6963
6964            // Check the dynamic one.
6965            si = getCallerShortcut("s1");
6966
6967            assertEquals("s1", si.getId());
6968            assertEquals("title", si.getTitle());
6969            assertEquals(null, si.getText());
6970            assertEquals(null, si.getDisabledMessage());
6971            assertEquals(START_TIME, si.getLastChangedTimestamp());
6972        });
6973
6974        mInjectedCurrentTimeMillis++;
6975
6976        // Change the locale and send the broadcast, make sure the launcher gets a callback too.
6977        mInjectedLocale = Locale.JAPANESE;
6978
6979        setCaller(LAUNCHER_1, USER_0);
6980
6981        assertForLauncherCallback(mLauncherApps, () -> {
6982            mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
6983        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
6984                .haveIds("ms1", "ms2", "s1");
6985
6986        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
6987            // check first shortcut.
6988            ShortcutInfo si = getCallerShortcut("ms1");
6989
6990            assertEquals("ms1", si.getId());
6991            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title1 + "/ja",
6992                    si.getTitle());
6993            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text1 + "/ja",
6994                    si.getText());
6995            assertEquals("string-com.android.test.1-user:0-res:"
6996                            + R.string.shortcut_disabled_message1 + "/ja",
6997                    si.getDisabledMessage());
6998            assertEquals(START_TIME + 1, si.getLastChangedTimestamp());
6999
7000            // check another
7001            si = getCallerShortcut("ms2");
7002
7003            assertEquals("ms2", si.getId());
7004            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title2 + "/ja",
7005                    si.getTitle());
7006            assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text2 + "/ja",
7007                    si.getText());
7008            assertEquals("string-com.android.test.1-user:0-res:"
7009                            + R.string.shortcut_disabled_message2 + "/ja",
7010                    si.getDisabledMessage());
7011            assertEquals(START_TIME + 1, si.getLastChangedTimestamp());
7012
7013            // Check the dynamic one.  (locale change shouldn't affect.)
7014            si = getCallerShortcut("s1");
7015
7016            assertEquals("s1", si.getId());
7017            assertEquals("title", si.getTitle());
7018            assertEquals(null, si.getText());
7019            assertEquals(null, si.getDisabledMessage());
7020            assertEquals(START_TIME, si.getLastChangedTimestamp()); // Not changed.
7021        });
7022    }
7023
7024    public void testManifestShortcuts_updateAndDisabled_notPinned() {
7025        mService.handleUnlockUser(USER_0);
7026
7027        // First, just publish a manifest shortcut.
7028        addManifestShortcutResource(
7029                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7030                R.xml.shortcut_1);
7031        updatePackageVersion(CALLING_PACKAGE_1, 1);
7032                mService.mPackageMonitor.onReceive(getTestContext(),
7033                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7034
7035        // Only the valid one is published.
7036        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7037            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7038                    mManager.getManifestShortcuts()))),
7039                    "ms1");
7040            assertEmpty(mManager.getPinnedShortcuts());
7041
7042            // Make sure there's no other dangling shortcuts.
7043            assertShortcutIds(getCallerShortcuts(), "ms1");
7044        });
7045
7046        // Now version up, the manifest shortcut is disabled now.
7047        addManifestShortcutResource(
7048                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7049                R.xml.shortcut_1_disable);
7050        updatePackageVersion(CALLING_PACKAGE_1, 1);
7051                mService.mPackageMonitor.onReceive(getTestContext(),
7052                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7053
7054        // Because shortcut 1 wasn't pinned, it'll just go away.
7055        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7056            assertEmpty(mManager.getManifestShortcuts());
7057            assertEmpty(mManager.getPinnedShortcuts());
7058
7059            // Make sure there's no other dangling shortcuts.
7060            assertEmpty(getCallerShortcuts());
7061        });
7062    }
7063
7064    public void testManifestShortcuts_updateAndDisabled_pinned() {
7065        mService.handleUnlockUser(USER_0);
7066
7067        // First, just publish a manifest shortcut.
7068        addManifestShortcutResource(
7069                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7070                R.xml.shortcut_1);
7071        updatePackageVersion(CALLING_PACKAGE_1, 1);
7072                mService.mPackageMonitor.onReceive(getTestContext(),
7073                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7074
7075        // Only the valid one is published.
7076        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7077            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7078                    mManager.getManifestShortcuts()))),
7079                    "ms1");
7080            assertEmpty(mManager.getPinnedShortcuts());
7081
7082            // Make sure there's no other dangling shortcuts.
7083            assertShortcutIds(getCallerShortcuts(), "ms1");
7084        });
7085
7086        runWithCaller(LAUNCHER_1, USER_0, () -> {
7087            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_0);
7088        });
7089
7090        // Now upgrade, the manifest shortcut is disabled now.
7091        addManifestShortcutResource(
7092                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7093                R.xml.shortcut_1_disable);
7094        updatePackageVersion(CALLING_PACKAGE_1, 1);
7095                mService.mPackageMonitor.onReceive(getTestContext(),
7096                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7097
7098        // Because shortcut 1 was pinned, it'll still exist as pinned, but disabled.
7099        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7100            assertEmpty(mManager.getManifestShortcuts());
7101            assertShortcutIds(assertAllNotManifest(assertAllImmutable(assertAllDisabled(
7102                    mManager.getPinnedShortcuts()))),
7103                    "ms1");
7104
7105            // Make sure the fields are updated.
7106            ShortcutInfo si = getCallerShortcut("ms1");
7107
7108            assertEquals("ms1", si.getId());
7109            assertEquals(R.drawable.icon2, si.getIconResourceId());
7110            assertEquals(R.string.shortcut_title2, si.getTitleResId());
7111            assertEquals(R.string.shortcut_text2, si.getTextResId());
7112            assertEquals(R.string.shortcut_disabled_message2, si.getDisabledMessageResourceId());
7113            assertEquals(Intent.ACTION_VIEW, si.getIntent().getAction());
7114
7115            // Make sure there's no other dangling shortcuts.
7116            assertShortcutIds(getCallerShortcuts(), "ms1");
7117        });
7118    }
7119
7120    public void testManifestShortcuts_duplicateInSingleActivity() {
7121        mService.handleUnlockUser(USER_0);
7122
7123        // The XML has two shortcuts with the same ID.
7124        addManifestShortcutResource(
7125                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7126                R.xml.shortcut_2_duplicate);
7127        updatePackageVersion(CALLING_PACKAGE_1, 1);
7128                mService.mPackageMonitor.onReceive(getTestContext(),
7129                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7130
7131        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7132            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7133                    mManager.getManifestShortcuts()))),
7134                    "ms1");
7135
7136            // Make sure the first one has survived.  (the second one has a different title.)
7137            ShortcutInfo si = getCallerShortcut("ms1");
7138            assertEquals(R.string.shortcut_title1, si.getTitleResId());
7139
7140            // Make sure there's no other dangling shortcuts.
7141            assertShortcutIds(getCallerShortcuts(), "ms1");
7142        });
7143    }
7144
7145    public void testManifestShortcuts_duplicateInTwoActivities() {
7146        mService.handleUnlockUser(USER_0);
7147
7148        // ShortcutActivity has shortcut ms1
7149        addManifestShortcutResource(
7150                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7151                R.xml.shortcut_1);
7152
7153        // ShortcutActivity2 has two shortcuts, ms1 and ms2.
7154        addManifestShortcutResource(
7155                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
7156                R.xml.shortcut_5);
7157        updatePackageVersion(CALLING_PACKAGE_1, 1);
7158                mService.mPackageMonitor.onReceive(getTestContext(),
7159                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7160
7161        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7162            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
7163                    mManager.getManifestShortcuts()))),
7164                    "ms1", "ms2", "ms3", "ms4", "ms5");
7165
7166            // ms1 should belong to ShortcutActivity.
7167            ShortcutInfo si = getCallerShortcut("ms1");
7168            assertEquals(R.string.shortcut_title1, si.getTitleResId());
7169            assertEquals(new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7170                    si.getActivity());
7171            assertEquals(0, si.getRank());
7172
7173            // ms2 should belong to ShortcutActivity*2*.
7174            si = getCallerShortcut("ms2");
7175            assertEquals(R.string.shortcut_title2, si.getTitleResId());
7176            assertEquals(new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
7177                    si.getActivity());
7178
7179            // Also check the ranks
7180            assertWith(getCallerShortcuts()).selectManifest()
7181                    .selectByActivity(
7182                            new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()))
7183                    .haveRanksInOrder("ms1");
7184            assertWith(getCallerShortcuts()).selectManifest()
7185                    .selectByActivity(
7186                            new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()))
7187                    .haveRanksInOrder("ms2", "ms3", "ms4", "ms5");
7188
7189            // Make sure there's no other dangling shortcuts.
7190            assertShortcutIds(getCallerShortcuts(), "ms1", "ms2", "ms3", "ms4", "ms5");
7191        });
7192    }
7193
7194    /**
7195     * Manifest shortcuts cannot override shortcuts that were published via the APIs.
7196     */
7197    public void testManifestShortcuts_cannotOverrideNonManifest() {
7198        mService.handleUnlockUser(USER_0);
7199
7200        // Create a non-pinned dynamic shortcut and a non-dynamic pinned shortcut.
7201
7202        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7203            mManager.setDynamicShortcuts(list(
7204                    makeShortcut("ms1", "title1",
7205                            new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7206                    /* icon */ null, new Intent("action1"), /* rank */ 0),
7207                    makeShortcut("ms2", "title2",
7208                            new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7209                    /* icon */ null, new Intent("action1"), /* rank */ 0)));
7210        });
7211
7212        runWithCaller(LAUNCHER_1, USER_0, () -> {
7213            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_0);
7214        });
7215
7216        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7217            mManager.removeDynamicShortcuts(list("ms2"));
7218
7219            assertShortcutIds(mManager.getDynamicShortcuts(), "ms1");
7220            assertShortcutIds(mManager.getPinnedShortcuts(), "ms2");
7221            assertEmpty(mManager.getManifestShortcuts());
7222        });
7223
7224        // Then update the app with 5 manifest shortcuts.
7225        // Make sure "ms1" and "ms2" won't be replaced.
7226        addManifestShortcutResource(
7227                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7228                R.xml.shortcut_5);
7229        updatePackageVersion(CALLING_PACKAGE_1, 1);
7230                mService.mPackageMonitor.onReceive(getTestContext(),
7231                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7232
7233        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7234            assertShortcutIds(assertAllNotManifest(mManager.getDynamicShortcuts()), "ms1");
7235            assertShortcutIds(assertAllNotManifest(mManager.getPinnedShortcuts()), "ms2");
7236            assertShortcutIds(assertAllManifest(mManager.getManifestShortcuts()),
7237                    "ms3", "ms4", "ms5");
7238
7239            // ms1 and ms2 shouold keep the original title.
7240            ShortcutInfo si = getCallerShortcut("ms1");
7241            assertEquals("title1", si.getTitle());
7242
7243            si = getCallerShortcut("ms2");
7244            assertEquals("title2", si.getTitle());
7245        });
7246    }
7247
7248    protected void checkManifestShortcuts_immutable_verify() {
7249        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7250            assertShortcutIds(assertAllNotManifest(assertAllEnabled(
7251                    mManager.getDynamicShortcuts())),
7252                    "s1");
7253            assertShortcutIds(assertAllManifest(assertAllEnabled(
7254                    mManager.getManifestShortcuts())),
7255                    "ms1");
7256            assertShortcutIds(assertAllNotManifest(assertAllDisabled(
7257                    mManager.getPinnedShortcuts())),
7258                    "ms2");
7259
7260            assertEquals("t1", getCallerShortcut("s1").getTitle());
7261
7262            // Make sure there are no other shortcuts.
7263            assertShortcutIds(getCallerShortcuts(), "s1", "ms1", "ms2");
7264        });
7265    }
7266
7267    /**
7268     * Make sure the APIs won't work on manifest shortcuts.
7269     */
7270    public void testManifestShortcuts_immutable() {
7271        mService.handleUnlockUser(USER_0);
7272
7273        // Create a non-pinned manifest shortcut, a pinned shortcut that was originally
7274        // a manifest shortcut, as well as a dynamic shortcut.
7275
7276        addManifestShortcutResource(
7277                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7278                R.xml.shortcut_2);
7279        updatePackageVersion(CALLING_PACKAGE_1, 1);
7280                mService.mPackageMonitor.onReceive(getTestContext(),
7281                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7282
7283        runWithCaller(LAUNCHER_1, USER_0, () -> {
7284            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_0);
7285        });
7286
7287        addManifestShortcutResource(
7288                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7289                R.xml.shortcut_1);
7290        updatePackageVersion(CALLING_PACKAGE_1, 1);
7291                mService.mPackageMonitor.onReceive(getTestContext(),
7292                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7293
7294        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7295            mManager.addDynamicShortcuts(list(makeShortcutWithTitle("s1", "t1")));
7296        });
7297
7298        checkManifestShortcuts_immutable_verify();
7299
7300        // Note that even though the first argument is not immutable and only the second one
7301        // is immutable, the first argument should not be executed either.
7302
7303        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7304            assertCannotUpdateImmutable(() -> {
7305                mManager.setDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms1")));
7306            });
7307            assertCannotUpdateImmutable(() -> {
7308                mManager.setDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms2")));
7309            });
7310        });
7311        checkManifestShortcuts_immutable_verify();
7312
7313        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7314            assertCannotUpdateImmutable(() -> {
7315                mManager.addDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms1")));
7316            });
7317            assertCannotUpdateImmutable(() -> {
7318                mManager.addDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms2")));
7319            });
7320        });
7321        checkManifestShortcuts_immutable_verify();
7322
7323
7324        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7325            assertCannotUpdateImmutable(() -> {
7326                mManager.updateShortcuts(list(makeShortcut("s1"), makeShortcut("ms1")));
7327            });
7328            assertCannotUpdateImmutable(() -> {
7329                mManager.updateShortcuts(list(makeShortcut("s1"), makeShortcut("ms2")));
7330            });
7331        });
7332        checkManifestShortcuts_immutable_verify();
7333
7334        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7335            assertCannotUpdateImmutable(() -> {
7336                mManager.removeDynamicShortcuts(list("s1", "ms1"));
7337            });
7338            assertCannotUpdateImmutable(() -> {
7339                mManager.removeDynamicShortcuts(list("s2", "ms2"));
7340            });
7341        });
7342        checkManifestShortcuts_immutable_verify();
7343
7344        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7345            assertCannotUpdateImmutable(() -> {
7346                mManager.disableShortcuts(list("s1", "ms1"));
7347            });
7348        });
7349        checkManifestShortcuts_immutable_verify();
7350
7351        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7352            assertCannotUpdateImmutable(() -> {
7353                mManager.enableShortcuts(list("s1", "ms2"));
7354            });
7355        });
7356        checkManifestShortcuts_immutable_verify();
7357    }
7358
7359
7360    /**
7361     * Make sure the APIs won't work on manifest shortcuts.
7362     */
7363    public void testManifestShortcuts_tooMany() {
7364        // Change the max number of shortcuts.
7365        mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
7366
7367        mService.handleUnlockUser(USER_0);
7368
7369        addManifestShortcutResource(
7370                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7371                R.xml.shortcut_5);
7372        updatePackageVersion(CALLING_PACKAGE_1, 1);
7373                mService.mPackageMonitor.onReceive(getTestContext(),
7374                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7375
7376        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7377            // Only the first 3 should be published.
7378            assertShortcutIds(mManager.getManifestShortcuts(), "ms1", "ms2", "ms3");
7379        });
7380    }
7381
7382    public void testMaxShortcutCount_set() {
7383        // Change the max number of shortcuts.
7384        mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
7385
7386        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7387            final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
7388            final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
7389            final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
7390            final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
7391            final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
7392            final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
7393            final ShortcutInfo s1_5 = makeShortcutWithActivity("s15", a1);
7394            final ShortcutInfo s1_6 = makeShortcutWithActivity("s16", a1);
7395            final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
7396            final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
7397            final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
7398            final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
7399
7400            // 3 shortcuts for 2 activities -> okay
7401            mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
7402            assertShortcutIds(mManager.getDynamicShortcuts(),
7403                    "s11", "s12", "s13", "s21", "s22", "s23");
7404
7405            mManager.removeAllDynamicShortcuts();
7406
7407            // 4 shortcut for activity 1 -> too many.
7408            assertDynamicShortcutCountExceeded(() -> {
7409                mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s1_4, s2_1, s2_2, s2_3));
7410            });
7411            assertEmpty(mManager.getDynamicShortcuts());
7412
7413            // 4 shortcut for activity 2 -> too many.
7414            assertDynamicShortcutCountExceeded(() -> {
7415                mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3, s2_4));
7416            });
7417            assertEmpty(mManager.getDynamicShortcuts());
7418
7419            // First, set 3.  Then set 4, which should be ignored.
7420            mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
7421            assertShortcutIds(mManager.getDynamicShortcuts(),
7422                    "s11", "s12", "s13");
7423            assertDynamicShortcutCountExceeded(() -> {
7424                mManager.setDynamicShortcuts(list(s2_1, s2_2, s2_3, s2_4));
7425            });
7426            assertShortcutIds(mManager.getDynamicShortcuts(),
7427                    "s11", "s12", "s13");
7428
7429            // Set will remove the old dynamic set, unlike add, so the following should pass.
7430            mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
7431            assertShortcutIds(mManager.getDynamicShortcuts(),
7432                    "s11", "s12", "s13");
7433            mManager.setDynamicShortcuts(list(s1_4, s1_5, s1_6));
7434            assertShortcutIds(mManager.getDynamicShortcuts(),
7435                    "s14", "s15", "s16");
7436
7437            // Now, test with 2 manifest shortcuts.
7438            mManager.removeAllDynamicShortcuts();
7439            addManifestShortcutResource(
7440                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7441                    R.xml.shortcut_2);
7442            updatePackageVersion(CALLING_PACKAGE_1, 1);
7443                    mService.mPackageMonitor.onReceive(getTestContext(),
7444                    genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7445            assertEquals(2, mManager.getManifestShortcuts().size());
7446
7447            // Setting 1 to activity 1 will work.
7448            mManager.setDynamicShortcuts(list(s1_1, s2_1, s2_2, s2_3));
7449            assertShortcutIds(mManager.getDynamicShortcuts(),
7450                    "s11", "s21", "s22", "s23");
7451            assertEquals(2, mManager.getManifestShortcuts().size());
7452
7453            // But setting 2 will not.
7454            mManager.removeAllDynamicShortcuts();
7455            assertDynamicShortcutCountExceeded(() -> {
7456                mManager.setDynamicShortcuts(list(s1_1, s1_2, s2_1, s2_2, s2_3));
7457            });
7458            assertEmpty(mManager.getDynamicShortcuts());
7459            assertEquals(2, mManager.getManifestShortcuts().size());
7460        });
7461    }
7462
7463    public void testMaxShortcutCount_add() {
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 s2_1 = makeShortcutWithActivity("s21", a2);
7475            final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
7476            final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
7477            final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
7478
7479            // 3 shortcuts for 2 activities -> okay
7480            mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
7481            assertShortcutIds(mManager.getDynamicShortcuts(),
7482                    "s11", "s12", "s13", "s21", "s22", "s23");
7483
7484            mManager.removeAllDynamicShortcuts();
7485
7486            // 4 shortcut for activity 1 -> too many.
7487            assertDynamicShortcutCountExceeded(() -> {
7488                mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s1_4, s2_1, s2_2, s2_3));
7489            });
7490            assertEmpty(mManager.getDynamicShortcuts());
7491
7492            // 4 shortcut for activity 2 -> too many.
7493            assertDynamicShortcutCountExceeded(() -> {
7494                mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3, s2_4));
7495            });
7496            assertEmpty(mManager.getDynamicShortcuts());
7497
7498            // First, set 3.  Then add 1 more, which should be ignored.
7499            mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
7500            assertShortcutIds(mManager.getDynamicShortcuts(),
7501                    "s11", "s12", "s13");
7502            assertDynamicShortcutCountExceeded(() -> {
7503                mManager.addDynamicShortcuts(list(s1_4, s2_1));
7504            });
7505            assertShortcutIds(mManager.getDynamicShortcuts(),
7506                    "s11", "s12", "s13");
7507
7508            // Update existing one, which should work.
7509            mManager.addDynamicShortcuts(list(makeShortcutWithActivityAndTitle(
7510                    "s11", a1, "xxx"), s2_1));
7511            assertShortcutIds(mManager.getDynamicShortcuts(),
7512                    "s11", "s12", "s13", "s21");
7513            assertEquals("xxx", getCallerShortcut("s11").getTitle());
7514
7515            // Make sure pinned shortcuts won't affect.
7516            // - Pin s11 - s13, and remove all dynamic.
7517            runWithCaller(LAUNCHER_1, USER_0, () -> {
7518                mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
7519                        HANDLE_USER_0);
7520            });
7521            mManager.removeAllDynamicShortcuts();
7522
7523            assertEmpty(mManager.getDynamicShortcuts());
7524            assertShortcutIds(mManager.getPinnedShortcuts(),
7525                    "s11", "s12", "s13");
7526
7527            // Then add dynamic.
7528            mManager.addDynamicShortcuts(list(s1_4, s2_1, s2_2, s2_3));
7529
7530            assertShortcutIds(mManager.getDynamicShortcuts(),
7531                    "s14", "s21", "s22", "s23");
7532            assertShortcutIds(mManager.getPinnedShortcuts(),
7533                    "s11", "s12", "s13");
7534
7535            // Adding "s11" and "s12" back, should work
7536            mManager.addDynamicShortcuts(list(s1_1, s1_2));
7537
7538            assertShortcutIds(mManager.getDynamicShortcuts(),
7539                    "s14", "s11", "s12", "s21", "s22", "s23");
7540            assertShortcutIds(mManager.getPinnedShortcuts(),
7541                    "s11", "s12", "s13");
7542
7543            // Adding back s13 doesn't work.
7544            assertDynamicShortcutCountExceeded(() -> {
7545                mManager.addDynamicShortcuts(list(s1_3));
7546            });
7547
7548            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
7549                    "s11", "s12", "s14");
7550            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
7551                    "s21", "s22", "s23");
7552
7553            // Now swap the activities.
7554            mManager.updateShortcuts(list(
7555                    makeShortcutWithActivity("s11", a2),
7556                    makeShortcutWithActivity("s21", a1)));
7557
7558            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
7559                    "s21", "s12", "s14");
7560            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
7561                    "s11", "s22", "s23");
7562
7563            // Now, test with 2 manifest shortcuts.
7564            mManager.removeAllDynamicShortcuts();
7565            addManifestShortcutResource(
7566                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7567                    R.xml.shortcut_2);
7568            updatePackageVersion(CALLING_PACKAGE_1, 1);
7569                    mService.mPackageMonitor.onReceive(getTestContext(),
7570                    genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7571
7572            assertEquals(2, mManager.getManifestShortcuts().size());
7573
7574            // Adding one shortcut to activity 1 works fine.
7575            mManager.addDynamicShortcuts(list(s1_1, s2_1, s2_2, s2_3));
7576            assertShortcutIds(mManager.getDynamicShortcuts(),
7577                    "s11", "s21", "s22", "s23");
7578            assertEquals(2, mManager.getManifestShortcuts().size());
7579
7580            // But adding one more doesn't.
7581            assertDynamicShortcutCountExceeded(() -> {
7582                mManager.addDynamicShortcuts(list(s1_4, s2_1));
7583            });
7584            assertShortcutIds(mManager.getDynamicShortcuts(),
7585                    "s11", "s21", "s22", "s23");
7586            assertEquals(2, mManager.getManifestShortcuts().size());
7587        });
7588    }
7589
7590    public void testMaxShortcutCount_update() {
7591        // Change the max number of shortcuts.
7592        mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
7593
7594        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7595            final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
7596            final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
7597            final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
7598            final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
7599            final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
7600            final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
7601            final ShortcutInfo s1_5 = makeShortcutWithActivity("s15", a1);
7602            final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
7603            final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
7604            final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
7605            final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
7606
7607            // 3 shortcuts for 2 activities -> okay
7608            mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
7609            assertShortcutIds(mManager.getDynamicShortcuts(),
7610                    "s11", "s12", "s13", "s21", "s22", "s23");
7611
7612            // Trying to move s11 from a1 to a2 should fail.
7613            assertDynamicShortcutCountExceeded(() -> {
7614                mManager.updateShortcuts(list(makeShortcutWithActivity("s11", a2)));
7615            });
7616            assertShortcutIds(mManager.getDynamicShortcuts(),
7617                    "s11", "s12", "s13", "s21", "s22", "s23");
7618
7619            // Trying to move s21 from a2 to a1 should also fail.
7620            assertDynamicShortcutCountExceeded(() -> {
7621                mManager.updateShortcuts(list(makeShortcutWithActivity("s21", a1)));
7622            });
7623            assertShortcutIds(mManager.getDynamicShortcuts(),
7624                    "s11", "s12", "s13", "s21", "s22", "s23");
7625
7626            // But, if we do these two at the same time, it should work.
7627            mManager.updateShortcuts(list(
7628                    makeShortcutWithActivity("s11", a2),
7629                    makeShortcutWithActivity("s21", a1)));
7630            assertShortcutIds(mManager.getDynamicShortcuts(),
7631                    "s11", "s12", "s13", "s21", "s22", "s23");
7632            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
7633                    "s21", "s12", "s13");
7634            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
7635                    "s11", "s22", "s23");
7636
7637            // Then reset.
7638            mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
7639            assertShortcutIds(mManager.getDynamicShortcuts(),
7640                    "s11", "s12", "s13", "s21", "s22", "s23");
7641
7642            // Pin some to have more shortcuts for a1.
7643            runWithCaller(LAUNCHER_1, USER_0, () -> {
7644                mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
7645                        HANDLE_USER_0);
7646            });
7647            mManager.setDynamicShortcuts(list(s1_4, s1_5, s2_1, s2_2, s2_3));
7648            assertShortcutIds(mManager.getDynamicShortcuts(),
7649                    "s14", "s15", "s21", "s22", "s23");
7650            assertShortcutIds(mManager.getPinnedShortcuts(),
7651                    "s11", "s12", "s13");
7652
7653            // a1 already has 2 dynamic shortcuts (and 3 pinned shortcuts that used to belong on it)
7654            // But that doesn't matter for update -- the following should still work.
7655            mManager.updateShortcuts(list(
7656                    makeShortcutWithActivityAndTitle("s11", a1, "xxx1"),
7657                    makeShortcutWithActivityAndTitle("s12", a1, "xxx2"),
7658                    makeShortcutWithActivityAndTitle("s13", a1, "xxx3"),
7659                    makeShortcutWithActivityAndTitle("s14", a1, "xxx4"),
7660                    makeShortcutWithActivityAndTitle("s15", a1, "xxx5")));
7661            // All the shortcuts should still exist they all belong on same activities,
7662            // with the updated titles.
7663            assertShortcutIds(mManager.getDynamicShortcuts(),
7664                    "s14", "s15", "s21", "s22", "s23");
7665            assertShortcutIds(mManager.getPinnedShortcuts(),
7666                    "s11", "s12", "s13");
7667
7668            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
7669                    "s14", "s15");
7670            assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
7671                    "s21", "s22", "s23");
7672
7673            assertEquals("xxx1", getCallerShortcut("s11").getTitle());
7674            assertEquals("xxx2", getCallerShortcut("s12").getTitle());
7675            assertEquals("xxx3", getCallerShortcut("s13").getTitle());
7676            assertEquals("xxx4", getCallerShortcut("s14").getTitle());
7677            assertEquals("xxx5", getCallerShortcut("s15").getTitle());
7678        });
7679    }
7680
7681    public void testShortcutsPushedOutByManifest() {
7682        // Change the max number of shortcuts.
7683        mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
7684
7685        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7686            final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
7687            final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
7688            final ShortcutInfo s1_1 = makeShortcutWithActivityAndRank("s11", a1, 4);
7689            final ShortcutInfo s1_2 = makeShortcutWithActivityAndRank("s12", a1, 3);
7690            final ShortcutInfo s1_3 = makeShortcutWithActivityAndRank("s13", a1, 2);
7691            final ShortcutInfo s1_4 = makeShortcutWithActivityAndRank("s14", a1, 1);
7692            final ShortcutInfo s1_5 = makeShortcutWithActivityAndRank("s15", a1, 0);
7693            final ShortcutInfo s2_1 = makeShortcutWithActivityAndRank("s21", a2, 0);
7694            final ShortcutInfo s2_2 = makeShortcutWithActivityAndRank("s22", a2, 1);
7695            final ShortcutInfo s2_3 = makeShortcutWithActivityAndRank("s23", a2, 2);
7696            final ShortcutInfo s2_4 = makeShortcutWithActivityAndRank("s24", a2, 3);
7697            final ShortcutInfo s2_5 = makeShortcutWithActivityAndRank("s25", a2, 4);
7698
7699            // Initial state.
7700            mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
7701            runWithCaller(LAUNCHER_1, USER_0, () -> {
7702                mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s21", "s22"),
7703                        HANDLE_USER_0);
7704            });
7705            mManager.setDynamicShortcuts(list(s1_2, s1_3, s1_4, s2_2, s2_3, s2_4));
7706            assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
7707                    "s12", "s13", "s14",
7708                    "s22", "s23", "s24");
7709            assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
7710                    "s11", "s12",
7711                    "s21", "s22");
7712
7713            // Add 1 manifest shortcut to a1.
7714            addManifestShortcutResource(
7715                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7716                    R.xml.shortcut_1);
7717            updatePackageVersion(CALLING_PACKAGE_1, 1);
7718                    mService.mPackageMonitor.onReceive(getTestContext(),
7719                    genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7720            assertEquals(1, mManager.getManifestShortcuts().size());
7721
7722            // s12 removed.
7723            assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
7724                    "s13", "s14",
7725                    "s22", "s23", "s24");
7726            assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
7727                    "s11", "s12",
7728                    "s21", "s22");
7729
7730            // Add more manifest shortcuts.
7731            addManifestShortcutResource(
7732                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7733                    R.xml.shortcut_2);
7734            addManifestShortcutResource(
7735                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
7736                    R.xml.shortcut_1_alt);
7737            updatePackageVersion(CALLING_PACKAGE_1, 1);
7738                    mService.mPackageMonitor.onReceive(getTestContext(),
7739                    genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7740            assertEquals(3, mManager.getManifestShortcuts().size());
7741
7742            // Note the ones with the highest rank values (== least important) will be removed.
7743            assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
7744                    "s14",
7745                    "s22", "s23");
7746            assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
7747                    "s11", "s12",
7748                    "s21", "s22");
7749
7750            // Add more manifest shortcuts.
7751            addManifestShortcutResource(
7752                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7753                    R.xml.shortcut_2);
7754            addManifestShortcutResource(
7755                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
7756                    R.xml.shortcut_5_alt); // manifest has 5, but max is 3, so a2 will have 3.
7757            updatePackageVersion(CALLING_PACKAGE_1, 1);
7758                    mService.mPackageMonitor.onReceive(getTestContext(),
7759                    genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7760            assertEquals(5, mManager.getManifestShortcuts().size());
7761
7762            assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
7763                    "s14" // a1 has 1 dynamic
7764            ); // a2 has no dynamic
7765            assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
7766                    "s11", "s12",
7767                    "s21", "s22");
7768
7769            // Update, no manifest shortucts.  This doesn't affect anything.
7770            addManifestShortcutResource(
7771                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7772                    R.xml.shortcut_0);
7773            addManifestShortcutResource(
7774                    new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
7775                    R.xml.shortcut_0);
7776            updatePackageVersion(CALLING_PACKAGE_1, 1);
7777                    mService.mPackageMonitor.onReceive(getTestContext(),
7778                    genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7779            assertEquals(0, mManager.getManifestShortcuts().size());
7780
7781            assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
7782                    "s14");
7783            assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
7784                    "s11", "s12",
7785                    "s21", "s22");
7786        });
7787    }
7788
7789    public void testReturnedByServer() {
7790        // Package 1 updated, with manifest shortcuts.
7791        addManifestShortcutResource(
7792                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
7793                R.xml.shortcut_1);
7794        updatePackageVersion(CALLING_PACKAGE_1, 1);
7795        mService.mPackageMonitor.onReceive(getTestContext(),
7796                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
7797
7798        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7799            assertWith(mManager.getManifestShortcuts())
7800                    .haveIds("ms1")
7801                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
7802
7803            assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
7804
7805            assertWith(mManager.getDynamicShortcuts())
7806                    .haveIds("s1")
7807                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
7808        });
7809
7810        // Pin them.
7811        runWithCaller(LAUNCHER_1, USER_0, () -> {
7812            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
7813                    list("ms1", "s1"), getCallingUser());
7814            assertWith(getShortcutAsLauncher(USER_0))
7815                    .haveIds("ms1", "s1")
7816                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
7817        });
7818
7819        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7820            assertWith(mManager.getPinnedShortcuts())
7821                    .haveIds("ms1", "s1")
7822                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
7823        });
7824
7825        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
7826            // This shows a warning log, but should still work.
7827            assertTrue(mManager.setDynamicShortcuts(mManager.getDynamicShortcuts()));
7828
7829            assertWith(mManager.getDynamicShortcuts())
7830                    .haveIds("s1")
7831                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
7832        });
7833    }
7834}
7835