ShortcutManagerTest2.java revision 51ab2b3fd04e24e0ca98afd1c1832d84f3a9e62c
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.assertExpectException;
19import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
20import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.parceled;
21import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
22
23import android.Manifest.permission;
24import android.app.ActivityManager;
25import android.content.ComponentName;
26import android.content.Intent;
27import android.content.pm.ShortcutInfo;
28import android.graphics.BitmapFactory;
29import android.graphics.drawable.Icon;
30import android.os.PersistableBundle;
31import android.os.UserHandle;
32import android.test.MoreAsserts;
33import android.test.suitebuilder.annotation.SmallTest;
34
35import com.android.frameworks.servicestests.R;
36import com.android.server.SystemService;
37
38/**
39 * Tests for ShortcutService and ShortcutManager.
40 *
41 m FrameworksServicesTests &&
42 adb install \
43 -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
44 adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 \
45 -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
46 */
47@SmallTest
48public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
49    // ShortcutInfo tests
50
51    public void testShortcutInfoMissingMandatoryFields() {
52        assertExpectException(
53                IllegalArgumentException.class,
54                "ID must be provided",
55                () -> new ShortcutInfo.Builder(getTestContext()).build());
56        assertExpectException(
57                NullPointerException.class,
58                "Intent action must be set",
59                () -> new ShortcutInfo.Builder(getTestContext()).setIntent(new Intent()));
60        assertExpectException(
61                NullPointerException.class,
62                "activity must be provided",
63                () -> new ShortcutInfo.Builder(getTestContext()).setId("id").build()
64                        .enforceMandatoryFields());
65        assertExpectException(
66                IllegalArgumentException.class,
67                "title must be provided",
68                () -> new ShortcutInfo.Builder(getTestContext()).setId("id")
69                        .setActivity(
70                                new ComponentName(getTestContext().getPackageName(), "s"))
71                        .build()
72                        .enforceMandatoryFields());
73        assertExpectException(
74                NullPointerException.class,
75                "Intent must be provided",
76                () -> new ShortcutInfo.Builder(getTestContext()).setId("id")
77                        .setActivity(
78                                new ComponentName(getTestContext().getPackageName(), "s"))
79                        .setTitle("x").build()
80                        .enforceMandatoryFields());
81    }
82
83    public void testShortcutInfoParcel() {
84        setCaller(CALLING_PACKAGE_1, USER_10);
85        ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext)
86                .setId("id")
87                .setTitle("title")
88                .setIntent(makeIntent("action", ShortcutActivity.class))
89                .build());
90        assertEquals(mClientContext.getPackageName(), si.getPackage());
91        assertEquals(USER_10, si.getUserId());
92        assertEquals(HANDLE_USER_10, si.getUserHandle());
93        assertEquals("id", si.getId());
94        assertEquals("title", si.getTitle());
95        assertEquals("action", si.getIntent().getAction());
96
97        PersistableBundle pb = new PersistableBundle();
98        pb.putInt("k", 1);
99
100        si = new ShortcutInfo.Builder(getTestContext())
101                .setId("id")
102                .setActivity(new ComponentName("a", "b"))
103                .setIcon(Icon.createWithResource(mClientContext, 123))
104                .setTitle("title")
105                .setText("text")
106                .setDisabledMessage("dismes")
107                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
108                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
109                .setRank(123)
110                .setExtras(pb)
111                .build();
112        si.addFlags(ShortcutInfo.FLAG_PINNED);
113        si.setBitmapPath("abc");
114        si.setIconResourceId(456);
115
116        si = parceled(si);
117
118        assertEquals(getTestContext().getPackageName(), si.getPackage());
119        assertEquals("id", si.getId());
120        assertEquals(new ComponentName("a", "b"), si.getActivity());
121        assertEquals(123, si.getIcon().getResId());
122        assertEquals("title", si.getTitle());
123        assertEquals("text", si.getText());
124        assertEquals("dismes", si.getDisabledMessage());
125        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
126        assertEquals("action", si.getIntent().getAction());
127        assertEquals("val", si.getIntent().getStringExtra("key"));
128        assertEquals(123, si.getRank());
129        assertEquals(1, si.getExtras().getInt("k"));
130
131        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
132        assertEquals("abc", si.getBitmapPath());
133        assertEquals(456, si.getIconResourceId());
134    }
135
136    public void testShortcutInfoParcel_resId() {
137        setCaller(CALLING_PACKAGE_1, USER_10);
138        ShortcutInfo si;
139
140        PersistableBundle pb = new PersistableBundle();
141        pb.putInt("k", 1);
142
143        si = new ShortcutInfo.Builder(getTestContext())
144                .setId("id")
145                .setActivity(new ComponentName("a", "b"))
146                .setIcon(Icon.createWithResource(mClientContext, 123))
147                .setTitleResId(10)
148                .setTextResId(11)
149                .setDisabledMessageResId(12)
150                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
151                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
152                .setRank(123)
153                .setExtras(pb)
154                .build();
155        si.addFlags(ShortcutInfo.FLAG_PINNED);
156        si.setBitmapPath("abc");
157        si.setIconResourceId(456);
158
159        si = parceled(si);
160
161        assertEquals(getTestContext().getPackageName(), si.getPackage());
162        assertEquals("id", si.getId());
163        assertEquals(new ComponentName("a", "b"), si.getActivity());
164        assertEquals(123, si.getIcon().getResId());
165        assertEquals(10, si.getTitleResId());
166        assertEquals(11, si.getTextResId());
167        assertEquals(12, si.getDisabledMessageResourceId());
168        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
169        assertEquals("action", si.getIntent().getAction());
170        assertEquals("val", si.getIntent().getStringExtra("key"));
171        assertEquals(123, si.getRank());
172        assertEquals(1, si.getExtras().getInt("k"));
173
174        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
175        assertEquals("abc", si.getBitmapPath());
176        assertEquals(456, si.getIconResourceId());
177    }
178
179    public void testShortcutInfoClone() {
180        setCaller(CALLING_PACKAGE_1, USER_11);
181
182        PersistableBundle pb = new PersistableBundle();
183        pb.putInt("k", 1);
184        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
185                .setId("id")
186                .setActivity(new ComponentName("a", "b"))
187                .setIcon(Icon.createWithResource(mClientContext, 123))
188                .setTitle("title")
189                .setText("text")
190                .setDisabledMessage("dismes")
191                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
192                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
193                .setRank(123)
194                .setExtras(pb)
195                .build();
196        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
197        sorig.setBitmapPath("abc");
198        sorig.setIconResourceId(456);
199
200        ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
201
202        assertEquals(USER_11, si.getUserId());
203        assertEquals(HANDLE_USER_11, si.getUserHandle());
204        assertEquals(mClientContext.getPackageName(), si.getPackage());
205        assertEquals("id", si.getId());
206        assertEquals(new ComponentName("a", "b"), si.getActivity());
207        assertEquals(123, si.getIcon().getResId());
208        assertEquals("title", si.getTitle());
209        assertEquals("text", si.getText());
210        assertEquals("dismes", si.getDisabledMessage());
211        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
212        assertEquals("action", si.getIntent().getAction());
213        assertEquals("val", si.getIntent().getStringExtra("key"));
214        assertEquals(123, si.getRank());
215        assertEquals(1, si.getExtras().getInt("k"));
216
217        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
218        assertEquals("abc", si.getBitmapPath());
219        assertEquals(456, si.getIconResourceId());
220
221        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
222
223        assertEquals(mClientContext.getPackageName(), si.getPackage());
224        assertEquals("id", si.getId());
225        assertEquals(new ComponentName("a", "b"), si.getActivity());
226        assertEquals(null, si.getIcon());
227        assertEquals("title", si.getTitle());
228        assertEquals("text", si.getText());
229        assertEquals("dismes", si.getDisabledMessage());
230        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
231        assertEquals("action", si.getIntent().getAction());
232        assertEquals("val", si.getIntent().getStringExtra("key"));
233        assertEquals(123, si.getRank());
234        assertEquals(1, si.getExtras().getInt("k"));
235
236        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
237        assertEquals(null, si.getBitmapPath());
238
239        assertEquals(456, si.getIconResourceId());
240
241        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
242
243        assertEquals(mClientContext.getPackageName(), si.getPackage());
244        assertEquals("id", si.getId());
245        assertEquals(new ComponentName("a", "b"), si.getActivity());
246        assertEquals(null, si.getIcon());
247        assertEquals("title", si.getTitle());
248        assertEquals("text", si.getText());
249        assertEquals("dismes", si.getDisabledMessage());
250        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
251        assertEquals(null, si.getIntent());
252        assertEquals(123, si.getRank());
253        assertEquals(1, si.getExtras().getInt("k"));
254
255        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
256        assertEquals(null, si.getBitmapPath());
257
258        assertEquals(456, si.getIconResourceId());
259
260        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
261
262        assertEquals(mClientContext.getPackageName(), si.getPackage());
263        assertEquals("id", si.getId());
264        assertEquals(null, si.getActivity());
265        assertEquals(null, si.getIcon());
266        assertEquals(null, si.getTitle());
267        assertEquals(null, si.getText());
268        assertEquals(null, si.getDisabledMessage());
269        assertEquals(null, si.getCategories());
270        assertEquals(null, si.getIntent());
271        assertEquals(0, si.getRank());
272        assertEquals(null, si.getExtras());
273
274        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
275        assertEquals(null, si.getBitmapPath());
276
277        assertEquals(456, si.getIconResourceId());
278    }
279
280    public void testShortcutInfoClone_resId() {
281        setCaller(CALLING_PACKAGE_1, USER_11);
282
283        PersistableBundle pb = new PersistableBundle();
284        pb.putInt("k", 1);
285        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
286                .setId("id")
287                .setActivity(new ComponentName("a", "b"))
288                .setIcon(Icon.createWithResource(mClientContext, 123))
289                .setTitleResId(10)
290                .setTextResId(11)
291                .setDisabledMessageResId(12)
292                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
293                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
294                .setRank(123)
295                .setExtras(pb)
296                .build();
297        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
298        sorig.setBitmapPath("abc");
299        sorig.setIconResourceId(456);
300
301        ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
302
303        assertEquals(USER_11, si.getUserId());
304        assertEquals(HANDLE_USER_11, si.getUserHandle());
305        assertEquals(mClientContext.getPackageName(), si.getPackage());
306        assertEquals("id", si.getId());
307        assertEquals(new ComponentName("a", "b"), si.getActivity());
308        assertEquals(123, si.getIcon().getResId());
309        assertEquals(10, si.getTitleResId());
310        assertEquals(11, si.getTextResId());
311        assertEquals(12, si.getDisabledMessageResourceId());
312        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
313        assertEquals("action", si.getIntent().getAction());
314        assertEquals("val", si.getIntent().getStringExtra("key"));
315        assertEquals(123, si.getRank());
316        assertEquals(1, si.getExtras().getInt("k"));
317
318        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
319        assertEquals("abc", si.getBitmapPath());
320        assertEquals(456, si.getIconResourceId());
321
322        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
323
324        assertEquals(mClientContext.getPackageName(), si.getPackage());
325        assertEquals("id", si.getId());
326        assertEquals(new ComponentName("a", "b"), si.getActivity());
327        assertEquals(null, si.getIcon());
328        assertEquals(10, si.getTitleResId());
329        assertEquals(11, si.getTextResId());
330        assertEquals(12, si.getDisabledMessageResourceId());
331        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
332        assertEquals("action", si.getIntent().getAction());
333        assertEquals("val", si.getIntent().getStringExtra("key"));
334        assertEquals(123, si.getRank());
335        assertEquals(1, si.getExtras().getInt("k"));
336
337        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
338        assertEquals(null, si.getBitmapPath());
339
340        assertEquals(456, si.getIconResourceId());
341
342        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
343
344        assertEquals(mClientContext.getPackageName(), si.getPackage());
345        assertEquals("id", si.getId());
346        assertEquals(new ComponentName("a", "b"), si.getActivity());
347        assertEquals(null, si.getIcon());
348        assertEquals(10, si.getTitleResId());
349        assertEquals(11, si.getTextResId());
350        assertEquals(12, si.getDisabledMessageResourceId());
351        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
352        assertEquals(null, si.getIntent());
353        assertEquals(123, si.getRank());
354        assertEquals(1, si.getExtras().getInt("k"));
355
356        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
357        assertEquals(null, si.getBitmapPath());
358
359        assertEquals(456, si.getIconResourceId());
360
361        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
362
363        assertEquals(mClientContext.getPackageName(), si.getPackage());
364        assertEquals("id", si.getId());
365        assertEquals(null, si.getActivity());
366        assertEquals(null, si.getIcon());
367        assertEquals(0, si.getTitleResId());
368        assertEquals(0, si.getTextResId());
369        assertEquals(0, si.getDisabledMessageResourceId());
370        assertEquals(null, si.getCategories());
371        assertEquals(null, si.getIntent());
372        assertEquals(0, si.getRank());
373        assertEquals(null, si.getExtras());
374
375        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
376        assertEquals(null, si.getBitmapPath());
377
378        assertEquals(456, si.getIconResourceId());
379    }
380
381    public void testShortcutInfoClone_minimum() {
382        PersistableBundle pb = new PersistableBundle();
383        pb.putInt("k", 1);
384        ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
385                .setId("id")
386                .setTitle("title")
387                .setIntent(makeIntent("action", ShortcutActivity.class))
388                .build();
389        ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
390
391        assertEquals(getTestContext().getPackageName(), si.getPackage());
392        assertEquals("id", si.getId());
393        assertEquals("title", si.getTitle());
394        assertEquals("action", si.getIntent().getAction());
395        assertEquals(null, si.getCategories());
396
397        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
398
399        assertEquals(getTestContext().getPackageName(), si.getPackage());
400        assertEquals("id", si.getId());
401        assertEquals("title", si.getTitle());
402        assertEquals("action", si.getIntent().getAction());
403        assertEquals(null, si.getCategories());
404
405        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
406
407        assertEquals(getTestContext().getPackageName(), si.getPackage());
408        assertEquals("id", si.getId());
409        assertEquals("title", si.getTitle());
410        assertEquals(null, si.getIntent());
411        assertEquals(null, si.getCategories());
412
413        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
414
415        assertEquals(getTestContext().getPackageName(), si.getPackage());
416        assertEquals("id", si.getId());
417        assertEquals(null, si.getTitle());
418        assertEquals(null, si.getIntent());
419        assertEquals(null, si.getCategories());
420    }
421
422    public void testShortcutInfoCopyNonNullFieldsFrom() throws InterruptedException {
423        PersistableBundle pb = new PersistableBundle();
424        pb.putInt("k", 1);
425        ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
426                .setId("id")
427                .setActivity(new ComponentName("a", "b"))
428                .setIcon(Icon.createWithResource(mClientContext, 123))
429                .setTitle("title")
430                .setText("text")
431                .setDisabledMessage("dismes")
432                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
433                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
434                .setRank(123)
435                .setExtras(pb)
436                .build();
437        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
438        sorig.setBitmapPath("abc");
439        sorig.setIconResourceId(456);
440
441        ShortcutInfo si;
442
443        si = sorig.clone(/* flags=*/ 0);
444        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
445                .setActivity(new ComponentName("x", "y")).build());
446        assertEquals("text", si.getText());
447        assertEquals(new ComponentName("x", "y"), si.getActivity());
448
449        si = sorig.clone(/* flags=*/ 0);
450        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
451                .setIcon(Icon.createWithResource(mClientContext, 456)).build());
452        assertEquals("text", si.getText());
453        assertEquals(456, si.getIcon().getResId());
454
455        si = sorig.clone(/* flags=*/ 0);
456        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
457                .setTitle("xyz").build());
458        assertEquals("text", si.getText());
459        assertEquals("xyz", si.getTitle());
460        assertEquals(0, si.getTitleResId());
461
462        si = sorig.clone(/* flags=*/ 0);
463        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
464                .setTitleResId(123).build());
465        assertEquals("text", si.getText());
466        assertEquals(null, si.getTitle());
467        assertEquals(123, si.getTitleResId());
468
469        si = sorig.clone(/* flags=*/ 0);
470        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
471                .setText("xxx").build());
472        assertEquals(123, si.getRank());
473        assertEquals("xxx", si.getText());
474        assertEquals(0, si.getTextResId());
475
476        si = sorig.clone(/* flags=*/ 0);
477        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
478                .setTextResId(1111).build());
479        assertEquals(123, si.getRank());
480        assertEquals(null, si.getText());
481        assertEquals(1111, si.getTextResId());
482
483        si = sorig.clone(/* flags=*/ 0);
484        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
485                .setDisabledMessage("xxx").build());
486        assertEquals(123, si.getRank());
487        assertEquals("xxx", si.getDisabledMessage());
488        assertEquals(0, si.getDisabledMessageResourceId());
489
490        si = sorig.clone(/* flags=*/ 0);
491        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
492                .setDisabledMessageResId(11111).build());
493        assertEquals(123, si.getRank());
494        assertEquals(null, si.getDisabledMessage());
495        assertEquals(11111, si.getDisabledMessageResourceId());
496
497        si = sorig.clone(/* flags=*/ 0);
498        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
499                .setCategories(set()).build());
500        assertEquals("text", si.getText());
501        assertEquals(set(), si.getCategories());
502
503        si = sorig.clone(/* flags=*/ 0);
504        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
505                .setCategories(set("x")).build());
506        assertEquals("text", si.getText());
507        assertEquals(set("x"), si.getCategories());
508
509        si = sorig.clone(/* flags=*/ 0);
510        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
511                .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
512        assertEquals("text", si.getText());
513        assertEquals("action2", si.getIntent().getAction());
514        assertEquals(null, si.getIntent().getStringExtra("key"));
515
516        si = sorig.clone(/* flags=*/ 0);
517        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
518                .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
519        assertEquals("text", si.getText());
520        assertEquals("action3", si.getIntent().getAction());
521        assertEquals("x", si.getIntent().getStringExtra("key"));
522
523        si = sorig.clone(/* flags=*/ 0);
524        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
525                .setRank(999).build());
526        assertEquals("text", si.getText());
527        assertEquals(999, si.getRank());
528
529
530        PersistableBundle pb2 = new PersistableBundle();
531        pb2.putInt("x", 99);
532
533        si = sorig.clone(/* flags=*/ 0);
534        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
535                .setExtras(pb2).build());
536        assertEquals("text", si.getText());
537        assertEquals(99, si.getExtras().getInt("x"));
538
539        // Make sure the timestamp gets updated too.
540
541        final long timestamp = si.getLastChangedTimestamp();
542        Thread.sleep(2);
543
544        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
545                .setTitle("xyz").build());
546
547        assertTrue(si.getLastChangedTimestamp() > timestamp);
548    }
549
550    public void testShortcutInfoCopyNonNullFieldsFrom_resId() throws InterruptedException {
551        PersistableBundle pb = new PersistableBundle();
552        pb.putInt("k", 1);
553        ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
554                .setId("id")
555                .setActivity(new ComponentName("a", "b"))
556                .setIcon(Icon.createWithResource(mClientContext, 123))
557                .setTitleResId(10)
558                .setTextResId(11)
559                .setDisabledMessageResId(12)
560                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
561                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
562                .setRank(123)
563                .setExtras(pb)
564                .build();
565        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
566        sorig.setBitmapPath("abc");
567        sorig.setIconResourceId(456);
568
569        ShortcutInfo si;
570
571        si = sorig.clone(/* flags=*/ 0);
572        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
573                .setActivity(new ComponentName("x", "y")).build());
574        assertEquals(11, si.getTextResId());
575        assertEquals(new ComponentName("x", "y"), si.getActivity());
576
577        si = sorig.clone(/* flags=*/ 0);
578        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
579                .setIcon(Icon.createWithResource(mClientContext, 456)).build());
580        assertEquals(11, si.getTextResId());
581        assertEquals(456, si.getIcon().getResId());
582
583        si = sorig.clone(/* flags=*/ 0);
584        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
585                .setTitle("xyz").build());
586        assertEquals(11, si.getTextResId());
587        assertEquals("xyz", si.getTitle());
588        assertEquals(0, si.getTitleResId());
589
590        si = sorig.clone(/* flags=*/ 0);
591        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
592                .setTitleResId(123).build());
593        assertEquals(11, si.getTextResId());
594        assertEquals(null, si.getTitle());
595        assertEquals(123, si.getTitleResId());
596
597        si = sorig.clone(/* flags=*/ 0);
598        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
599                .setText("xxx").build());
600        assertEquals(123, si.getRank());
601        assertEquals("xxx", si.getText());
602        assertEquals(0, si.getTextResId());
603
604        si = sorig.clone(/* flags=*/ 0);
605        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
606                .setTextResId(1111).build());
607        assertEquals(123, si.getRank());
608        assertEquals(null, si.getText());
609        assertEquals(1111, si.getTextResId());
610
611        si = sorig.clone(/* flags=*/ 0);
612        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
613                .setDisabledMessage("xxx").build());
614        assertEquals(123, si.getRank());
615        assertEquals("xxx", si.getDisabledMessage());
616        assertEquals(0, si.getDisabledMessageResourceId());
617
618        si = sorig.clone(/* flags=*/ 0);
619        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
620                .setDisabledMessageResId(11111).build());
621        assertEquals(123, si.getRank());
622        assertEquals(null, si.getDisabledMessage());
623        assertEquals(11111, si.getDisabledMessageResourceId());
624
625        si = sorig.clone(/* flags=*/ 0);
626        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
627                .setCategories(set()).build());
628        assertEquals(11, si.getTextResId());
629        assertEquals(set(), si.getCategories());
630
631        si = sorig.clone(/* flags=*/ 0);
632        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
633                .setCategories(set("x")).build());
634        assertEquals(11, si.getTextResId());
635        assertEquals(set("x"), si.getCategories());
636
637        si = sorig.clone(/* flags=*/ 0);
638        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
639                .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
640        assertEquals(11, si.getTextResId());
641        assertEquals("action2", si.getIntent().getAction());
642        assertEquals(null, si.getIntent().getStringExtra("key"));
643
644        si = sorig.clone(/* flags=*/ 0);
645        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
646                .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
647        assertEquals(11, si.getTextResId());
648        assertEquals("action3", si.getIntent().getAction());
649        assertEquals("x", si.getIntent().getStringExtra("key"));
650
651        si = sorig.clone(/* flags=*/ 0);
652        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
653                .setRank(999).build());
654        assertEquals(11, si.getTextResId());
655        assertEquals(999, si.getRank());
656
657
658        PersistableBundle pb2 = new PersistableBundle();
659        pb2.putInt("x", 99);
660
661        si = sorig.clone(/* flags=*/ 0);
662        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
663                .setExtras(pb2).build());
664        assertEquals(11, si.getTextResId());
665        assertEquals(99, si.getExtras().getInt("x"));
666
667        // Make sure the timestamp gets updated too.
668
669        final long timestamp = si.getLastChangedTimestamp();
670        Thread.sleep(2);
671
672        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
673                .setTitle("xyz").build());
674
675        assertTrue(si.getLastChangedTimestamp() > timestamp);
676    }
677
678    public void testShortcutInfoSaveAndLoad() throws InterruptedException {
679        setCaller(CALLING_PACKAGE_1, USER_10);
680
681        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
682                getTestContext().getResources(), R.drawable.black_32x32));
683
684        PersistableBundle pb = new PersistableBundle();
685        pb.putInt("k", 1);
686        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
687                .setId("id")
688                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
689                .setIcon(bmp32x32)
690                .setTitle("title")
691                .setText("text")
692                .setDisabledMessage("dismes")
693                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
694                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
695                .setRank(123)
696                .setExtras(pb)
697                .build();
698
699        mManager.addDynamicShortcuts(list(sorig));
700
701        Thread.sleep(2);
702        final long now = System.currentTimeMillis();
703
704        // Save and load.
705        mService.saveDirtyInfo();
706        initService();
707        mService.handleUnlockUser(USER_10);
708
709        ShortcutInfo si;
710        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
711
712        assertEquals(USER_10, si.getUserId());
713        assertEquals(HANDLE_USER_10, si.getUserHandle());
714        assertEquals(CALLING_PACKAGE_1, si.getPackage());
715        assertEquals("id", si.getId());
716        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
717        assertEquals(null, si.getIcon());
718        assertEquals("title", si.getTitle());
719        assertEquals("text", si.getText());
720        assertEquals("dismes", si.getDisabledMessage());
721        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
722        assertEquals("action", si.getIntent().getAction());
723        assertEquals("val", si.getIntent().getStringExtra("key"));
724        assertEquals(123, si.getRank());
725        assertEquals(1, si.getExtras().getInt("k"));
726
727        assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags());
728        assertNotNull(si.getBitmapPath()); // Something should be set.
729        assertEquals(0, si.getIconResourceId());
730        assertTrue(si.getLastChangedTimestamp() < now);
731    }
732
733    public void testShortcutInfoSaveAndLoad_resId() throws InterruptedException {
734        setCaller(CALLING_PACKAGE_1, USER_10);
735
736        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
737                getTestContext().getResources(), R.drawable.black_32x32));
738
739        PersistableBundle pb = new PersistableBundle();
740        pb.putInt("k", 1);
741        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
742                .setId("id")
743                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
744                .setIcon(bmp32x32)
745                .setTitleResId(10)
746                .setTextResId(11)
747                .setDisabledMessageResId(12)
748                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
749                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
750                .setRank(123)
751                .setExtras(pb)
752                .build();
753
754        mManager.addDynamicShortcuts(list(sorig));
755
756        Thread.sleep(2);
757        final long now = System.currentTimeMillis();
758
759        // Save and load.
760        mService.saveDirtyInfo();
761        initService();
762        mService.handleUnlockUser(USER_10);
763
764        ShortcutInfo si;
765        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
766
767        assertEquals(USER_10, si.getUserId());
768        assertEquals(HANDLE_USER_10, si.getUserHandle());
769        assertEquals(CALLING_PACKAGE_1, si.getPackage());
770        assertEquals("id", si.getId());
771        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
772        assertEquals(null, si.getIcon());
773        assertEquals(10, si.getTitleResId());
774        assertEquals(11, si.getTextResId());
775        assertEquals(12, si.getDisabledMessageResourceId());
776        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
777        assertEquals("action", si.getIntent().getAction());
778        assertEquals("val", si.getIntent().getStringExtra("key"));
779        assertEquals(123, si.getRank());
780        assertEquals(1, si.getExtras().getInt("k"));
781
782        assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags());
783        assertNotNull(si.getBitmapPath()); // Something should be set.
784        assertEquals(0, si.getIconResourceId());
785        assertTrue(si.getLastChangedTimestamp() < now);
786    }
787
788    public void testShortcutInfoSaveAndLoad_forBackup() {
789        setCaller(CALLING_PACKAGE_1, USER_0);
790
791        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
792                getTestContext().getResources(), R.drawable.black_32x32));
793
794        PersistableBundle pb = new PersistableBundle();
795        pb.putInt("k", 1);
796        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
797                .setId("id")
798                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
799                .setIcon(bmp32x32)
800                .setTitle("title")
801                .setText("text")
802                .setDisabledMessage("dismes")
803                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
804                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
805                .setRank(123)
806                .setExtras(pb)
807                .build();
808
809        mManager.addDynamicShortcuts(list(sorig));
810
811        // Dynamic shortcuts won't be backed up, so we need to pin it.
812        setCaller(LAUNCHER_1, USER_0);
813        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
814
815        // Do backup & restore.
816        backupAndRestore();
817
818        mService.handleUnlockUser(USER_0); // Load user-0.
819
820        ShortcutInfo si;
821        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
822
823        assertEquals(CALLING_PACKAGE_1, si.getPackage());
824        assertEquals("id", si.getId());
825        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
826        assertEquals(null, si.getIcon());
827        assertEquals("title", si.getTitle());
828        assertEquals("text", si.getText());
829        assertEquals("dismes", si.getDisabledMessage());
830        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
831        assertEquals("action", si.getIntent().getAction());
832        assertEquals("val", si.getIntent().getStringExtra("key"));
833        assertEquals(123, si.getRank());
834        assertEquals(1, si.getExtras().getInt("k"));
835
836        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
837        assertNull(si.getBitmapPath()); // No icon.
838        assertEquals(0, si.getIconResourceId());
839    }
840
841    public void testShortcutInfoSaveAndLoad_forBackup_resId() {
842        setCaller(CALLING_PACKAGE_1, USER_0);
843
844        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
845                getTestContext().getResources(), R.drawable.black_32x32));
846
847        PersistableBundle pb = new PersistableBundle();
848        pb.putInt("k", 1);
849        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
850                .setId("id")
851                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
852                .setIcon(bmp32x32)
853                .setTitleResId(10)
854                .setTextResId(11)
855                .setDisabledMessageResId(12)
856                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
857                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
858                .setRank(123)
859                .setExtras(pb)
860                .build();
861
862        mManager.addDynamicShortcuts(list(sorig));
863
864        // Dynamic shortcuts won't be backed up, so we need to pin it.
865        setCaller(LAUNCHER_1, USER_0);
866        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
867
868        // Do backup & restore.
869        backupAndRestore();
870
871        mService.handleUnlockUser(USER_0); // Load user-0.
872
873        ShortcutInfo si;
874        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
875
876        assertEquals(CALLING_PACKAGE_1, si.getPackage());
877        assertEquals("id", si.getId());
878        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
879        assertEquals(null, si.getIcon());
880        assertEquals(10, si.getTitleResId());
881        assertEquals(11, si.getTextResId());
882        assertEquals(12, si.getDisabledMessageResourceId());
883        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
884        assertEquals("action", si.getIntent().getAction());
885        assertEquals("val", si.getIntent().getStringExtra("key"));
886        assertEquals(123, si.getRank());
887        assertEquals(1, si.getExtras().getInt("k"));
888
889        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
890        assertNull(si.getBitmapPath()); // No icon.
891        assertEquals(0, si.getIconResourceId());
892    }
893
894
895    public void testThrottling() {
896        final ShortcutInfo si1 = makeShortcut("shortcut1");
897
898        assertTrue(mManager.setDynamicShortcuts(list(si1)));
899        assertEquals(2, mManager.getRemainingCallCount());
900        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
901
902        mInjectedCurrentTimeMillis++;
903        assertTrue(mManager.setDynamicShortcuts(list(si1)));
904        assertEquals(1, mManager.getRemainingCallCount());
905        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
906
907        mInjectedCurrentTimeMillis++;
908        assertTrue(mManager.setDynamicShortcuts(list(si1)));
909        assertEquals(0, mManager.getRemainingCallCount());
910        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
911
912        // Reached the max
913
914        mInjectedCurrentTimeMillis++;
915        assertFalse(mManager.setDynamicShortcuts(list(si1)));
916        assertEquals(0, mManager.getRemainingCallCount());
917        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
918
919        // Still throttled
920        mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
921        assertFalse(mManager.setDynamicShortcuts(list(si1)));
922        assertEquals(0, mManager.getRemainingCallCount());
923        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
924
925        // Now it should work.
926        mInjectedCurrentTimeMillis++;
927        assertTrue(mManager.setDynamicShortcuts(list(si1))); // fail
928        assertEquals(2, mManager.getRemainingCallCount());
929        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
930
931        mInjectedCurrentTimeMillis++;
932        assertTrue(mManager.setDynamicShortcuts(list(si1)));
933        assertEquals(1, mManager.getRemainingCallCount());
934        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
935
936        mInjectedCurrentTimeMillis++;
937        assertTrue(mManager.setDynamicShortcuts(list(si1)));
938        assertEquals(0, mManager.getRemainingCallCount());
939        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
940
941        mInjectedCurrentTimeMillis++;
942        assertFalse(mManager.setDynamicShortcuts(list(si1)));
943        assertEquals(0, mManager.getRemainingCallCount());
944        assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
945
946        // 4 hours later...
947        mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL;
948        assertTrue(mManager.setDynamicShortcuts(list(si1)));
949        assertEquals(2, mManager.getRemainingCallCount());
950        assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
951
952        mInjectedCurrentTimeMillis++;
953        assertTrue(mManager.setDynamicShortcuts(list(si1)));
954        assertEquals(1, mManager.getRemainingCallCount());
955        assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
956
957        // Make sure getRemainingCallCount() itself gets reset without calling setDynamicShortcuts().
958        mInjectedCurrentTimeMillis = START_TIME + 8 * INTERVAL;
959        assertEquals(3, mManager.getRemainingCallCount());
960        assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
961
962        mInjectedCurrentTimeMillis++;
963        assertTrue(mManager.setDynamicShortcuts(list(si1)));
964        assertEquals(2, mManager.getRemainingCallCount());
965        assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
966    }
967
968    public void testThrottling_rewind() {
969        final ShortcutInfo si1 = makeShortcut("shortcut1");
970
971        assertTrue(mManager.setDynamicShortcuts(list(si1)));
972        assertEquals(2, mManager.getRemainingCallCount());
973        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
974
975        mInjectedCurrentTimeMillis = 12345; // Clock reset!
976
977        // Since the clock looks invalid, the counter shouldn't have reset.
978        assertEquals(2, mManager.getRemainingCallCount());
979        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
980
981        // Forward again.  Still haven't reset yet.
982        mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
983        assertEquals(2, mManager.getRemainingCallCount());
984        assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
985
986        // Now rewind -- this will reset the counters.
987        mInjectedCurrentTimeMillis = START_TIME - 100000;
988        assertEquals(3, mManager.getRemainingCallCount());
989
990        assertTrue(mManager.setDynamicShortcuts(list(si1)));
991        assertEquals(2, mManager.getRemainingCallCount());
992
993        // Forward again, should be reset now.
994        mInjectedCurrentTimeMillis += INTERVAL;
995        assertEquals(3, mManager.getRemainingCallCount());
996    }
997
998    public void testThrottling_perPackage() {
999        final ShortcutInfo si1 = makeShortcut("shortcut1");
1000
1001        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1002        assertEquals(2, mManager.getRemainingCallCount());
1003
1004        mInjectedCurrentTimeMillis++;
1005        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1006        assertEquals(1, mManager.getRemainingCallCount());
1007
1008        mInjectedCurrentTimeMillis++;
1009        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1010        assertEquals(0, mManager.getRemainingCallCount());
1011
1012        // Reached the max
1013
1014        mInjectedCurrentTimeMillis++;
1015        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1016
1017        // Try from a different caller.
1018        mInjectedClientPackage = CALLING_PACKAGE_2;
1019        mInjectedCallingUid = CALLING_UID_2;
1020
1021        // Need to create a new one wit the updated package name.
1022        final ShortcutInfo si2 = makeShortcut("shortcut1");
1023
1024        assertEquals(3, mManager.getRemainingCallCount());
1025
1026        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1027        assertEquals(2, mManager.getRemainingCallCount());
1028
1029        mInjectedCurrentTimeMillis++;
1030        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1031        assertEquals(1, mManager.getRemainingCallCount());
1032
1033        // Back to the original caller, still throttled.
1034        mInjectedClientPackage = CALLING_PACKAGE_1;
1035        mInjectedCallingUid = CALLING_UID_1;
1036
1037        mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
1038        assertEquals(0, mManager.getRemainingCallCount());
1039        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1040        assertEquals(0, mManager.getRemainingCallCount());
1041
1042        // Now it should work.
1043        mInjectedCurrentTimeMillis++;
1044        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1045
1046        mInjectedCurrentTimeMillis++;
1047        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1048
1049        mInjectedCurrentTimeMillis++;
1050        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1051
1052        mInjectedCurrentTimeMillis++;
1053        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1054
1055        mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL;
1056        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1057        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1058        assertTrue(mManager.setDynamicShortcuts(list(si1)));
1059        assertFalse(mManager.setDynamicShortcuts(list(si1)));
1060
1061        mInjectedClientPackage = CALLING_PACKAGE_2;
1062        mInjectedCallingUid = CALLING_UID_2;
1063
1064        assertEquals(3, mManager.getRemainingCallCount());
1065
1066        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1067        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1068        assertTrue(mManager.setDynamicShortcuts(list(si2)));
1069        assertFalse(mManager.setDynamicShortcuts(list(si2)));
1070    }
1071
1072    public void testThrottling_localeChanges() {
1073        prepareCrossProfileDataSet();
1074
1075        dumpsysOnLogcat("Before save & load");
1076
1077        mService.saveDirtyInfo();
1078        initService();
1079
1080        final long origSequenceNumber = mService.getLocaleChangeSequenceNumber();
1081
1082        // onSystemLocaleChangedNoLock before boot completed will be ignored.
1083        mInternal.onSystemLocaleChangedNoLock();
1084        assertEquals(origSequenceNumber, mService.getLocaleChangeSequenceNumber());
1085
1086        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
1087        mInternal.onSystemLocaleChangedNoLock();
1088        assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
1089
1090        // Note at this point only user-0 is loaded, and the counters are reset for this user,
1091        // but it will work for other users too, because we persist when
1092
1093        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1094            assertEquals(3, mManager.getRemainingCallCount());
1095        });
1096        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1097            assertEquals(3, mManager.getRemainingCallCount());
1098        });
1099        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1100            assertEquals(3, mManager.getRemainingCallCount());
1101        });
1102        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1103            assertEquals(3, mManager.getRemainingCallCount());
1104        });
1105        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1106            assertEquals(3, mManager.getRemainingCallCount());
1107        });
1108        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1109            assertEquals(3, mManager.getRemainingCallCount());
1110        });
1111
1112        mService.saveDirtyInfo();
1113        initService();
1114
1115        // Make sure the counter is persisted.
1116        assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
1117    }
1118
1119    public void testThrottling_foreground() throws Exception {
1120        prepareCrossProfileDataSet();
1121
1122        dumpsysOnLogcat("Before save & load");
1123
1124        mService.saveDirtyInfo();
1125        initService();
1126
1127        // We need to update the current time from time to time, since some of the internal checks
1128        // rely on the time being correctly incremented.
1129        mInjectedCurrentTimeMillis++;
1130
1131        // First, all packages have less than 3 (== initial value) remaining calls.
1132
1133        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1134            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1135        });
1136        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1137            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1138        });
1139        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1140            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1141        });
1142        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1143            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1144        });
1145        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1146            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1147        });
1148        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1149            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1150        });
1151
1152        mInjectedCurrentTimeMillis++;
1153
1154        // State changed, but not foreground, so no resetting.
1155        mService.mUidObserver.onUidStateChanged(
1156                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1157        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1158            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1159        });
1160        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1161            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1162        });
1163        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1164            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1165        });
1166        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1167            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1168        });
1169        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1170            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1171        });
1172        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1173            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1174        });
1175
1176        mInjectedCurrentTimeMillis++;
1177
1178        // State changed, package1 foreground, reset.
1179        mService.mUidObserver.onUidStateChanged(
1180                CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1181        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1182            assertEquals(3, mManager.getRemainingCallCount());
1183        });
1184        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1185            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1186        });
1187        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1188            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1189        });
1190        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1191            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1192        });
1193        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1194            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1195        });
1196        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1197            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1198        });
1199        mService.mUidObserver.onUidStateChanged(
1200                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1201
1202        mInjectedCurrentTimeMillis++;
1203
1204        // Different app comes to foreground briefly, and goes back to background.
1205        // Now, make sure package 2's counter is reset, even in this case.
1206        mService.mUidObserver.onUidStateChanged(
1207                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1208        mService.mUidObserver.onUidStateChanged(
1209                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1210
1211        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1212            assertEquals(3, mManager.getRemainingCallCount());
1213        });
1214        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1215            assertEquals(3, mManager.getRemainingCallCount());
1216        });
1217        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1218            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1219        });
1220        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1221            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1222        });
1223        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1224            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1225        });
1226        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1227            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1228        });
1229
1230        mInjectedCurrentTimeMillis++;
1231
1232        // Do the same thing one more time.  This would catch the bug with mixuing up
1233        // the current time and the elapsed time.
1234        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1235            mManager.updateShortcuts(list(makeShortcut("s")));
1236            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1237        });
1238
1239        mService.mUidObserver.onUidStateChanged(
1240                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1241        mService.mUidObserver.onUidStateChanged(
1242                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
1243
1244        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1245            assertEquals(3, mManager.getRemainingCallCount());
1246        });
1247        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1248            assertEquals(3, mManager.getRemainingCallCount());
1249        });
1250        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1251            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1252        });
1253        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1254            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1255        });
1256        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1257            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1258        });
1259        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1260            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1261        });
1262
1263        mInjectedCurrentTimeMillis++;
1264
1265        // Package 1 on user-10 comes to foreground.
1266        // Now, also try calling some APIs and make sure foreground apps don't get throttled.
1267        mService.mUidObserver.onUidStateChanged(
1268                UserHandle.getUid(USER_10, CALLING_UID_1),
1269                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
1270        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1271            assertEquals(3, mManager.getRemainingCallCount());
1272
1273            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1274            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1275            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1276
1277            assertEquals(0, mManager.getRemainingCallCount());
1278        });
1279        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1280            assertEquals(3, mManager.getRemainingCallCount());
1281
1282            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1283            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1284            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1285
1286            assertEquals(0, mManager.getRemainingCallCount());
1287        });
1288        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1289            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1290
1291            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1292            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1293            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1294
1295            assertEquals(0, mManager.getRemainingCallCount());
1296        });
1297        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1298            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1299
1300            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1301            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1302            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1303
1304            assertEquals(0, mManager.getRemainingCallCount());
1305        });
1306        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1307            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1308
1309            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1310            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1311            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1312
1313            assertEquals(0, mManager.getRemainingCallCount());
1314        });
1315        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1316            assertEquals(3, mManager.getRemainingCallCount());
1317
1318            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1319            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1320            mManager.setDynamicShortcuts(list(makeShortcut("s")));
1321
1322            assertEquals(3, mManager.getRemainingCallCount()); // Still 3!
1323        });
1324    }
1325
1326
1327    public void testThrottling_resetByInternalCall() throws Exception {
1328        prepareCrossProfileDataSet();
1329
1330        dumpsysOnLogcat("Before save & load");
1331
1332        mService.saveDirtyInfo();
1333        initService();
1334
1335        // First, all packages have less than 3 (== initial value) remaining calls.
1336
1337        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1338            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1339        });
1340        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1341            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1342        });
1343        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1344            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1345        });
1346        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1347            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1348        });
1349        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1350            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1351        });
1352        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1353            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1354        });
1355
1356        // Simulate a call from sys UI.
1357        mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
1358        mService.onApplicationActive(CALLING_PACKAGE_1, USER_0);
1359
1360        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1361            assertEquals(3, mManager.getRemainingCallCount());
1362        });
1363        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1364            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1365        });
1366        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1367            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1368        });
1369        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1370            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1371        });
1372        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1373            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1374        });
1375        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1376            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1377        });
1378
1379        mService.onApplicationActive(CALLING_PACKAGE_3, USER_0);
1380
1381        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1382            assertEquals(3, mManager.getRemainingCallCount());
1383        });
1384        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1385            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1386        });
1387        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1388            assertEquals(3, mManager.getRemainingCallCount());
1389        });
1390        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1391            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1392        });
1393        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1394            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1395        });
1396        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1397            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1398        });
1399
1400        mService.onApplicationActive(CALLING_PACKAGE_1, USER_10);
1401
1402        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
1403            assertEquals(3, mManager.getRemainingCallCount());
1404        });
1405        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
1406            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1407        });
1408        runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
1409            assertEquals(3, mManager.getRemainingCallCount());
1410        });
1411        runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
1412            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1413        });
1414        runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
1415            MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
1416        });
1417        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
1418            assertEquals(3, mManager.getRemainingCallCount());
1419        });
1420    }
1421}
1422