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