ShortcutManagerTest2.java revision b5a012fd6f088629746057a3902b5926f9fe8e08
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.assertBundlesEqual;
19import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
20import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
21import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
22import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makeBundle;
23import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.parceled;
24import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
25
26import static org.mockito.Matchers.anyInt;
27import static org.mockito.Matchers.anyString;
28import static org.mockito.Matchers.eq;
29import static org.mockito.Mockito.reset;
30import static org.mockito.Mockito.times;
31import static org.mockito.Mockito.verify;
32
33import android.Manifest.permission;
34import android.app.ActivityManager;
35import android.content.ComponentName;
36import android.content.Intent;
37import android.content.pm.ShortcutInfo;
38import android.content.res.Resources;
39import android.graphics.BitmapFactory;
40import android.graphics.drawable.Icon;
41import android.net.Uri;
42import android.os.PersistableBundle;
43import android.os.UserHandle;
44import android.test.MoreAsserts;
45import android.test.suitebuilder.annotation.SmallTest;
46
47import com.android.frameworks.servicestests.R;
48import com.android.server.pm.ShortcutService.ConfigConstants;
49
50/**
51 * Tests for ShortcutService and ShortcutManager.
52 *
53 m FrameworksServicesTests &&
54 adb install \
55 -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
56 adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 \
57 -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
58 */
59@SmallTest
60public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
61    // ShortcutInfo tests
62
63    public void testShortcutInfoMissingMandatoryFields() {
64        // Disable throttling.
65        mService.updateConfigurationLocked(
66                ShortcutService.ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
67                + ShortcutService.ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
68        );
69
70        assertExpectException(
71                IllegalArgumentException.class,
72                "ID must be provided",
73                () -> new ShortcutInfo.Builder(getTestContext()).build());
74
75        assertExpectException(NullPointerException.class, "Intent action must be set",
76                () -> new ShortcutInfo.Builder(getTestContext()).setIntent(new Intent()));
77
78        assertExpectException(NullPointerException.class, "Activity must be provided", () -> {
79            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext()).setId("id").build();
80            assertTrue(getManager().setDynamicShortcuts(list(si)));
81        });
82
83        assertExpectException(
84                IllegalArgumentException.class, "Short label must be provided", () -> {
85            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext())
86                    .setId("id")
87                    .setActivity(new ComponentName(getTestContext().getPackageName(), "s"))
88                    .build();
89            assertTrue(getManager().setDynamicShortcuts(list(si)));
90        });
91
92        assertExpectException(
93                IllegalArgumentException.class, "Short label must be provided", () -> {
94            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext())
95                    .setId("id")
96                    .setActivity(new ComponentName(getTestContext().getPackageName(), "s"))
97                    .build();
98            assertTrue(getManager().addDynamicShortcuts(list(si)));
99        });
100
101        assertExpectException(NullPointerException.class, "Intent must be provided", () -> {
102            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext())
103                    .setId("id")
104                    .setActivity(new ComponentName(getTestContext().getPackageName(), "s"))
105                    .setShortLabel("x")
106                    .build();
107            assertTrue(getManager().setDynamicShortcuts(list(si)));
108        });
109
110        assertExpectException(NullPointerException.class, "Intent must be provided", () -> {
111            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext())
112                    .setId("id")
113                    .setActivity(new ComponentName(getTestContext().getPackageName(), "s"))
114                    .setShortLabel("x")
115                    .build();
116            assertTrue(getManager().addDynamicShortcuts(list(si)));
117        });
118
119        assertExpectException(
120                IllegalStateException.class, "package name mismatch", () -> {
121            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext())
122                    .setId("id")
123                    .setActivity(new ComponentName("xxx", "s"))
124                    .build();
125            assertTrue(getManager().setDynamicShortcuts(list(si)));
126        });
127
128        assertExpectException(
129                IllegalStateException.class, "package name mismatch", () -> {
130            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext())
131                    .setId("id")
132                    .setActivity(new ComponentName("xxx", "s"))
133                    .build();
134            assertTrue(getManager().addDynamicShortcuts(list(si)));
135        });
136    }
137
138    public void testShortcutInfoParcel() {
139        setCaller(CALLING_PACKAGE_1, USER_10);
140        ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext)
141                .setId("id")
142                .setTitle("title")
143                .setIntent(makeIntent("action", ShortcutActivity.class))
144                .build());
145        assertEquals(mClientContext.getPackageName(), si.getPackage());
146        assertEquals(USER_10, si.getUserId());
147        assertEquals(HANDLE_USER_10, si.getUserHandle());
148        assertEquals("id", si.getId());
149        assertEquals("title", si.getTitle());
150        assertEquals("action", si.getIntent().getAction());
151
152        PersistableBundle pb = new PersistableBundle();
153        pb.putInt("k", 1);
154
155        si = new ShortcutInfo.Builder(getTestContext())
156                .setId("id")
157                .setActivity(new ComponentName("a", "b"))
158                .setIcon(Icon.createWithResource(mClientContext, 123))
159                .setTitle("title")
160                .setText("text")
161                .setDisabledMessage("dismes")
162                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
163                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
164                .setRank(123)
165                .setExtras(pb)
166                .build();
167        si.addFlags(ShortcutInfo.FLAG_PINNED);
168        si.setBitmapPath("abc");
169        si.setIconResourceId(456);
170
171        si = parceled(si);
172
173        assertEquals(getTestContext().getPackageName(), si.getPackage());
174        assertEquals("id", si.getId());
175        assertEquals(new ComponentName("a", "b"), si.getActivity());
176        assertEquals(123, si.getIcon().getResId());
177        assertEquals("title", si.getTitle());
178        assertEquals("text", si.getText());
179        assertEquals("dismes", si.getDisabledMessage());
180        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
181        assertEquals("action", si.getIntent().getAction());
182        assertEquals("val", si.getIntent().getStringExtra("key"));
183        assertEquals(123, si.getRank());
184        assertEquals(1, si.getExtras().getInt("k"));
185
186        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
187        assertEquals("abc", si.getBitmapPath());
188        assertEquals(456, si.getIconResourceId());
189
190        assertEquals(0, si.getTitleResId());
191        assertEquals(null, si.getTitleResName());
192        assertEquals(0, si.getTextResId());
193        assertEquals(null, si.getTextResName());
194        assertEquals(0, si.getDisabledMessageResourceId());
195        assertEquals(null, si.getDisabledMessageResName());
196    }
197
198    public void testShortcutInfoParcel_resId() {
199        setCaller(CALLING_PACKAGE_1, USER_10);
200        ShortcutInfo si;
201
202        PersistableBundle pb = new PersistableBundle();
203        pb.putInt("k", 1);
204
205        si = new ShortcutInfo.Builder(getTestContext())
206                .setId("id")
207                .setActivity(new ComponentName("a", "b"))
208                .setIcon(Icon.createWithResource(mClientContext, 123))
209                .setTitleResId(10)
210                .setTextResId(11)
211                .setDisabledMessageResId(12)
212                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
213                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
214                .setRank(123)
215                .setExtras(pb)
216                .build();
217        si.addFlags(ShortcutInfo.FLAG_PINNED);
218        si.setBitmapPath("abc");
219        si.setIconResourceId(456);
220
221        lookupAndFillInResourceNames(si);
222
223        si = parceled(si);
224
225        assertEquals(getTestContext().getPackageName(), si.getPackage());
226        assertEquals("id", si.getId());
227        assertEquals(new ComponentName("a", "b"), si.getActivity());
228        assertEquals(123, si.getIcon().getResId());
229        assertEquals(10, si.getTitleResId());
230        assertEquals("r10", si.getTitleResName());
231        assertEquals(11, si.getTextResId());
232        assertEquals("r11", si.getTextResName());
233        assertEquals(12, si.getDisabledMessageResourceId());
234        assertEquals("r12", si.getDisabledMessageResName());
235        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
236        assertEquals("action", si.getIntent().getAction());
237        assertEquals("val", si.getIntent().getStringExtra("key"));
238        assertEquals(123, si.getRank());
239        assertEquals(1, si.getExtras().getInt("k"));
240
241        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
242        assertEquals("abc", si.getBitmapPath());
243        assertEquals(456, si.getIconResourceId());
244        assertEquals("string/r456", si.getIconResName());
245    }
246
247    public void testShortcutInfoClone() {
248        setCaller(CALLING_PACKAGE_1, USER_11);
249
250        PersistableBundle pb = new PersistableBundle();
251        pb.putInt("k", 1);
252        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
253                .setId("id")
254                .setActivity(new ComponentName("a", "b"))
255                .setIcon(Icon.createWithResource(mClientContext, 123))
256                .setTitle("title")
257                .setText("text")
258                .setDisabledMessage("dismes")
259                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
260                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
261                .setRank(123)
262                .setExtras(pb)
263                .build();
264        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
265        sorig.setBitmapPath("abc");
266        sorig.setIconResourceId(456);
267
268        lookupAndFillInResourceNames(sorig);
269
270        ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
271
272        assertEquals(USER_11, si.getUserId());
273        assertEquals(HANDLE_USER_11, si.getUserHandle());
274        assertEquals(mClientContext.getPackageName(), si.getPackage());
275        assertEquals("id", si.getId());
276        assertEquals(new ComponentName("a", "b"), si.getActivity());
277        assertEquals(123, si.getIcon().getResId());
278        assertEquals("title", si.getTitle());
279        assertEquals("text", si.getText());
280        assertEquals("dismes", si.getDisabledMessage());
281        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
282        assertEquals("action", si.getIntent().getAction());
283        assertEquals("val", si.getIntent().getStringExtra("key"));
284        assertEquals(123, si.getRank());
285        assertEquals(1, si.getExtras().getInt("k"));
286
287        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
288        assertEquals("abc", si.getBitmapPath());
289        assertEquals(456, si.getIconResourceId());
290        assertEquals("string/r456", si.getIconResName());
291
292        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
293
294        assertEquals(mClientContext.getPackageName(), si.getPackage());
295        assertEquals("id", si.getId());
296        assertEquals(new ComponentName("a", "b"), si.getActivity());
297        assertEquals(null, si.getIcon());
298        assertEquals("title", si.getTitle());
299        assertEquals("text", si.getText());
300        assertEquals("dismes", si.getDisabledMessage());
301        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
302        assertEquals("action", si.getIntent().getAction());
303        assertEquals("val", si.getIntent().getStringExtra("key"));
304        assertEquals(123, si.getRank());
305        assertEquals(1, si.getExtras().getInt("k"));
306
307        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
308        assertEquals(null, si.getBitmapPath());
309
310        assertEquals(456, si.getIconResourceId());
311        assertEquals(null, si.getIconResName());
312
313        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
314
315        assertEquals(mClientContext.getPackageName(), si.getPackage());
316        assertEquals("id", si.getId());
317        assertEquals(new ComponentName("a", "b"), si.getActivity());
318        assertEquals(null, si.getIcon());
319        assertEquals("title", si.getTitle());
320        assertEquals("text", si.getText());
321        assertEquals("dismes", si.getDisabledMessage());
322        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
323        assertEquals(null, si.getIntent());
324        assertEquals(123, si.getRank());
325        assertEquals(1, si.getExtras().getInt("k"));
326
327        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
328        assertEquals(null, si.getBitmapPath());
329
330        assertEquals(456, si.getIconResourceId());
331        assertEquals(null, si.getIconResName());
332
333        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
334
335        assertEquals(mClientContext.getPackageName(), si.getPackage());
336        assertEquals("id", si.getId());
337        assertEquals(new ComponentName("a", "b"), si.getActivity());
338        assertEquals(null, si.getIcon());
339        assertEquals(null, si.getTitle());
340        assertEquals(null, si.getText());
341        assertEquals(null, si.getDisabledMessage());
342        assertEquals(null, si.getCategories());
343        assertEquals(null, si.getIntent());
344        assertEquals(0, si.getRank());
345        assertEquals(null, si.getExtras());
346
347        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
348        assertEquals(null, si.getBitmapPath());
349
350        assertEquals(456, si.getIconResourceId());
351        assertEquals(null, si.getIconResName());
352    }
353
354    public void testShortcutInfoClone_resId() {
355        setCaller(CALLING_PACKAGE_1, USER_11);
356
357        PersistableBundle pb = new PersistableBundle();
358        pb.putInt("k", 1);
359        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
360                .setId("id")
361                .setActivity(new ComponentName("a", "b"))
362                .setIcon(Icon.createWithResource(mClientContext, 123))
363                .setTitleResId(10)
364                .setTextResId(11)
365                .setDisabledMessageResId(12)
366                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
367                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
368                .setRank(123)
369                .setExtras(pb)
370                .build();
371        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
372        sorig.setBitmapPath("abc");
373        sorig.setIconResourceId(456);
374
375        lookupAndFillInResourceNames(sorig);
376
377        ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
378
379        assertEquals(USER_11, si.getUserId());
380        assertEquals(HANDLE_USER_11, si.getUserHandle());
381        assertEquals(mClientContext.getPackageName(), si.getPackage());
382        assertEquals("id", si.getId());
383        assertEquals(new ComponentName("a", "b"), si.getActivity());
384        assertEquals(123, si.getIcon().getResId());
385        assertEquals(10, si.getTitleResId());
386        assertEquals("r10", si.getTitleResName());
387        assertEquals(11, si.getTextResId());
388        assertEquals("r11", si.getTextResName());
389        assertEquals(12, si.getDisabledMessageResourceId());
390        assertEquals("r12", si.getDisabledMessageResName());
391        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
392        assertEquals("action", si.getIntent().getAction());
393        assertEquals("val", si.getIntent().getStringExtra("key"));
394        assertEquals(123, si.getRank());
395        assertEquals(1, si.getExtras().getInt("k"));
396
397        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
398        assertEquals("abc", si.getBitmapPath());
399        assertEquals(456, si.getIconResourceId());
400        assertEquals("string/r456", si.getIconResName());
401
402        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
403
404        assertEquals(mClientContext.getPackageName(), si.getPackage());
405        assertEquals("id", si.getId());
406        assertEquals(new ComponentName("a", "b"), si.getActivity());
407        assertEquals(null, si.getIcon());
408        assertEquals(10, si.getTitleResId());
409        assertEquals(null, si.getTitleResName());
410        assertEquals(11, si.getTextResId());
411        assertEquals(null, si.getTextResName());
412        assertEquals(12, si.getDisabledMessageResourceId());
413        assertEquals(null, si.getDisabledMessageResName());
414        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
415        assertEquals("action", si.getIntent().getAction());
416        assertEquals("val", si.getIntent().getStringExtra("key"));
417        assertEquals(123, si.getRank());
418        assertEquals(1, si.getExtras().getInt("k"));
419
420        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
421        assertEquals(null, si.getBitmapPath());
422
423        assertEquals(456, si.getIconResourceId());
424        assertEquals(null, si.getIconResName());
425
426        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
427
428        assertEquals(mClientContext.getPackageName(), si.getPackage());
429        assertEquals("id", si.getId());
430        assertEquals(new ComponentName("a", "b"), si.getActivity());
431        assertEquals(null, si.getIcon());
432        assertEquals(10, si.getTitleResId());
433        assertEquals(null, si.getTitleResName());
434        assertEquals(11, si.getTextResId());
435        assertEquals(null, si.getTextResName());
436        assertEquals(12, si.getDisabledMessageResourceId());
437        assertEquals(null, si.getDisabledMessageResName());
438        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
439        assertEquals(null, si.getIntent());
440        assertEquals(123, si.getRank());
441        assertEquals(1, si.getExtras().getInt("k"));
442
443        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
444        assertEquals(null, si.getBitmapPath());
445
446        assertEquals(456, si.getIconResourceId());
447        assertEquals(null, si.getIconResName());
448
449        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
450
451        assertEquals(mClientContext.getPackageName(), si.getPackage());
452        assertEquals("id", si.getId());
453        assertEquals(new ComponentName("a", "b"), si.getActivity());
454        assertEquals(null, si.getIcon());
455        assertEquals(0, si.getTitleResId());
456        assertEquals(null, si.getTitleResName());
457        assertEquals(0, si.getTextResId());
458        assertEquals(null, si.getTextResName());
459        assertEquals(0, si.getDisabledMessageResourceId());
460        assertEquals(null, si.getDisabledMessageResName());
461        assertEquals(null, si.getCategories());
462        assertEquals(null, si.getIntent());
463        assertEquals(0, si.getRank());
464        assertEquals(null, si.getExtras());
465
466        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
467        assertEquals(null, si.getBitmapPath());
468
469        assertEquals(456, si.getIconResourceId());
470        assertEquals(null, si.getIconResName());
471    }
472
473    public void testShortcutInfoClone_minimum() {
474        PersistableBundle pb = new PersistableBundle();
475        pb.putInt("k", 1);
476        ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
477                .setId("id")
478                .setTitle("title")
479                .setIntent(makeIntent("action", ShortcutActivity.class))
480                .build();
481        ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
482
483        assertEquals(getTestContext().getPackageName(), si.getPackage());
484        assertEquals("id", si.getId());
485        assertEquals("title", si.getTitle());
486        assertEquals("action", si.getIntent().getAction());
487        assertEquals(null, si.getCategories());
488
489        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
490
491        assertEquals(getTestContext().getPackageName(), si.getPackage());
492        assertEquals("id", si.getId());
493        assertEquals("title", si.getTitle());
494        assertEquals("action", si.getIntent().getAction());
495        assertEquals(null, si.getCategories());
496
497        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
498
499        assertEquals(getTestContext().getPackageName(), si.getPackage());
500        assertEquals("id", si.getId());
501        assertEquals("title", si.getTitle());
502        assertEquals(null, si.getIntent());
503        assertEquals(null, si.getCategories());
504
505        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
506
507        assertEquals(getTestContext().getPackageName(), si.getPackage());
508        assertEquals("id", si.getId());
509        assertEquals(null, si.getTitle());
510        assertEquals(null, si.getIntent());
511        assertEquals(null, si.getCategories());
512    }
513
514    public void testShortcutInfoCopyNonNullFieldsFrom() throws InterruptedException {
515        PersistableBundle pb = new PersistableBundle();
516        pb.putInt("k", 1);
517        ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
518                .setId("id")
519                .setActivity(new ComponentName("a", "b"))
520                .setIcon(Icon.createWithResource(mClientContext, 123))
521                .setTitle("title")
522                .setText("text")
523                .setDisabledMessage("dismes")
524                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
525                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
526                .setRank(123)
527                .setExtras(pb)
528                .build();
529        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
530        sorig.setBitmapPath("abc");
531        sorig.setIconResourceId(456);
532
533        lookupAndFillInResourceNames(sorig);
534
535        ShortcutInfo si;
536
537        si = sorig.clone(/* flags=*/ 0);
538        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
539                .setActivity(new ComponentName("x", "y")).build());
540        assertEquals("text", si.getText());
541        assertEquals(123, si.getRank());
542        assertEquals(new ComponentName("x", "y"), si.getActivity());
543
544        si = sorig.clone(/* flags=*/ 0);
545        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
546                .setIcon(Icon.createWithResource(mClientContext, 456)).build());
547        assertEquals("text", si.getText());
548        assertEquals(456, si.getIcon().getResId());
549        assertEquals(0, si.getIconResourceId());
550        assertEquals(null, si.getIconResName());
551        assertEquals(null, si.getBitmapPath());
552
553        si = sorig.clone(/* flags=*/ 0);
554        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
555                .setTitle("xyz").build());
556        assertEquals("text", si.getText());
557        assertEquals("xyz", si.getTitle());
558        assertEquals(0, si.getTitleResId());
559
560        si = sorig.clone(/* flags=*/ 0);
561        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
562                .setTitleResId(123).build());
563        assertEquals("text", si.getText());
564        assertEquals(null, si.getTitle());
565        assertEquals(123, si.getTitleResId());
566
567        si = sorig.clone(/* flags=*/ 0);
568        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
569                .setText("xxx").build());
570        assertEquals(123, si.getRank());
571        assertEquals("xxx", si.getText());
572        assertEquals(0, si.getTextResId());
573
574        si = sorig.clone(/* flags=*/ 0);
575        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
576                .setTextResId(1111).build());
577        assertEquals(123, si.getRank());
578        assertEquals(null, si.getText());
579        assertEquals(1111, si.getTextResId());
580
581        si = sorig.clone(/* flags=*/ 0);
582        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
583                .setDisabledMessage("xxx").build());
584        assertEquals(123, si.getRank());
585        assertEquals("xxx", si.getDisabledMessage());
586        assertEquals(0, si.getDisabledMessageResourceId());
587
588        si = sorig.clone(/* flags=*/ 0);
589        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
590                .setDisabledMessageResId(11111).build());
591        assertEquals(123, si.getRank());
592        assertEquals(null, si.getDisabledMessage());
593        assertEquals(11111, si.getDisabledMessageResourceId());
594
595        si = sorig.clone(/* flags=*/ 0);
596        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
597                .setCategories(set()).build());
598        assertEquals("text", si.getText());
599        assertEquals(set(), si.getCategories());
600
601        si = sorig.clone(/* flags=*/ 0);
602        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
603                .setCategories(set("x")).build());
604        assertEquals("text", si.getText());
605        assertEquals(set("x"), si.getCategories());
606
607        si = sorig.clone(/* flags=*/ 0);
608        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
609                .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
610        assertEquals("text", si.getText());
611        assertEquals("action2", si.getIntent().getAction());
612        assertEquals(null, si.getIntent().getStringExtra("key"));
613
614        si = sorig.clone(/* flags=*/ 0);
615        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
616                .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
617        assertEquals("text", si.getText());
618        assertEquals("action3", si.getIntent().getAction());
619        assertEquals("x", si.getIntent().getStringExtra("key"));
620
621        si = sorig.clone(/* flags=*/ 0);
622        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
623                .setRank(999).build());
624        assertEquals("text", si.getText());
625        assertEquals(999, si.getRank());
626
627
628        PersistableBundle pb2 = new PersistableBundle();
629        pb2.putInt("x", 99);
630
631        si = sorig.clone(/* flags=*/ 0);
632        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
633                .setExtras(pb2).build());
634        assertEquals("text", si.getText());
635        assertEquals(99, si.getExtras().getInt("x"));
636    }
637
638    public void testShortcutInfoCopyNonNullFieldsFrom_resId() throws InterruptedException {
639        PersistableBundle pb = new PersistableBundle();
640        pb.putInt("k", 1);
641        ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
642                .setId("id")
643                .setActivity(new ComponentName("a", "b"))
644                .setIcon(Icon.createWithResource(mClientContext, 123))
645                .setTitleResId(10)
646                .setTextResId(11)
647                .setDisabledMessageResId(12)
648                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
649                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
650                .setRank(123)
651                .setExtras(pb)
652                .build();
653        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
654        sorig.setBitmapPath("abc");
655        sorig.setIconResourceId(456);
656
657        ShortcutInfo si;
658
659        si = sorig.clone(/* flags=*/ 0);
660        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
661                .setActivity(new ComponentName("x", "y")).build());
662        assertEquals(11, si.getTextResId());
663        assertEquals(new ComponentName("x", "y"), si.getActivity());
664
665        si = sorig.clone(/* flags=*/ 0);
666        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
667                .setIcon(Icon.createWithResource(mClientContext, 456)).build());
668        assertEquals(11, si.getTextResId());
669        assertEquals(456, si.getIcon().getResId());
670        assertEquals(0, si.getIconResourceId());
671        assertEquals(null, si.getIconResName());
672        assertEquals(null, si.getBitmapPath());
673
674        si = sorig.clone(/* flags=*/ 0);
675        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
676                .setTitle("xyz").build());
677        assertEquals(11, si.getTextResId());
678        assertEquals("xyz", si.getTitle());
679        assertEquals(0, si.getTitleResId());
680        assertEquals(null, si.getTitleResName());
681
682        si = sorig.clone(/* flags=*/ 0);
683        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
684                .setTitleResId(123).build());
685        assertEquals(11, si.getTextResId());
686        assertEquals(null, si.getTitle());
687        assertEquals(123, si.getTitleResId());
688        assertEquals(null, si.getTitleResName());
689
690        si = sorig.clone(/* flags=*/ 0);
691        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
692                .setText("xxx").build());
693        assertEquals(123, si.getRank());
694        assertEquals("xxx", si.getText());
695        assertEquals(0, si.getTextResId());
696        assertEquals(null, si.getTextResName());
697
698        si = sorig.clone(/* flags=*/ 0);
699        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
700                .setTextResId(1111).build());
701        assertEquals(123, si.getRank());
702        assertEquals(null, si.getText());
703        assertEquals(1111, si.getTextResId());
704        assertEquals(null, si.getTextResName());
705
706        si = sorig.clone(/* flags=*/ 0);
707        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
708                .setDisabledMessage("xxx").build());
709        assertEquals(123, si.getRank());
710        assertEquals("xxx", si.getDisabledMessage());
711        assertEquals(0, si.getDisabledMessageResourceId());
712        assertEquals(null, si.getDisabledMessageResName());
713
714        si = sorig.clone(/* flags=*/ 0);
715        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
716                .setDisabledMessageResId(11111).build());
717        assertEquals(123, si.getRank());
718        assertEquals(null, si.getDisabledMessage());
719        assertEquals(11111, si.getDisabledMessageResourceId());
720        assertEquals(null, si.getDisabledMessageResName());
721
722        si = sorig.clone(/* flags=*/ 0);
723        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
724                .setCategories(set()).build());
725        assertEquals(11, si.getTextResId());
726        assertEquals(set(), si.getCategories());
727
728        si = sorig.clone(/* flags=*/ 0);
729        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
730                .setCategories(set("x")).build());
731        assertEquals(11, si.getTextResId());
732        assertEquals(set("x"), si.getCategories());
733
734        si = sorig.clone(/* flags=*/ 0);
735        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
736                .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
737        assertEquals(11, si.getTextResId());
738        assertEquals("action2", si.getIntent().getAction());
739        assertEquals(null, si.getIntent().getStringExtra("key"));
740
741        si = sorig.clone(/* flags=*/ 0);
742        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
743                .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
744        assertEquals(11, si.getTextResId());
745        assertEquals("action3", si.getIntent().getAction());
746        assertEquals("x", si.getIntent().getStringExtra("key"));
747
748        si = sorig.clone(/* flags=*/ 0);
749        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
750                .setRank(999).build());
751        assertEquals(11, si.getTextResId());
752        assertEquals(999, si.getRank());
753
754
755        PersistableBundle pb2 = new PersistableBundle();
756        pb2.putInt("x", 99);
757
758        si = sorig.clone(/* flags=*/ 0);
759        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
760                .setExtras(pb2).build());
761        assertEquals(11, si.getTextResId());
762        assertEquals(99, si.getExtras().getInt("x"));
763    }
764
765    public void testShortcutInfoSaveAndLoad() throws InterruptedException {
766        setCaller(CALLING_PACKAGE_1, USER_10);
767
768        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
769                getTestContext().getResources(), R.drawable.black_32x32));
770
771        PersistableBundle pb = new PersistableBundle();
772        pb.putInt("k", 1);
773        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
774                .setId("id")
775                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
776                .setIcon(bmp32x32)
777                .setTitle("title")
778                .setText("text")
779                .setDisabledMessage("dismes")
780                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
781                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
782                .setRank(123)
783                .setExtras(pb)
784                .build();
785        sorig.setTimestamp(mInjectedCurrentTimeMillis);
786
787        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
788                .setId("id2")
789                .setTitle("x")
790                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
791                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
792                .setRank(456)
793                .build();
794        sorig2.setTimestamp(mInjectedCurrentTimeMillis);
795
796        mManager.addDynamicShortcuts(list(sorig, sorig2));
797
798        mInjectedCurrentTimeMillis += 1;
799        final long now = mInjectedCurrentTimeMillis;
800        mInjectedCurrentTimeMillis += 1;
801
802        // Save and load.
803        mService.saveDirtyInfo();
804        initService();
805        mService.handleUnlockUser(USER_10);
806
807        ShortcutInfo si;
808        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
809
810        assertEquals(USER_10, si.getUserId());
811        assertEquals(HANDLE_USER_10, si.getUserHandle());
812        assertEquals(CALLING_PACKAGE_1, si.getPackage());
813        assertEquals("id", si.getId());
814        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
815        assertEquals(null, si.getIcon());
816        assertEquals("title", si.getTitle());
817        assertEquals("text", si.getText());
818        assertEquals("dismes", si.getDisabledMessage());
819        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
820        assertEquals("action", si.getIntent().getAction());
821        assertEquals("val", si.getIntent().getStringExtra("key"));
822        assertEquals(0, si.getRank());
823        assertEquals(1, si.getExtras().getInt("k"));
824
825        assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE
826                | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
827        assertNotNull(si.getBitmapPath()); // Something should be set.
828        assertEquals(0, si.getIconResourceId());
829        assertTrue(si.getLastChangedTimestamp() < now);
830
831        // Make sure ranks are saved too.  Because of the auto-adjusting, we need two shortcuts
832        // to test it.
833        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
834        assertEquals(1, si.getRank());
835    }
836
837    public void testShortcutInfoSaveAndLoad_resId() throws InterruptedException {
838        setCaller(CALLING_PACKAGE_1, USER_10);
839
840        final Icon res32x32 = Icon.createWithResource(mClientContext, R.drawable.black_32x32);
841
842        PersistableBundle pb = new PersistableBundle();
843        pb.putInt("k", 1);
844        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
845                .setId("id")
846                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
847                .setIcon(res32x32)
848                .setTitleResId(10)
849                .setTextResId(11)
850                .setDisabledMessageResId(12)
851                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
852                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
853                .setRank(123)
854                .setExtras(pb)
855                .build();
856        sorig.setTimestamp(mInjectedCurrentTimeMillis);
857
858        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
859                .setId("id2")
860                .setTitle("x")
861                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
862                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
863                .setRank(456)
864                .build();
865        sorig2.setTimestamp(mInjectedCurrentTimeMillis);
866
867        mManager.addDynamicShortcuts(list(sorig, sorig2));
868
869        mInjectedCurrentTimeMillis += 1;
870        final long now = mInjectedCurrentTimeMillis;
871        mInjectedCurrentTimeMillis += 1;
872
873        // Save and load.
874        mService.saveDirtyInfo();
875        initService();
876        mService.handleUnlockUser(USER_10);
877
878        ShortcutInfo si;
879        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
880
881        assertEquals(USER_10, si.getUserId());
882        assertEquals(HANDLE_USER_10, si.getUserHandle());
883        assertEquals(CALLING_PACKAGE_1, si.getPackage());
884        assertEquals("id", si.getId());
885        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
886        assertEquals(null, si.getIcon());
887        assertEquals(10, si.getTitleResId());
888        assertEquals("r10", si.getTitleResName());
889        assertEquals(11, si.getTextResId());
890        assertEquals("r11", si.getTextResName());
891        assertEquals(12, si.getDisabledMessageResourceId());
892        assertEquals("r12", si.getDisabledMessageResName());
893        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
894        assertEquals("action", si.getIntent().getAction());
895        assertEquals("val", si.getIntent().getStringExtra("key"));
896        assertEquals(0, si.getRank());
897        assertEquals(1, si.getExtras().getInt("k"));
898
899        assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_RES
900                | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
901        assertNull(si.getBitmapPath());
902        assertEquals(R.drawable.black_32x32, si.getIconResourceId());
903        assertTrue(si.getLastChangedTimestamp() < now);
904
905        // Make sure ranks are saved too.  Because of the auto-adjusting, we need two shortcuts
906        // to test it.
907        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
908        assertEquals(1, si.getRank());
909    }
910
911    public void testShortcutInfoSaveAndLoad_forBackup() {
912        setCaller(CALLING_PACKAGE_1, USER_0);
913
914        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
915                getTestContext().getResources(), R.drawable.black_32x32));
916
917        PersistableBundle pb = new PersistableBundle();
918        pb.putInt("k", 1);
919        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
920                .setId("id")
921                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
922                .setIcon(bmp32x32)
923                .setTitle("title")
924                .setText("text")
925                .setDisabledMessage("dismes")
926                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
927                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
928                .setRank(123)
929                .setExtras(pb)
930                .build();
931
932        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
933                .setId("id2")
934                .setTitle("x")
935                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
936                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
937                .setRank(456)
938                .build();
939
940        mManager.addDynamicShortcuts(list(sorig, sorig2));
941
942        // Dynamic shortcuts won't be backed up, so we need to pin it.
943        setCaller(LAUNCHER_1, USER_0);
944        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
945
946        // Do backup & restore.
947        backupAndRestore();
948
949        mService.handleUnlockUser(USER_0); // Load user-0.
950
951        ShortcutInfo si;
952        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
953
954        assertEquals(CALLING_PACKAGE_1, si.getPackage());
955        assertEquals("id", si.getId());
956        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
957        assertEquals(null, si.getIcon());
958        assertEquals("title", si.getTitle());
959        assertEquals("text", si.getText());
960        assertEquals("dismes", si.getDisabledMessage());
961        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
962        assertEquals("action", si.getIntent().getAction());
963        assertEquals("val", si.getIntent().getStringExtra("key"));
964        assertEquals(0, si.getRank());
965        assertEquals(1, si.getExtras().getInt("k"));
966
967        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
968        assertNull(si.getBitmapPath()); // No icon.
969        assertEquals(0, si.getIconResourceId());
970
971        // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
972        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
973        assertEquals(0, si.getRank());
974    }
975
976    public void testShortcutInfoSaveAndLoad_forBackup_resId() {
977        setCaller(CALLING_PACKAGE_1, USER_0);
978
979        final Icon res32x32 = Icon.createWithResource(mClientContext, R.drawable.black_32x32);
980
981        PersistableBundle pb = new PersistableBundle();
982        pb.putInt("k", 1);
983        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
984                .setId("id")
985                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
986                .setIcon(res32x32)
987                .setTitleResId(10)
988                .setTextResId(11)
989                .setDisabledMessageResId(12)
990                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
991                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
992                .setRank(123)
993                .setExtras(pb)
994                .build();
995
996        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
997                .setId("id2")
998                .setTitle("x")
999                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
1000                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
1001                .setRank(456)
1002                .build();
1003
1004        mManager.addDynamicShortcuts(list(sorig, sorig2));
1005
1006        // Dynamic shortcuts won't be backed up, so we need to pin it.
1007        setCaller(LAUNCHER_1, USER_0);
1008        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
1009
1010        // Do backup & restore.
1011        backupAndRestore();
1012
1013        mService.handleUnlockUser(USER_0); // Load user-0.
1014
1015        ShortcutInfo si;
1016        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
1017
1018        assertEquals(CALLING_PACKAGE_1, si.getPackage());
1019        assertEquals("id", si.getId());
1020        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
1021        assertEquals(null, si.getIcon());
1022        assertEquals(10, si.getTitleResId());
1023        assertEquals("r10", si.getTitleResName());
1024        assertEquals(11, si.getTextResId());
1025        assertEquals("r11", si.getTextResName());
1026        assertEquals(12, si.getDisabledMessageResourceId());
1027        assertEquals("r12", si.getDisabledMessageResName());
1028        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
1029        assertEquals("action", si.getIntent().getAction());
1030        assertEquals("val", si.getIntent().getStringExtra("key"));
1031        assertEquals(0, si.getRank());
1032        assertEquals(1, si.getExtras().getInt("k"));
1033
1034        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
1035        assertNull(si.getBitmapPath()); // No icon.
1036        assertEquals(0, si.getIconResourceId());
1037        assertEquals(null, si.getIconResName());
1038
1039        // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
1040        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
1041        assertEquals(0, si.getRank());
1042    }
1043
1044    private void checkShortcutInfoSaveAndLoad_intents(Intent intent) {
1045        assertTrue(mManager.setDynamicShortcuts(list(
1046                makeShortcutWithIntent("s1", intent))));
1047        initService();
1048        mService.handleUnlockUser(USER_0);
1049
1050        assertWith(getCallerShortcuts())
1051                .haveIds("s1")
1052                .forShortcutWithId("s1", si -> {
1053                    assertEquals(intent.getAction(), si.getIntent().getAction());
1054                    assertEquals(intent.getData(), si.getIntent().getData());
1055                    assertEquals(intent.getComponent(), si.getIntent().getComponent());
1056                    assertBundlesEqual(intent.getExtras(), si.getExtras());
1057                });
1058    }
1059
1060    public void testShortcutInfoSaveAndLoad_intents() {
1061        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW));
1062
1063        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1064
1065        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN));
1066
1067        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1068
1069        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW,
1070                Uri.parse("http://www.example.com/")));
1071
1072        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1073
1074        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN,
1075                Uri.parse("http://www.example.com/")));
1076
1077        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1078
1079        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW)
1080                .setComponent(new ComponentName("a", "b")));
1081
1082        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1083
1084        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN)
1085                .setComponent(new ComponentName("a", "b")));
1086
1087        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1088
1089        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW)
1090                .putExtras(makeBundle("a", "b")));
1091
1092        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1093
1094
1095        checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN)
1096                .putExtras(makeBundle("a", "b")));
1097
1098        mInjectedCurrentTimeMillis += INTERVAL; // reset throttling.
1099    }
1100
1101    public void testThrottling() {
1102        final ShortcutInfo si1 = makeShortcut("shortcut1");
1103
1104        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1105        assertEquals(2, mManager.getRemainingCallCount());
1106        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1107
1108        mInjectedCurrentTimeMillis++;
1109        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1110        assertEquals(1, mManager.getRemainingCallCount());
1111        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1112
1113        mInjectedCurrentTimeMillis++;
1114        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1115        assertEquals(0, mManager.getRemainingCallCount());
1116        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1117
1118        // Reached the max
1119
1120        mInjectedCurrentTimeMillis++;
1121        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1122        assertEquals(0, mManager.getRemainingCallCount());
1123        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1124
1125        // Still throttled
1126        mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
1127        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1128        assertEquals(0, mManager.getRemainingCallCount());
1129        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1130
1131        // Now it should work.
1132        mInjectedCurrentTimeMillis++;
1133        assertTrue(mManager.setDynamicShortcuts(list(si1))); // fail
1134        assertEquals(2, mManager.getRemainingCallCount());
1135        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
1136
1137        mInjectedCurrentTimeMillis++;
1138        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1139        assertEquals(1, mManager.getRemainingCallCount());
1140        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
1141
1142        mInjectedCurrentTimeMillis++;
1143        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1144        assertEquals(0, mManager.getRemainingCallCount());
1145        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
1146
1147        mInjectedCurrentTimeMillis++;
1148        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1149        assertEquals(0, mManager.getRemainingCallCount());
1150        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
1151
1152        // 4 hours later...
1153        mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL;
1154        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1155        assertEquals(2, mManager.getRemainingCallCount());
1156        assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
1157
1158        mInjectedCurrentTimeMillis++;
1159        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1160        assertEquals(1, mManager.getRemainingCallCount());
1161        assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
1162
1163        // Make sure getRemainingCallCount() itself gets reset without calling setDynamicShortcuts().
1164        mInjectedCurrentTimeMillis = START_TIME + 8 * INTERVAL;
1165        assertEquals(3, mManager.getRemainingCallCount());
1166        assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
1167
1168        mInjectedCurrentTimeMillis++;
1169        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1170        assertEquals(2, mManager.getRemainingCallCount());
1171        assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
1172    }
1173
1174    public void testThrottling_rewind() {
1175        final ShortcutInfo si1 = makeShortcut("shortcut1");
1176
1177        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1178        assertEquals(2, mManager.getRemainingCallCount());
1179        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1180
1181        mInjectedCurrentTimeMillis = 12345; // Clock reset!
1182
1183        // Since the clock looks invalid, the counter shouldn't have reset.
1184        assertEquals(2, mManager.getRemainingCallCount());
1185        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1186
1187        // Forward again.  Still haven't reset yet.
1188        mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
1189        assertEquals(2, mManager.getRemainingCallCount());
1190        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
1191
1192        // Now rewind -- this will reset the counters.
1193        mInjectedCurrentTimeMillis = START_TIME - 100000;
1194        assertEquals(3, mManager.getRemainingCallCount());
1195
1196        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1197        assertEquals(2, mManager.getRemainingCallCount());
1198
1199        // Forward again, should be reset now.
1200        mInjectedCurrentTimeMillis += INTERVAL;
1201        assertEquals(3, mManager.getRemainingCallCount());
1202    }
1203
1204    public void testThrottling_perPackage() {
1205        final ShortcutInfo si1 = makeShortcut("shortcut1");
1206
1207        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1208        assertEquals(2, mManager.getRemainingCallCount());
1209
1210        mInjectedCurrentTimeMillis++;
1211        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1212        assertEquals(1, mManager.getRemainingCallCount());
1213
1214        mInjectedCurrentTimeMillis++;
1215        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1216        assertEquals(0, mManager.getRemainingCallCount());
1217
1218        // Reached the max
1219
1220        mInjectedCurrentTimeMillis++;
1221        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1222
1223        // Try from a different caller.
1224        mInjectedClientPackage = CALLING_PACKAGE_2;
1225        mInjectedCallingUid = CALLING_UID_2;
1226
1227        // Need to create a new one wit the updated package name.
1228        final ShortcutInfo si2 = makeShortcut("shortcut1");
1229
1230        assertEquals(3, mManager.getRemainingCallCount());
1231
1232        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1233        assertEquals(2, mManager.getRemainingCallCount());
1234
1235        mInjectedCurrentTimeMillis++;
1236        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1237        assertEquals(1, mManager.getRemainingCallCount());
1238
1239        // Back to the original caller, still throttled.
1240        mInjectedClientPackage = CALLING_PACKAGE_1;
1241        mInjectedCallingUid = CALLING_UID_1;
1242
1243        mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
1244        assertEquals(0, mManager.getRemainingCallCount());
1245        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1246        assertEquals(0, mManager.getRemainingCallCount());
1247
1248        // Now it should work.
1249        mInjectedCurrentTimeMillis++;
1250        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1251
1252        mInjectedCurrentTimeMillis++;
1253        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1254
1255        mInjectedCurrentTimeMillis++;
1256        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1257
1258        mInjectedCurrentTimeMillis++;
1259        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1260
1261        mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL;
1262        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1263        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1264        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1265        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1266
1267        mInjectedClientPackage = CALLING_PACKAGE_2;
1268        mInjectedCallingUid = CALLING_UID_2;
1269
1270        assertEquals(3, mManager.getRemainingCallCount());
1271
1272        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1273        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1274        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1275        assertFalse(mManager.setDynamicShortcuts(list(si2)));
1276    }
1277
1278    public void testThrottling_localeChanges() {
1279        prepareCrossProfileDataSet();
1280
1281        dumpsysOnLogcat("Before save & load");
1282
1283        mService.saveDirtyInfo();
1284        initService();
1285
1286        final long origSequenceNumber = mService.getLocaleChangeSequenceNumber();
1287
1288        mInternal.onSystemLocaleChangedNoLock();
1289        assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
1290
1291        // Note at this point only user-0 is loaded, and the counters are reset for this user,
1292        // but it will work for other users too, because we persist when
1293
1294        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1295            assertEquals(3, mManager.getRemainingCallCount());
1296        });
1297        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1298            assertEquals(3, mManager.getRemainingCallCount());
1299        });
1300        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1301            assertEquals(3, mManager.getRemainingCallCount());
1302        });
1303        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1304            assertEquals(3, mManager.getRemainingCallCount());
1305        });
1306        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1307            assertEquals(3, mManager.getRemainingCallCount());
1308        });
1309        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1310            assertEquals(3, mManager.getRemainingCallCount());
1311        });
1312
1313        mService.saveDirtyInfo();
1314        initService();
1315
1316        // Make sure the counter is persisted.
1317        assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
1318    }
1319
1320    public void testThrottling_foreground() throws Exception {
1321        prepareCrossProfileDataSet();
1322
1323        dumpsysOnLogcat("Before save & load");
1324
1325        mService.saveDirtyInfo();
1326        initService();
1327
1328        // We need to update the current time from time to time, since some of the internal checks
1329        // rely on the time being correctly incremented.
1330        mInjectedCurrentTimeMillis++;
1331
1332        // First, all packages have less than 3 (== initial value) remaining calls.
1333
1334        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1335            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1336        });
1337        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1338            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1339        });
1340        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1341            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1342        });
1343        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1344            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1345        });
1346        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1347            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1348        });
1349        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1350            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1351        });
1352
1353        mInjectedCurrentTimeMillis++;
1354
1355        // State changed, but not foreground, so no resetting.
1356        mService.mUidObserver.onUidStateChanged(
1357                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1358        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1359            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1360        });
1361        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1362            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1363        });
1364        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1365            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1366        });
1367        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1368            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1369        });
1370        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1371            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1372        });
1373        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1374            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1375        });
1376
1377        mInjectedCurrentTimeMillis++;
1378
1379        // State changed, package1 foreground, reset.
1380        mService.mUidObserver.onUidStateChanged(
1381                CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1382        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1383            assertEquals(3, mManager.getRemainingCallCount());
1384        });
1385        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1386            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1387        });
1388        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1389            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1390        });
1391        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1392            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1393        });
1394        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1395            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1396        });
1397        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1398            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1399        });
1400        mService.mUidObserver.onUidStateChanged(
1401                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1402
1403        mInjectedCurrentTimeMillis++;
1404
1405        // Different app comes to foreground briefly, and goes back to background.
1406        // Now, make sure package 2's counter is reset, even in this case.
1407        mService.mUidObserver.onUidStateChanged(
1408                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1409        mService.mUidObserver.onUidStateChanged(
1410                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1411
1412        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1413            assertEquals(3, mManager.getRemainingCallCount());
1414        });
1415        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1416            assertEquals(3, mManager.getRemainingCallCount());
1417        });
1418        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1419            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1420        });
1421        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1422            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1423        });
1424        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1425            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1426        });
1427        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1428            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1429        });
1430
1431        mInjectedCurrentTimeMillis++;
1432
1433        // Do the same thing one more time.  This would catch the bug with mixuing up
1434        // the current time and the elapsed time.
1435        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1436            mManager.updateShortcuts(list(makeShortcut("s")));
1437            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1438        });
1439
1440        mService.mUidObserver.onUidStateChanged(
1441                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1442        mService.mUidObserver.onUidStateChanged(
1443                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1444
1445        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1446            assertEquals(3, mManager.getRemainingCallCount());
1447        });
1448        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1449            assertEquals(3, mManager.getRemainingCallCount());
1450        });
1451        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1452            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1453        });
1454        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1455            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1456        });
1457        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1458            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1459        });
1460        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1461            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1462        });
1463
1464        mInjectedCurrentTimeMillis++;
1465
1466        // Package 1 on user-10 comes to foreground.
1467        // Now, also try calling some APIs and make sure foreground apps don't get throttled.
1468        mService.mUidObserver.onUidStateChanged(
1469                UserHandle.getUid(USER_10, CALLING_UID_1),
1470                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1471        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1472            assertEquals(3, mManager.getRemainingCallCount());
1473
1474            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1475            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1476            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1477
1478            assertEquals(0, mManager.getRemainingCallCount());
1479        });
1480        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1481            assertEquals(3, mManager.getRemainingCallCount());
1482
1483            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1484            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1485            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1486
1487            assertEquals(0, mManager.getRemainingCallCount());
1488        });
1489        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1490            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1491
1492            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1493            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1494            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1495
1496            assertEquals(0, mManager.getRemainingCallCount());
1497        });
1498        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1499            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1500
1501            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1502            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1503            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1504
1505            assertEquals(0, mManager.getRemainingCallCount());
1506        });
1507        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1508            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1509
1510            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1511            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1512            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1513
1514            assertEquals(0, mManager.getRemainingCallCount());
1515        });
1516        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1517            assertEquals(3, mManager.getRemainingCallCount());
1518
1519            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1520            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1521            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1522
1523            assertEquals(3, mManager.getRemainingCallCount()); // Still 3!
1524        });
1525    }
1526
1527
1528    public void testThrottling_resetByInternalCall() throws Exception {
1529        prepareCrossProfileDataSet();
1530
1531        dumpsysOnLogcat("Before save & load");
1532
1533        mService.saveDirtyInfo();
1534        initService();
1535
1536        // First, all packages have less than 3 (== initial value) remaining calls.
1537
1538        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1539            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1540        });
1541        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1542            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1543        });
1544        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1545            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1546        });
1547        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1548            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1549        });
1550        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1551            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1552        });
1553        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1554            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1555        });
1556
1557        // Simulate a call from sys UI.
1558        mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
1559        mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
1560
1561        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1562            assertEquals(3, mManager.getRemainingCallCount());
1563        });
1564        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1565            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1566        });
1567        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1568            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1569        });
1570        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1571            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1572        });
1573        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1574            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1575        });
1576        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1577            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1578        });
1579
1580        mManager.onApplicationActive(CALLING_PACKAGE_3, USER_0);
1581
1582        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1583            assertEquals(3, mManager.getRemainingCallCount());
1584        });
1585        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1586            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1587        });
1588        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1589            assertEquals(3, mManager.getRemainingCallCount());
1590        });
1591        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1592            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1593        });
1594        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1595            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1596        });
1597        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1598            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1599        });
1600
1601        mManager.onApplicationActive(CALLING_PACKAGE_1, USER_10);
1602
1603        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1604            assertEquals(3, mManager.getRemainingCallCount());
1605        });
1606        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1607            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1608        });
1609        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1610            assertEquals(3, mManager.getRemainingCallCount());
1611        });
1612        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1613            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1614        });
1615        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1616            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1617        });
1618        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1619            assertEquals(3, mManager.getRemainingCallCount());
1620        });
1621    }
1622
1623    public void testReportShortcutUsed() {
1624        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1625            reset(mMockUsageStatsManagerInternal);
1626
1627            // Report with an nonexistent shortcut.
1628            mManager.reportShortcutUsed("s1");
1629            verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
1630                    anyString(), anyString(), anyInt());
1631
1632            // Publish s2, but s1 still doesn't exist.
1633            mManager.setDynamicShortcuts(list(makeShortcut("s2")));
1634            mManager.reportShortcutUsed("s1");
1635            verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
1636                    anyString(), anyString(), anyInt());
1637
1638            mManager.reportShortcutUsed("s2");
1639            verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
1640                    eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_10));
1641
1642        });
1643        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
1644            // Try with a different package.
1645            reset(mMockUsageStatsManagerInternal);
1646
1647            // Report with an nonexistent shortcut.
1648            mManager.reportShortcutUsed("s2");
1649            verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
1650                    anyString(), anyString(), anyInt());
1651
1652            // Publish s2, but s1 still doesn't exist.
1653            mManager.setDynamicShortcuts(list(makeShortcut("s3")));
1654            mManager.reportShortcutUsed("s2");
1655            verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
1656                    anyString(), anyString(), anyInt());
1657
1658            mManager.reportShortcutUsed("s3");
1659            verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
1660                    eq(CALLING_PACKAGE_2), eq("s3"), eq(USER_10));
1661
1662        });
1663    }
1664
1665    // Test for a ShortcutInfo method.
1666    public void testGetResourcePackageName() {
1667        assertEquals(null, ShortcutInfo.getResourcePackageName(""));
1668        assertEquals(null, ShortcutInfo.getResourcePackageName("abc"));
1669        assertEquals("p", ShortcutInfo.getResourcePackageName("p:"));
1670        assertEquals("p", ShortcutInfo.getResourcePackageName("p:xx"));
1671        assertEquals("pac", ShortcutInfo.getResourcePackageName("pac:"));
1672    }
1673
1674    // Test for a ShortcutInfo method.
1675    public void testGetResourceTypeName() {
1676        assertEquals(null, ShortcutInfo.getResourceTypeName(""));
1677        assertEquals(null, ShortcutInfo.getResourceTypeName(":"));
1678        assertEquals(null, ShortcutInfo.getResourceTypeName("/"));
1679        assertEquals(null, ShortcutInfo.getResourceTypeName("/:"));
1680        assertEquals("a", ShortcutInfo.getResourceTypeName(":a/"));
1681        assertEquals("type", ShortcutInfo.getResourceTypeName("xxx:type/yyy"));
1682    }
1683
1684    // Test for a ShortcutInfo method.
1685    public void testGetResourceTypeAndEntryName() {
1686        assertEquals(null, ShortcutInfo.getResourceTypeAndEntryName(""));
1687        assertEquals(null, ShortcutInfo.getResourceTypeAndEntryName("abc"));
1688        assertEquals("", ShortcutInfo.getResourceTypeAndEntryName("p:"));
1689        assertEquals("x", ShortcutInfo.getResourceTypeAndEntryName(":x"));
1690        assertEquals("x", ShortcutInfo.getResourceTypeAndEntryName("p:x"));
1691        assertEquals("xyz", ShortcutInfo.getResourceTypeAndEntryName("pac:xyz"));
1692    }
1693
1694    // Test for a ShortcutInfo method.
1695    public void testGetResourceEntryName() {
1696        assertEquals(null, ShortcutInfo.getResourceEntryName(""));
1697        assertEquals(null, ShortcutInfo.getResourceEntryName("ab:"));
1698        assertEquals("", ShortcutInfo.getResourceEntryName("/"));
1699        assertEquals("abc", ShortcutInfo.getResourceEntryName("/abc"));
1700        assertEquals("abc", ShortcutInfo.getResourceEntryName("xyz/abc"));
1701    }
1702
1703    // Test for a ShortcutInfo method.
1704    public void testLookUpResourceName_systemResources() {
1705        // For android system resources, lookUpResourceName will simply return the value as a
1706        // string, regardless of "withType".
1707        final Resources res = getTestContext().getResources();
1708
1709        assertEquals("" + android.R.string.cancel, ShortcutInfo.lookUpResourceName(res,
1710                android.R.string.cancel, true, getTestContext().getPackageName()));
1711        assertEquals("" + android.R.drawable.alert_dark_frame, ShortcutInfo.lookUpResourceName(res,
1712                android.R.drawable.alert_dark_frame, true, getTestContext().getPackageName()));
1713        assertEquals("" + android.R.string.cancel, ShortcutInfo.lookUpResourceName(res,
1714                android.R.string.cancel, false, getTestContext().getPackageName()));
1715    }
1716
1717    public void testLookUpResourceName_appResources() {
1718        final Resources res = getTestContext().getResources();
1719
1720        assertEquals("shortcut_text1", ShortcutInfo.lookUpResourceName(res,
1721                R.string.shortcut_text1, false, getTestContext().getPackageName()));
1722        assertEquals("string/shortcut_text1", ShortcutInfo.lookUpResourceName(res,
1723                R.string.shortcut_text1, true, getTestContext().getPackageName()));
1724
1725        assertEquals("black_16x64", ShortcutInfo.lookUpResourceName(res,
1726                R.drawable.black_16x64, false, getTestContext().getPackageName()));
1727        assertEquals("drawable/black_16x64", ShortcutInfo.lookUpResourceName(res,
1728                R.drawable.black_16x64, true, getTestContext().getPackageName()));
1729    }
1730
1731    // Test for a ShortcutInfo method.
1732    public void testLookUpResourceId_systemResources() {
1733        final Resources res = getTestContext().getResources();
1734
1735        assertEquals(android.R.string.cancel, ShortcutInfo.lookUpResourceId(res,
1736                "" + android.R.string.cancel, null,
1737                getTestContext().getPackageName()));
1738        assertEquals(android.R.drawable.alert_dark_frame, ShortcutInfo.lookUpResourceId(res,
1739                "" + android.R.drawable.alert_dark_frame, null,
1740                getTestContext().getPackageName()));
1741    }
1742
1743    // Test for a ShortcutInfo method.
1744    public void testLookUpResourceId_appResources() {
1745        final Resources res = getTestContext().getResources();
1746
1747        assertEquals(R.string.shortcut_text1,
1748                ShortcutInfo.lookUpResourceId(res, "shortcut_text1", "string",
1749                        getTestContext().getPackageName()));
1750
1751        assertEquals(R.string.shortcut_text1,
1752                ShortcutInfo.lookUpResourceId(res, "string/shortcut_text1", null,
1753                        getTestContext().getPackageName()));
1754
1755        assertEquals(R.drawable.black_16x64,
1756                ShortcutInfo.lookUpResourceId(res, "black_16x64", "drawable",
1757                        getTestContext().getPackageName()));
1758
1759        assertEquals(R.drawable.black_16x64,
1760                ShortcutInfo.lookUpResourceId(res, "drawable/black_16x64", null,
1761                        getTestContext().getPackageName()));
1762    }
1763}
1764