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