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