ShortcutManagerTest3.java revision f34c308dfd9cdda428b8ead8bf655de1608501a9
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.assertWith;
19import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
20
21import android.content.ComponentName;
22import android.content.pm.ShortcutInfo;
23import android.test.suitebuilder.annotation.SmallTest;
24
25import com.android.frameworks.servicestests.R;
26import com.android.server.pm.ShortcutService.ConfigConstants;
27
28/**
29 * Tests related to shortcut rank auto-adjustment.
30 */
31@SmallTest
32public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
33
34    private static final String CALLING_PACKAGE = CALLING_PACKAGE_1;
35
36    private static final ComponentName A1 = new ComponentName(CALLING_PACKAGE,
37            ShortcutActivity.class.getName());
38
39    private static final ComponentName A2 = new ComponentName(CALLING_PACKAGE,
40            ShortcutActivity2.class.getName());
41
42    private static final ComponentName A3 = new ComponentName(CALLING_PACKAGE,
43            ShortcutActivity3.class.getName());
44
45    private ShortcutInfo shortcut(String id, ComponentName activity, int rank) {
46        return makeShortcutWithActivityAndRank(id, activity, rank);
47    }
48
49    private ShortcutInfo shortcut(String id, ComponentName activity) {
50        return makeShortcutWithActivityAndRank(id, activity, ShortcutInfo.RANK_NOT_SET);
51    }
52
53    @Override
54    protected void setUp() throws Exception {
55        super.setUp();
56
57        // We don't need throttling during this test class, and also relax the max cap.
58        mService.updateConfigurationLocked(
59                ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
60                + ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
61        );
62
63        setCaller(CALLING_PACKAGE, USER_0);
64    }
65
66    private void publishManifestShortcuts(ComponentName activity, int resId) {
67        addManifestShortcutResource(activity, resId);
68        updatePackageVersion(CALLING_PACKAGE, 1);
69        mService.mPackageMonitor.onReceive(getTestContext(),
70                genPackageAddIntent(CALLING_PACKAGE, USER_0));
71    }
72
73    public void testSetDynamicShortcuts_noManifestShortcuts() {
74        mManager.setDynamicShortcuts(list(
75                shortcut("s1", A1)
76        ));
77
78        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
79                .haveRanksInOrder("s1");
80
81        assertTrue(mManager.setDynamicShortcuts(list(
82                shortcut("s5", A1),
83                shortcut("s4", A1),
84                shortcut("s3", A1)
85        )));
86        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
87                .haveRanksInOrder("s5", "s4", "s3");
88
89        // RANK_NOT_SET is always the last.
90        assertTrue(mManager.setDynamicShortcuts(list(
91                shortcut("s5", A1),
92                shortcut("s4", A1, 5),
93                shortcut("s3", A1, 3),
94                shortcut("s2", A1)
95        )));
96        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
97                .haveRanksInOrder("s3", "s4", "s5", "s2");
98
99        // Same rank, preserve the argument order.
100        assertTrue(mManager.setDynamicShortcuts(list(
101                shortcut("s5", A1, 5),
102                shortcut("s4", A1, 0),
103                shortcut("s3", A1, 5)
104        )));
105        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
106                .haveRanksInOrder("s4", "s5", "s3");
107
108        // Multiple activities.
109        assertTrue(mManager.setDynamicShortcuts(list(
110                shortcut("s5", A1),
111                shortcut("s4", A2),
112                shortcut("s3", A3)
113        )));
114        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
115                .haveRanksInOrder("s5");
116        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
117                .haveRanksInOrder("s4");
118        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
119                .haveRanksInOrder("s3");
120
121        assertTrue(mManager.setDynamicShortcuts(list(
122                shortcut("s5", A1, 5),
123                shortcut("s4", A1),
124                shortcut("s3", A1, 5),
125                shortcut("x5", A2, 5),
126                shortcut("x4", A2),
127                shortcut("x3", A2, 1)
128        )));
129        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
130                .haveRanksInOrder("s5", "s3", "s4");
131        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
132                .haveRanksInOrder("x3", "x5", "x4");
133
134        // Clear.  Make sure it wouldn't lead to invalid internals state.
135        // (ShortcutService.verifyStates() will do so internally.)
136        assertTrue(mManager.setDynamicShortcuts(list()));
137        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1).isEmpty();
138        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2).isEmpty();
139    }
140
141    private void runTestWithManifestShortcuts(Runnable r) {
142        publishManifestShortcuts(A1, R.xml.shortcut_5_alt);
143        publishManifestShortcuts(A2, R.xml.shortcut_1);
144
145        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
146                .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
147
148        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
149                .haveRanksInOrder("ms1");
150
151        // Existence of manifest shortcuts shouldn't affect dynamic shortcut ranks,
152        // so running another test here should pass.
153        r.run();
154
155        // And dynamic shortcut tests shouldn't affect manifest shortcuts, so repeat the
156        // same check.
157        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
158                .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
159
160        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
161                .haveRanksInOrder("ms1");
162    }
163
164    public void testSetDynamicShortcuts_withManifestShortcuts() {
165        runTestWithManifestShortcuts(() -> testSetDynamicShortcuts_noManifestShortcuts());
166    }
167
168    public void testAddDynamicShortcuts_noManifestShortcuts() {
169        mManager.addDynamicShortcuts(list(
170                shortcut("s1", A1)
171        ));
172        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
173                .haveRanksInOrder("s1");
174
175        //------------------------------------------------------
176        long lastApiTime = ++mInjectedCurrentTimeMillis;
177
178        mManager.addDynamicShortcuts(list(
179                shortcut("s5", A1, 0),
180                shortcut("s4", A1),
181                shortcut("s2", A1, 3),
182                shortcut("x1", A2),
183                shortcut("x3", A2, 2),
184                shortcut("x2", A2, 2),
185                shortcut("s3", A1, 0)
186        ));
187        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
188                .haveRanksInOrder("s5", "s3", "s1", "s2", "s4");
189
190        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
191                .haveRanksInOrder("x3", "x2", "x1");
192
193        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
194                .haveIds("s5", "s3", "s1", "s2", "s4", "x3", "x2", "x1");
195
196        //------------------------------------------------------
197        lastApiTime = ++mInjectedCurrentTimeMillis;
198
199        mManager.addDynamicShortcuts(list(
200                shortcut("s1", A1, 1)
201        ));
202        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
203                .haveRanksInOrder("s5", "s1", "s3", "s2", "s4");
204
205        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
206                .haveRanksInOrder("x3", "x2", "x1");
207
208        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
209                .haveIds("s1", "s3");
210
211        //------------------------------------------------------
212        lastApiTime = ++mInjectedCurrentTimeMillis;
213
214        mManager.addDynamicShortcuts(list(
215                shortcut("s1", A1, 1),
216
217                // This is add, not update, so the following means s5 will have NO_RANK,
218                // which puts it at the end.
219                shortcut("s5", A1),
220                shortcut("s3", A1, 0),
221
222                // s10 also has NO_RANK, so it'll be put at the end, even after "s5" as we preserve
223                // the argument order.
224                shortcut("s10", A1),
225
226                // Note we're changing the activity for x2.
227                shortcut("x2", A1, 0),
228                shortcut("x10", A2)
229        ));
230        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
231                .haveRanksInOrder("s3", "x2", "s1", "s2", "s4", "s5", "s10");
232
233        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
234                .haveRanksInOrder("x3", "x1", "x10");
235
236        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
237                .haveIds("s3", "x2", "s1", "s5", "s10", "x1", "x10");
238
239        //------------------------------------------------------
240        lastApiTime = ++mInjectedCurrentTimeMillis;
241
242        // Change the activities again.
243        mManager.addDynamicShortcuts(list(
244                shortcut("s1", A2),
245                shortcut("s2", A2, 999)
246        ));
247        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
248                .haveRanksInOrder("s3", "x2", "s4", "s5", "s10");
249
250        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
251                .haveRanksInOrder("x3", "x1", "x10", "s2", "s1");
252
253        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
254                .haveIds("s1", "s2", "s4", "s5", "s10");
255    }
256
257    public void testAddDynamicShortcuts_withManifestShortcuts() {
258        runTestWithManifestShortcuts(() -> testAddDynamicShortcuts_noManifestShortcuts());
259    }
260
261    public void testUpdateShortcuts_noManifestShortcuts() {
262        mManager.addDynamicShortcuts(list(
263                shortcut("s5", A1, 0),
264                shortcut("s4", A1),
265                shortcut("s2", A1, 3),
266                shortcut("x1", A2),
267                shortcut("x3", A2, 2),
268                shortcut("x2", A2, 2),
269                shortcut("s3", A1, 0)
270        ));
271        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
272                .haveRanksInOrder("s5", "s3", "s2", "s4");
273
274        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
275                .haveRanksInOrder("x3", "x2", "x1");
276
277        //------------------------------------------------------
278        long lastApiTime = ++mInjectedCurrentTimeMillis;
279
280        mManager.updateShortcuts(list());
281        // Same order.
282        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
283                .haveRanksInOrder("s5", "s3", "s2", "s4");
284
285        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
286                .haveRanksInOrder("x3", "x2", "x1");
287
288        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
289                .isEmpty();
290
291
292        runWithCaller(LAUNCHER_1, USER_0, () -> {
293            mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
294        });
295        // Still same order.
296        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
297                .haveRanksInOrder("s5", "s3", "s2", "s4");
298
299        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
300                .haveRanksInOrder("x3", "x2", "x1");
301
302        //------------------------------------------------------
303        lastApiTime = ++mInjectedCurrentTimeMillis;
304
305        mManager.updateShortcuts(list(
306                shortcut("s4", A1, 1),
307
308                // Rank not changing, should keep the same positions.
309                // c.f. in case of addDynamicShortcuts, this means "put them at the end".
310                shortcut("s3", A1),
311                shortcut("x2", A2)
312        ));
313        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
314                .haveRanksInOrder("s5", "s4", "s3", "s2");
315
316        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
317                .haveRanksInOrder("x3", "x2", "x1");
318
319        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
320                .haveIds("s4", "s3", "s2", "x2");
321
322        //------------------------------------------------------
323        lastApiTime = ++mInjectedCurrentTimeMillis;
324
325        mManager.updateShortcuts(list(
326                shortcut("s4", A1, 0),
327
328                // Change the activity without specifying a rank -> keep the same rank.
329                shortcut("s5", A2),
330
331                // Change the activity without specifying a rank -> assign a new rank.
332                shortcut("x2", A1, 2),
333
334                // "xx" doesn't exist, so it'll be ignored.
335                shortcut("xx", A1, 0)
336        ));
337        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
338                .haveRanksInOrder("s4", "x2", "s3", "s2");
339
340        // Interesting case: both x3 and s5 originally had rank=0, and in this case s5 has moved
341        // to A2 without changing the rank.  So they're tie for the new rank, as well as
342        // the "rank changed" bit.  Also in this case, "s5" won't have an implicit order, since
343        // its rank isn't changing.  So we sort them by ID, thus s5 comes before x3.
344        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
345                .haveRanksInOrder("s5", "x3", "x1");
346
347        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
348                .haveIds("s4", "x2", "s5", "x3");
349
350        //------------------------------------------------------
351        lastApiTime = ++mInjectedCurrentTimeMillis;
352
353        mManager.updateShortcuts(list(
354                shortcut("s3", A3)));
355
356        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
357                .haveRanksInOrder("s4", "x2", "s2");
358        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
359                .haveRanksInOrder("s5", "x3", "x1");
360        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
361                .haveRanksInOrder("s3");
362
363        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
364                .haveIds("s3", "s2");
365    }
366
367    public void testUpdateShortcuts_withManifestShortcuts() {
368        runTestWithManifestShortcuts(() -> testUpdateShortcuts_noManifestShortcuts());
369    }
370
371    public void testDeleteDynamicShortcuts_noManifestShortcuts() {
372        mManager.addDynamicShortcuts(list(
373                shortcut("s5", A1, 0),
374                shortcut("s4", A1),
375                shortcut("s2", A1, 3),
376                shortcut("x1", A2),
377                shortcut("x3", A2, 2),
378                shortcut("x2", A2, 2),
379                shortcut("s3", A1, 0)
380        ));
381        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
382                .haveRanksInOrder("s5", "s3", "s2", "s4");
383
384        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
385                .haveRanksInOrder("x3", "x2", "x1");
386
387        //------------------------------------------------------
388        long lastApiTime = ++mInjectedCurrentTimeMillis;
389
390        mManager.removeDynamicShortcuts(list());
391
392        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
393                .haveRanksInOrder("s5", "s3", "s2", "s4");
394
395        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
396                .haveRanksInOrder("x3", "x2", "x1");
397
398        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
399                .isEmpty();
400
401        runWithCaller(LAUNCHER_1, USER_0, () -> {
402            mLauncherApps.pinShortcuts(
403                    CALLING_PACKAGE, list("s2", "s4", "x1", "x2"), HANDLE_USER_0);
404        });
405        // Still same order.
406
407        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
408                .haveRanksInOrder("s5", "s3", "s2", "s4");
409
410        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
411                .haveRanksInOrder("x3", "x2", "x1");
412
413        //------------------------------------------------------
414        lastApiTime = ++mInjectedCurrentTimeMillis;
415
416        mManager.removeDynamicShortcuts(list("s3", "x1", "xxxx"));
417
418        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
419                .haveRanksInOrder("s5", "s2", "s4");
420
421        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
422                .haveRanksInOrder("x3", "x2");
423
424        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
425                .haveIds("s2", "s4");
426    }
427
428    public void testDeleteDynamicShortcuts_withManifestShortcuts() {
429        runTestWithManifestShortcuts(() -> testDeleteDynamicShortcuts_noManifestShortcuts());
430    }
431
432    public void testDisableShortcuts_noManifestShortcuts() {
433        mManager.addDynamicShortcuts(list(
434                shortcut("s5", A1, 0),
435                shortcut("s4", A1),
436                shortcut("s2", A1, 3),
437                shortcut("x1", A2),
438                shortcut("x3", A2, 2),
439                shortcut("x2", A2, 2),
440                shortcut("s3", A1, 0)
441        ));
442        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
443                .haveRanksInOrder("s5", "s3", "s2", "s4");
444
445        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
446                .haveRanksInOrder("x3", "x2", "x1");
447
448        //------------------------------------------------------
449        long lastApiTime = ++mInjectedCurrentTimeMillis;
450
451        mManager.disableShortcuts(list());
452
453        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
454                .haveRanksInOrder("s5", "s3", "s2", "s4");
455
456        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
457                .haveRanksInOrder("x3", "x2", "x1");
458
459        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
460                .isEmpty();
461
462        //------------------------------------------------------
463        lastApiTime = ++mInjectedCurrentTimeMillis;
464
465        mManager.disableShortcuts(list("s3", "x1", "xxxx"));
466
467        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
468                .haveRanksInOrder("s5", "s2", "s4");
469
470        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
471                .haveRanksInOrder("x3", "x2");
472
473        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
474                .haveIds("s2", "s4");
475
476        runWithCaller(LAUNCHER_1, USER_0, () -> {
477            mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
478        });
479        // Still same order.
480        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
481                .haveRanksInOrder("s5", "s2", "s4");
482
483        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
484                .haveRanksInOrder("x3", "x2");
485
486        //------------------------------------------------------
487        lastApiTime = ++mInjectedCurrentTimeMillis;
488
489        mManager.disableShortcuts(list("s2", "x3"));
490
491        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
492                .haveRanksInOrder("s5", "s4");
493
494        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
495                .haveRanksInOrder("x2");
496
497        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
498                .haveIds("s4", "x2");
499    }
500
501    public void testDisableShortcuts_withManifestShortcuts() {
502        runTestWithManifestShortcuts(() -> testDisableShortcuts_noManifestShortcuts());
503    }
504
505}
506