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.cloneShortcutList;
     19 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
     20 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
     21 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makeBundle;
     22 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
     23 
     24 import static org.mockito.Matchers.any;
     25 import static org.mockito.Matchers.anyInt;
     26 import static org.mockito.Matchers.anyString;
     27 import static org.mockito.Matchers.eq;
     28 import static org.mockito.Mockito.doAnswer;
     29 import static org.mockito.Mockito.mock;
     30 import static org.mockito.Mockito.reset;
     31 import static org.mockito.Mockito.spy;
     32 import static org.mockito.Mockito.times;
     33 import static org.mockito.Mockito.verify;
     34 import static org.mockito.Mockito.when;
     35 
     36 import android.annotation.NonNull;
     37 import android.annotation.UserIdInt;
     38 import android.app.Activity;
     39 import android.app.ActivityManager;
     40 import android.app.ActivityManagerInternal;
     41 import android.app.IUidObserver;
     42 import android.app.usage.UsageStatsManagerInternal;
     43 import android.content.ActivityNotFoundException;
     44 import android.content.BroadcastReceiver;
     45 import android.content.ComponentName;
     46 import android.content.Context;
     47 import android.content.Intent;
     48 import android.content.IntentFilter;
     49 import android.content.pm.ActivityInfo;
     50 import android.content.pm.ApplicationInfo;
     51 import android.content.pm.ILauncherApps;
     52 import android.content.pm.LauncherApps;
     53 import android.content.pm.LauncherApps.ShortcutQuery;
     54 import android.content.pm.PackageInfo;
     55 import android.content.pm.PackageManager;
     56 import android.content.pm.PackageManagerInternal;
     57 import android.content.pm.ResolveInfo;
     58 import android.content.pm.ShortcutInfo;
     59 import android.content.pm.ShortcutManager;
     60 import android.content.pm.ShortcutServiceInternal;
     61 import android.content.pm.Signature;
     62 import android.content.pm.UserInfo;
     63 import android.content.res.Resources;
     64 import android.content.res.XmlResourceParser;
     65 import android.graphics.drawable.Icon;
     66 import android.net.Uri;
     67 import android.os.Bundle;
     68 import android.os.FileUtils;
     69 import android.os.Handler;
     70 import android.os.Looper;
     71 import android.os.PersistableBundle;
     72 import android.os.Process;
     73 import android.os.UserHandle;
     74 import android.os.UserManager;
     75 import android.test.InstrumentationTestCase;
     76 import android.test.mock.MockContext;
     77 import android.util.Log;
     78 import android.util.Pair;
     79 
     80 import com.android.internal.util.Preconditions;
     81 import com.android.server.LocalServices;
     82 import com.android.server.SystemService;
     83 import com.android.server.pm.LauncherAppsService.LauncherAppsImpl;
     84 import com.android.server.pm.ShortcutUser.PackageWithUser;
     85 
     86 import org.junit.Assert;
     87 import org.mockito.ArgumentCaptor;
     88 import org.mockito.invocation.InvocationOnMock;
     89 import org.mockito.stubbing.Answer;
     90 
     91 import java.io.BufferedReader;
     92 import java.io.ByteArrayOutputStream;
     93 import java.io.File;
     94 import java.io.FileReader;
     95 import java.io.IOException;
     96 import java.io.InputStreamReader;
     97 import java.io.PrintWriter;
     98 import java.util.ArrayList;
     99 import java.util.HashMap;
    100 import java.util.HashSet;
    101 import java.util.LinkedHashMap;
    102 import java.util.List;
    103 import java.util.Locale;
    104 import java.util.Map;
    105 import java.util.Set;
    106 import java.util.function.BiFunction;
    107 import java.util.function.BiPredicate;
    108 import java.util.function.Consumer;
    109 import java.util.function.Function;
    110 
    111 public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
    112     protected static final String TAG = "ShortcutManagerTest";
    113 
    114     protected static final boolean DUMP_IN_TEARDOWN = false; // DO NOT SUBMIT WITH true
    115 
    116     /**
    117      * Whether to enable dump or not.  Should be only true when debugging to avoid bugs where
    118      * dump affecting the behavior.
    119      */
    120     protected static final boolean ENABLE_DUMP = false // DO NOT SUBMIT WITH true
    121             || DUMP_IN_TEARDOWN || ShortcutService.DEBUG;
    122 
    123     protected static final String[] EMPTY_STRINGS = new String[0]; // Just for readability.
    124 
    125     protected static final String MAIN_ACTIVITY_CLASS = "MainActivity";
    126 
    127     // public for mockito
    128     public class BaseContext extends MockContext {
    129         @Override
    130         public Object getSystemService(String name) {
    131             switch (name) {
    132                 case Context.USER_SERVICE:
    133                     return mMockUserManager;
    134             }
    135             throw new UnsupportedOperationException();
    136         }
    137 
    138         @Override
    139         public String getSystemServiceName(Class<?> serviceClass) {
    140             return getTestContext().getSystemServiceName(serviceClass);
    141         }
    142 
    143         @Override
    144         public PackageManager getPackageManager() {
    145             return mMockPackageManager;
    146         }
    147 
    148         @Override
    149         public Resources getResources() {
    150             return getTestContext().getResources();
    151         }
    152 
    153         @Override
    154         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
    155                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
    156             // ignore.
    157             return null;
    158         }
    159 
    160         @Override
    161         public void unregisterReceiver(BroadcastReceiver receiver) {
    162             // ignore.
    163         }
    164     }
    165 
    166     /** Context used in the client side */
    167     public class ClientContext extends BaseContext {
    168         @Override
    169         public String getPackageName() {
    170             return mInjectedClientPackage;
    171         }
    172 
    173         @Override
    174         public int getUserId() {
    175             return getCallingUserId();
    176         }
    177     }
    178 
    179     /** Context used in the service side */
    180     public class ServiceContext extends BaseContext {
    181         long injectClearCallingIdentity() {
    182             final int prevCallingUid = mInjectedCallingUid;
    183             mInjectedCallingUid = Process.SYSTEM_UID;
    184             return prevCallingUid;
    185         }
    186 
    187         void injectRestoreCallingIdentity(long token) {
    188             mInjectedCallingUid = (int) token;
    189         }
    190 
    191         @Override
    192         public int getUserId() {
    193             return UserHandle.USER_SYSTEM;
    194         }
    195 
    196         public PackageInfo injectGetActivitiesWithMetadata(
    197                 String packageName, @UserIdInt int userId) {
    198             return BaseShortcutManagerTest.this.injectGetActivitiesWithMetadata(packageName, userId);
    199         }
    200 
    201         public XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
    202             return BaseShortcutManagerTest.this.injectXmlMetaData(activityInfo, key);
    203         }
    204     }
    205 
    206     /** ShortcutService with injection override methods. */
    207     protected final class ShortcutServiceTestable extends ShortcutService {
    208         final ServiceContext mContext;
    209         IUidObserver mUidObserver;
    210 
    211         public ShortcutServiceTestable(ServiceContext context, Looper looper) {
    212             super(context, looper, /* onyForPackageManagerApis */ false);
    213             mContext = context;
    214         }
    215 
    216         @Override
    217         public String injectGetLocaleTagsForUser(@UserIdInt int userId) {
    218             return mInjectedLocale.toLanguageTag();
    219         }
    220 
    221         @Override
    222         boolean injectShouldPerformVerification() {
    223             return true; // Always verify during unit tests.
    224         }
    225 
    226         @Override
    227         String injectShortcutManagerConstants() {
    228             return ConfigConstants.KEY_RESET_INTERVAL_SEC + "=" + (INTERVAL / 1000) + ","
    229                     + ConfigConstants.KEY_MAX_SHORTCUTS + "=" + MAX_SHORTCUTS + ","
    230                     + ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "="
    231                     + MAX_UPDATES_PER_INTERVAL + ","
    232                     + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=" + MAX_ICON_DIMENSION + ","
    233                     + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "="
    234                     + MAX_ICON_DIMENSION_LOWRAM + ","
    235                     + ConfigConstants.KEY_ICON_FORMAT + "=PNG,"
    236                     + ConfigConstants.KEY_ICON_QUALITY + "=100";
    237         }
    238 
    239         @Override
    240         long injectClearCallingIdentity() {
    241             return mContext.injectClearCallingIdentity();
    242         }
    243 
    244         @Override
    245         void injectRestoreCallingIdentity(long token) {
    246             mContext.injectRestoreCallingIdentity(token);
    247         }
    248 
    249         @Override
    250         int injectDipToPixel(int dip) {
    251             return dip;
    252         }
    253 
    254         @Override
    255         long injectCurrentTimeMillis() {
    256             return mInjectedCurrentTimeMillis;
    257         }
    258 
    259         @Override
    260         long injectElapsedRealtime() {
    261             // TODO This should be kept separately from mInjectedCurrentTimeMillis, since
    262             // this should increase even if we rewind mInjectedCurrentTimeMillis in some tests.
    263             return mInjectedCurrentTimeMillis - START_TIME;
    264         }
    265 
    266         @Override
    267         int injectBinderCallingUid() {
    268             return mInjectedCallingUid;
    269         }
    270 
    271         @Override
    272         int injectGetPackageUid(String packageName, int userId) {
    273             return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid;
    274         }
    275 
    276         @Override
    277         File injectSystemDataPath() {
    278             return new File(mInjectedFilePathRoot, "system");
    279         }
    280 
    281         @Override
    282         File injectUserDataPath(@UserIdInt int userId) {
    283             return new File(mInjectedFilePathRoot, "user-" + userId);
    284         }
    285 
    286         @Override
    287         void injectValidateIconResPackage(ShortcutInfo shortcut, Icon icon) {
    288             // Can't check
    289         }
    290 
    291         @Override
    292         boolean injectIsLowRamDevice() {
    293             return mInjectedIsLowRamDevice;
    294         }
    295 
    296         @Override
    297         void injectRegisterUidObserver(IUidObserver observer, int which) {
    298             mUidObserver = observer;
    299         }
    300 
    301         @Override
    302         boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
    303             return mDefaultLauncherChecker.test(callingPackage, userId);
    304         }
    305 
    306         @Override
    307         PackageInfo injectPackageInfoWithUninstalled(String packageName, @UserIdInt int userId,
    308                 boolean getSignatures) {
    309             return getInjectedPackageInfo(packageName, userId, getSignatures);
    310         }
    311 
    312         @Override
    313         ApplicationInfo injectApplicationInfoWithUninstalled(
    314                 String packageName, @UserIdInt int userId) {
    315             PackageInfo pi = injectPackageInfoWithUninstalled(
    316                     packageName, userId, /* getSignatures= */ false);
    317             return pi != null ? pi.applicationInfo : null;
    318         }
    319 
    320         @Override
    321         List<PackageInfo> injectGetPackagesWithUninstalled(@UserIdInt int userId) {
    322             return BaseShortcutManagerTest.this.getInstalledPackagesWithUninstalled(userId);
    323         }
    324 
    325         @Override
    326         ActivityInfo injectGetActivityInfoWithMetadataWithUninstalled(ComponentName activity,
    327                 @UserIdInt int userId) {
    328             final PackageInfo pi = mContext.injectGetActivitiesWithMetadata(
    329                     activity.getPackageName(), userId);
    330             if (pi == null || pi.activities == null) {
    331                 return null;
    332             }
    333             for (ActivityInfo ai : pi.activities) {
    334                 if (!mEnabledActivityChecker.test(ai.getComponentName(), userId)) {
    335                     continue;
    336                 }
    337                 if (activity.equals(ai.getComponentName())) {
    338                     return ai;
    339                 }
    340             }
    341             return null;
    342         }
    343 
    344         @Override
    345         boolean injectIsMainActivity(@NonNull ComponentName activity, int userId) {
    346             if (!mEnabledActivityChecker.test(activity, userId)) {
    347                 return false;
    348             }
    349             return mMainActivityChecker.test(activity, userId);
    350         }
    351 
    352         @Override
    353         List<ResolveInfo> injectGetMainActivities(@NonNull String packageName, int userId) {
    354             final PackageInfo pi = mContext.injectGetActivitiesWithMetadata(
    355                     packageName, userId);
    356             if (pi == null || pi.activities == null) {
    357                 return null;
    358             }
    359             final ArrayList<ResolveInfo> ret = new ArrayList<>(pi.activities.length);
    360             for (int i = 0; i < pi.activities.length; i++) {
    361                 if (!mEnabledActivityChecker.test(pi.activities[i].getComponentName(), userId)) {
    362                     continue;
    363                 }
    364                 final ResolveInfo ri = new ResolveInfo();
    365                 ri.activityInfo = pi.activities[i];
    366                 ret.add(ri);
    367             }
    368 
    369             return ret;
    370         }
    371 
    372         @Override
    373         ComponentName injectGetDefaultMainActivity(@NonNull String packageName, int userId) {
    374             return mMainActivityFetcher.apply(packageName, userId);
    375         }
    376 
    377         @Override
    378         boolean injectIsActivityEnabledAndExported(ComponentName activity, @UserIdInt int userId) {
    379             return mEnabledActivityChecker.test(activity, userId);
    380         }
    381 
    382         @Override
    383         XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
    384             return mContext.injectXmlMetaData(activityInfo, key);
    385         }
    386 
    387         @Override
    388         void injectPostToHandler(Runnable r) {
    389             runOnHandler(r);
    390         }
    391 
    392         @Override
    393         void injectRunOnNewThread(Runnable r) {
    394             runOnHandler(r);
    395         }
    396 
    397         @Override
    398         void injectEnforceCallingPermission(String permission, String message) {
    399             if (!mCallerPermissions.contains(permission)) {
    400                 throw new SecurityException("Missing permission: " + permission);
    401             }
    402         }
    403 
    404         @Override
    405         boolean injectIsSafeModeEnabled() {
    406             return mSafeMode;
    407         }
    408 
    409         @Override
    410         String injectBuildFingerprint() {
    411             return mInjectedBuildFingerprint;
    412         }
    413 
    414         @Override
    415         void wtf(String message, Throwable th) {
    416             // During tests, WTF is fatal.
    417             fail(message + "  exception: " + th + "\n" + Log.getStackTraceString(th));
    418         }
    419     }
    420 
    421     /** ShortcutManager with injection override methods. */
    422     protected class ShortcutManagerTestable extends ShortcutManager {
    423         public ShortcutManagerTestable(Context context, ShortcutServiceTestable service) {
    424             super(context, service);
    425         }
    426 
    427         @Override
    428         protected int injectMyUserId() {
    429             return UserHandle.getUserId(mInjectedCallingUid);
    430         }
    431 
    432         @Override
    433         public boolean setDynamicShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
    434             // Note to simulate the binder RPC, we need to clone the incoming arguments.
    435             // Otherwise bad things will happen because they're mutable.
    436             return super.setDynamicShortcuts(cloneShortcutList(shortcutInfoList));
    437         }
    438 
    439         @Override
    440         public boolean addDynamicShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
    441             // Note to simulate the binder RPC, we need to clone the incoming arguments.
    442             return super.addDynamicShortcuts(cloneShortcutList(shortcutInfoList));
    443         }
    444 
    445         @Override
    446         public boolean updateShortcuts(List<ShortcutInfo> shortcutInfoList) {
    447             // Note to simulate the binder RPC, we need to clone the incoming arguments.
    448             return super.updateShortcuts(cloneShortcutList(shortcutInfoList));
    449         }
    450     }
    451 
    452     protected class LauncherAppImplTestable extends LauncherAppsImpl {
    453         final ServiceContext mContext;
    454 
    455         public LauncherAppImplTestable(ServiceContext context) {
    456             super(context);
    457             mContext = context;
    458         }
    459 
    460         @Override
    461         public void verifyCallingPackage(String callingPackage) {
    462             // SKIP
    463         }
    464 
    465         @Override
    466         void postToPackageMonitorHandler(Runnable r) {
    467             runOnHandler(r);
    468         }
    469 
    470         @Override
    471         int injectBinderCallingUid() {
    472             return mInjectedCallingUid;
    473         }
    474 
    475         @Override
    476         long injectClearCallingIdentity() {
    477             final int prevCallingUid = mInjectedCallingUid;
    478             mInjectedCallingUid = Process.SYSTEM_UID;
    479             return prevCallingUid;
    480         }
    481 
    482         @Override
    483         void injectRestoreCallingIdentity(long token) {
    484             mInjectedCallingUid = (int) token;
    485         }
    486     }
    487 
    488     protected class LauncherAppsTestable extends LauncherApps {
    489         public LauncherAppsTestable(Context context, ILauncherApps service) {
    490             super(context, service);
    491         }
    492     }
    493 
    494     public static class ShortcutActivity extends Activity {
    495     }
    496 
    497     public static class ShortcutActivity2 extends Activity {
    498     }
    499 
    500     public static class ShortcutActivity3 extends Activity {
    501     }
    502 
    503     protected Looper mLooper;
    504     protected Handler mHandler;
    505 
    506     protected ServiceContext mServiceContext;
    507     protected ClientContext mClientContext;
    508 
    509     protected ShortcutServiceTestable mService;
    510     protected ShortcutManagerTestable mManager;
    511     protected ShortcutServiceInternal mInternal;
    512 
    513     protected LauncherAppImplTestable mLauncherAppImpl;
    514 
    515     // LauncherApps has per-instace state, so we need a differnt instance for each launcher.
    516     protected final Map<Pair<Integer, String>, LauncherAppsTestable>
    517             mLauncherAppsMap = new HashMap<>();
    518     protected LauncherAppsTestable mLauncherApps; // Current one
    519 
    520     protected File mInjectedFilePathRoot;
    521 
    522     protected boolean mSafeMode;
    523 
    524     protected long mInjectedCurrentTimeMillis;
    525 
    526     protected boolean mInjectedIsLowRamDevice;
    527 
    528     protected Locale mInjectedLocale = Locale.ENGLISH;
    529 
    530     protected int mInjectedCallingUid;
    531     protected String mInjectedClientPackage;
    532 
    533     protected Map<String, PackageInfo> mInjectedPackages;
    534 
    535     protected Set<PackageWithUser> mUninstalledPackages;
    536     protected Set<String> mSystemPackages;
    537 
    538     protected PackageManager mMockPackageManager;
    539     protected PackageManagerInternal mMockPackageManagerInternal;
    540     protected UserManager mMockUserManager;
    541     protected UsageStatsManagerInternal mMockUsageStatsManagerInternal;
    542     protected ActivityManagerInternal mMockActivityManagerInternal;
    543 
    544     protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
    545     protected static final int CALLING_UID_1 = 10001;
    546 
    547     protected static final String CALLING_PACKAGE_2 = "com.android.test.2";
    548     protected static final int CALLING_UID_2 = 10002;
    549 
    550     protected static final String CALLING_PACKAGE_3 = "com.android.test.3";
    551     protected static final int CALLING_UID_3 = 10003;
    552 
    553     protected static final String CALLING_PACKAGE_4 = "com.android.test.4";
    554     protected static final int CALLING_UID_4 = 10004;
    555 
    556     protected static final String LAUNCHER_1 = "com.android.launcher.1";
    557     protected static final int LAUNCHER_UID_1 = 10011;
    558 
    559     protected static final String LAUNCHER_2 = "com.android.launcher.2";
    560     protected static final int LAUNCHER_UID_2 = 10012;
    561 
    562     protected static final String LAUNCHER_3 = "com.android.launcher.3";
    563     protected static final int LAUNCHER_UID_3 = 10013;
    564 
    565     protected static final String LAUNCHER_4 = "com.android.launcher.4";
    566     protected static final int LAUNCHER_UID_4 = 10014;
    567 
    568     protected static final int USER_0 = UserHandle.USER_SYSTEM;
    569     protected static final int USER_10 = 10;
    570     protected static final int USER_11 = 11;
    571     protected static final int USER_P0 = 20; // profile of user 0
    572 
    573     protected static final UserHandle HANDLE_USER_0 = UserHandle.of(USER_0);
    574     protected static final UserHandle HANDLE_USER_10 = UserHandle.of(USER_10);
    575     protected static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11);
    576     protected static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0);
    577 
    578     protected static final UserInfo USER_INFO_0 = withProfileGroupId(
    579             new UserInfo(USER_0, "user0",
    580                     UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED), 10);
    581 
    582     protected static final UserInfo USER_INFO_10 =
    583             new UserInfo(USER_10, "user10", UserInfo.FLAG_INITIALIZED);
    584 
    585     protected static final UserInfo USER_INFO_11 =
    586             new UserInfo(USER_11, "user11", UserInfo.FLAG_INITIALIZED);
    587 
    588     protected static final UserInfo USER_INFO_P0 = withProfileGroupId(
    589             new UserInfo(USER_P0, "userP0",
    590                     UserInfo.FLAG_MANAGED_PROFILE), 10);
    591 
    592     protected BiPredicate<String, Integer> mDefaultLauncherChecker =
    593             (callingPackage, userId) ->
    594             LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage)
    595             || LAUNCHER_3.equals(callingPackage) || LAUNCHER_4.equals(callingPackage);
    596 
    597     protected BiPredicate<ComponentName, Integer> mMainActivityChecker =
    598             (activity, userId) -> true;
    599 
    600     protected BiFunction<String, Integer, ComponentName> mMainActivityFetcher =
    601             (packageName, userId) -> new ComponentName(packageName, MAIN_ACTIVITY_CLASS);
    602 
    603     protected BiPredicate<ComponentName, Integer> mEnabledActivityChecker
    604             = (activity, userId) -> true; // all activities are enabled.
    605 
    606     protected static final long START_TIME = 1440000000101L;
    607 
    608     protected static final long INTERVAL = 10000;
    609 
    610     protected static final int MAX_SHORTCUTS = 10;
    611 
    612     protected static final int MAX_UPDATES_PER_INTERVAL = 3;
    613 
    614     protected static final int MAX_ICON_DIMENSION = 128;
    615 
    616     protected static final int MAX_ICON_DIMENSION_LOWRAM = 32;
    617 
    618     protected static final ShortcutQuery QUERY_ALL = new ShortcutQuery();
    619 
    620     protected final ArrayList<String> mCallerPermissions = new ArrayList<>();
    621 
    622     protected final HashMap<String, LinkedHashMap<ComponentName, Integer>> mActivityMetadataResId
    623             = new HashMap<>();
    624 
    625     protected final Map<Integer, UserInfo> mUserInfos = new HashMap<>();
    626     protected final Map<Integer, Boolean> mRunningUsers = new HashMap<>();
    627     protected final Map<Integer, Boolean> mUnlockedUsers = new HashMap<>();
    628 
    629     protected static final String PACKAGE_SYSTEM_LAUNCHER = "com.android.systemlauncher";
    630     protected static final String PACKAGE_SYSTEM_LAUNCHER_NAME = "systemlauncher_name";
    631     protected static final int PACKAGE_SYSTEM_LAUNCHER_PRIORITY = 0;
    632 
    633     protected static final String PACKAGE_FALLBACK_LAUNCHER = "com.android.settings";
    634     protected static final String PACKAGE_FALLBACK_LAUNCHER_NAME = "fallback";
    635     protected static final int PACKAGE_FALLBACK_LAUNCHER_PRIORITY = -999;
    636 
    637     protected String mInjectedBuildFingerprint = "build1";
    638 
    639     static {
    640         QUERY_ALL.setQueryFlags(
    641                 ShortcutQuery.FLAG_GET_ALL_KINDS);
    642     }
    643 
    644     @Override
    645     protected void setUp() throws Exception {
    646         super.setUp();
    647 
    648         mLooper = Looper.getMainLooper();
    649         mHandler = new Handler(mLooper);
    650 
    651         mServiceContext = spy(new ServiceContext());
    652         mClientContext = new ClientContext();
    653 
    654         mMockPackageManager = mock(PackageManager.class);
    655         mMockPackageManagerInternal = mock(PackageManagerInternal.class);
    656         mMockUserManager = mock(UserManager.class);
    657         mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
    658         mMockActivityManagerInternal = mock(ActivityManagerInternal.class);
    659 
    660         LocalServices.removeServiceForTest(PackageManagerInternal.class);
    661         LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
    662         LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
    663         LocalServices.addService(UsageStatsManagerInternal.class, mMockUsageStatsManagerInternal);
    664         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
    665         LocalServices.addService(ActivityManagerInternal.class, mMockActivityManagerInternal);
    666 
    667         // Prepare injection values.
    668 
    669         mInjectedCurrentTimeMillis = START_TIME;
    670 
    671         mInjectedPackages = new HashMap<>();
    672         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1);
    673         addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 2);
    674         addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 3);
    675         addPackage(CALLING_PACKAGE_4, CALLING_UID_4, 10);
    676         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4);
    677         addPackage(LAUNCHER_2, LAUNCHER_UID_2, 5);
    678         addPackage(LAUNCHER_3, LAUNCHER_UID_3, 6);
    679         addPackage(LAUNCHER_4, LAUNCHER_UID_4, 10);
    680 
    681         // CALLING_PACKAGE_3 / LAUNCHER_3 are not backup target.
    682         updatePackageInfo(CALLING_PACKAGE_3,
    683                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
    684         updatePackageInfo(LAUNCHER_3,
    685                 pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
    686 
    687         mUninstalledPackages = new HashSet<>();
    688         mSystemPackages = new HashSet<>();
    689 
    690         mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");
    691 
    692         deleteAllSavedFiles();
    693 
    694         // Set up users.
    695         when(mMockUserManager.getUserInfo(anyInt())).thenAnswer(new AnswerWithSystemCheck<>(
    696                 inv -> mUserInfos.get((Integer) inv.getArguments()[0])));
    697 
    698         mUserInfos.put(USER_0, USER_INFO_0);
    699         mUserInfos.put(USER_10, USER_INFO_10);
    700         mUserInfos.put(USER_11, USER_INFO_11);
    701         mUserInfos.put(USER_P0, USER_INFO_P0);
    702 
    703         // Set up isUserRunning and isUserUnlocked.
    704         when(mMockUserManager.isUserRunning(anyInt())).thenAnswer(new AnswerWithSystemCheck<>(
    705                         inv -> b(mRunningUsers.get((Integer) inv.getArguments()[0]))));
    706 
    707         when(mMockUserManager.isUserUnlocked(anyInt()))
    708                 .thenAnswer(new AnswerWithSystemCheck<>(inv -> {
    709                     final int userId = (Integer) inv.getArguments()[0];
    710                     return b(mRunningUsers.get(userId)) && b(mUnlockedUsers.get(userId));
    711                 }));
    712         // isUserUnlockingOrUnlocked() return the same value as isUserUnlocked().
    713         when(mMockUserManager.isUserUnlockingOrUnlocked(anyInt()))
    714                 .thenAnswer(new AnswerWithSystemCheck<>(inv -> {
    715                     final int userId = (Integer) inv.getArguments()[0];
    716                     return b(mRunningUsers.get(userId)) && b(mUnlockedUsers.get(userId));
    717                 }));
    718 
    719         when(mMockActivityManagerInternal.getUidProcessState(anyInt())).thenReturn(
    720                 ActivityManager.PROCESS_STATE_CACHED_EMPTY);
    721 
    722         // User 0 and P0 are always running
    723         mRunningUsers.put(USER_0, true);
    724         mRunningUsers.put(USER_10, false);
    725         mRunningUsers.put(USER_11, false);
    726         mRunningUsers.put(USER_P0, true);
    727 
    728         // Unlock all users by default.
    729         mUnlockedUsers.put(USER_0, true);
    730         mUnlockedUsers.put(USER_10, true);
    731         mUnlockedUsers.put(USER_11, true);
    732         mUnlockedUsers.put(USER_P0, true);
    733 
    734         // Set up resources
    735         setUpAppResources();
    736 
    737         // Start the service.
    738         initService();
    739         setCaller(CALLING_PACKAGE_1);
    740     }
    741 
    742     private static boolean b(Boolean value) {
    743         return (value != null && value);
    744     }
    745 
    746     /**
    747      * Returns a boolean but also checks if the current UID is SYSTEM_UID.
    748      */
    749     protected class AnswerWithSystemCheck<T> implements Answer<T> {
    750         private final Function<InvocationOnMock, T> mChecker;
    751 
    752         public AnswerWithSystemCheck(Function<InvocationOnMock, T> checker) {
    753             mChecker = checker;
    754         }
    755 
    756         @Override
    757         public T answer(InvocationOnMock invocation) throws Throwable {
    758             assertEquals("Must be called on SYSTEM UID.",
    759                     Process.SYSTEM_UID, mInjectedCallingUid);
    760             return mChecker.apply(invocation);
    761         }
    762     }
    763 
    764     protected void setUpAppResources() throws Exception {
    765         setUpAppResources(/* offset = */ 0);
    766     }
    767 
    768     protected void setUpAppResources(int ressIdOffset) throws Exception {
    769         // ressIdOffset is used to adjust resource IDs to emulate the case where an updated app
    770         // has resource IDs changed.
    771 
    772         doAnswer(pmInvocation -> {
    773             assertEquals(Process.SYSTEM_UID, mInjectedCallingUid);
    774 
    775             final String packageName = (String) pmInvocation.getArguments()[0];
    776             final int userId = (Integer) pmInvocation.getArguments()[1];
    777 
    778             final Resources res = mock(Resources.class);
    779 
    780             doAnswer(resInvocation -> {
    781                 final int argResId = (Integer) resInvocation.getArguments()[0];
    782 
    783                 return "string-" + packageName + "-user:" + userId + "-res:" + argResId
    784                         + "/" + mInjectedLocale;
    785             }).when(res).getString(anyInt());
    786 
    787             doAnswer(resInvocation -> {
    788                 final int resId = (Integer) resInvocation.getArguments()[0];
    789 
    790                 // Always use the "string" resource type.  The type doesn't matter during the test.
    791                 return packageName + ":string/r" + resId;
    792             }).when(res).getResourceName(anyInt());
    793 
    794             doAnswer(resInvocation -> {
    795                 final String argResName = (String) resInvocation.getArguments()[0];
    796                 final String argType = (String) resInvocation.getArguments()[1];
    797                 final String argPackageName = (String) resInvocation.getArguments()[2];
    798 
    799                 // See the above code.  getResourceName() will just use "r" + res ID as the entry
    800                 // name.
    801                 String entryName = argResName;
    802                 if (entryName.contains("/")) {
    803                     entryName = ShortcutInfo.getResourceEntryName(entryName);
    804                 }
    805                 return Integer.parseInt(entryName.substring(1)) + ressIdOffset;
    806             }).when(res).getIdentifier(anyString(), anyString(), anyString());
    807             return res;
    808         }).when(mMockPackageManager).getResourcesForApplicationAsUser(anyString(), anyInt());
    809     }
    810 
    811     protected static UserInfo withProfileGroupId(UserInfo in, int groupId) {
    812         in.profileGroupId = groupId;
    813         return in;
    814     }
    815 
    816     @Override
    817     protected void tearDown() throws Exception {
    818         if (DUMP_IN_TEARDOWN) dumpsysOnLogcat("Teardown");
    819 
    820         shutdownServices();
    821 
    822         super.tearDown();
    823     }
    824 
    825     protected Context getTestContext() {
    826         return getInstrumentation().getContext();
    827     }
    828 
    829     protected ShortcutManager getManager() {
    830         return mManager;
    831     }
    832 
    833     protected void deleteAllSavedFiles() {
    834         // Empty the data directory.
    835         if (mInjectedFilePathRoot.exists()) {
    836             Assert.assertTrue("failed to delete dir",
    837                     FileUtils.deleteContents(mInjectedFilePathRoot));
    838         }
    839         mInjectedFilePathRoot.mkdirs();
    840     }
    841 
    842     /** (Re-) init the manager and the service. */
    843     protected void initService() {
    844         shutdownServices();
    845 
    846         LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
    847 
    848         // Instantiate targets.
    849         mService = new ShortcutServiceTestable(mServiceContext, mLooper);
    850         mManager = new ShortcutManagerTestable(mClientContext, mService);
    851 
    852         mInternal = LocalServices.getService(ShortcutServiceInternal.class);
    853 
    854         mLauncherAppImpl = new LauncherAppImplTestable(mServiceContext);
    855         mLauncherApps = null;
    856         mLauncherAppsMap.clear();
    857 
    858         // Send boot sequence events.
    859         mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
    860 
    861         mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
    862     }
    863 
    864     protected void shutdownServices() {
    865         if (mService != null) {
    866             // Flush all the unsaved data from the previous instance.
    867             mService.saveDirtyInfo();
    868 
    869             // Make sure everything is consistent.
    870             mService.verifyStates();
    871         }
    872         LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
    873 
    874         mService = null;
    875         mManager = null;
    876         mInternal = null;
    877         mLauncherAppImpl = null;
    878         mLauncherApps = null;
    879         mLauncherAppsMap.clear();
    880     }
    881 
    882     protected void runOnHandler(Runnable r) {
    883         final long token = mServiceContext.injectClearCallingIdentity();
    884         try {
    885             r.run();
    886         } finally {
    887             mServiceContext.injectRestoreCallingIdentity(token);
    888         }
    889     }
    890 
    891     protected void addPackage(String packageName, int uid, int version) {
    892         addPackage(packageName, uid, version, packageName);
    893     }
    894 
    895     protected Signature[] genSignatures(String... signatures) {
    896         final Signature[] sigs = new Signature[signatures.length];
    897         for (int i = 0; i < signatures.length; i++){
    898             sigs[i] = new Signature(signatures[i].getBytes());
    899         }
    900         return sigs;
    901     }
    902 
    903     protected PackageInfo genPackage(String packageName, int uid, int version, String... signatures) {
    904         final PackageInfo pi = new PackageInfo();
    905         pi.packageName = packageName;
    906         pi.applicationInfo = new ApplicationInfo();
    907         pi.applicationInfo.uid = uid;
    908         pi.applicationInfo.flags = ApplicationInfo.FLAG_INSTALLED
    909                 | ApplicationInfo.FLAG_ALLOW_BACKUP;
    910         pi.versionCode = version;
    911         pi.applicationInfo.versionCode = version;
    912         pi.signatures = genSignatures(signatures);
    913 
    914         return pi;
    915     }
    916 
    917     protected void addPackage(String packageName, int uid, int version, String... signatures) {
    918         mInjectedPackages.put(packageName, genPackage(packageName, uid, version, signatures));
    919     }
    920 
    921     protected void updatePackageInfo(String packageName, Consumer<PackageInfo> c) {
    922         c.accept(mInjectedPackages.get(packageName));
    923     }
    924 
    925     protected void updatePackageVersion(String packageName, int increment) {
    926         updatePackageInfo(packageName, pi -> {
    927             pi.versionCode += increment;
    928             pi.applicationInfo.versionCode += increment;
    929         });
    930     }
    931 
    932     protected void updatePackageLastUpdateTime(String packageName, long increment) {
    933         updatePackageInfo(packageName, pi -> {
    934             pi.lastUpdateTime += increment;
    935         });
    936     }
    937 
    938     protected void setPackageLastUpdateTime(String packageName, long value) {
    939         updatePackageInfo(packageName, pi -> {
    940             pi.lastUpdateTime = value;
    941         });
    942     }
    943 
    944     protected void uninstallPackage(int userId, String packageName) {
    945         if (ENABLE_DUMP) {
    946             Log.v(TAG, "Unnstall package " + packageName + " / " + userId);
    947         }
    948         mUninstalledPackages.add(PackageWithUser.of(userId, packageName));
    949     }
    950 
    951     protected void installPackage(int userId, String packageName) {
    952         if (ENABLE_DUMP) {
    953             Log.v(TAG, "Install package " + packageName + " / " + userId);
    954         }
    955         mUninstalledPackages.remove(PackageWithUser.of(userId, packageName));
    956     }
    957 
    958     PackageInfo getInjectedPackageInfo(String packageName, @UserIdInt int userId,
    959             boolean getSignatures) {
    960         final PackageInfo pi = mInjectedPackages.get(packageName);
    961         if (pi == null) return null;
    962 
    963         final PackageInfo ret = new PackageInfo();
    964         ret.packageName = pi.packageName;
    965         ret.versionCode = pi.versionCode;
    966         ret.lastUpdateTime = pi.lastUpdateTime;
    967 
    968         ret.applicationInfo = new ApplicationInfo(pi.applicationInfo);
    969         ret.applicationInfo.uid = UserHandle.getUid(userId, pi.applicationInfo.uid);
    970         ret.applicationInfo.packageName = pi.packageName;
    971 
    972         if (mUninstalledPackages.contains(PackageWithUser.of(userId, packageName))) {
    973             ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
    974         }
    975         if (mSystemPackages.contains(packageName)) {
    976             ret.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
    977         }
    978 
    979         if (getSignatures) {
    980             ret.signatures = pi.signatures;
    981         }
    982 
    983         return ret;
    984     }
    985 
    986     protected void addApplicationInfo(PackageInfo pi, List<ApplicationInfo> list) {
    987         if (pi != null && pi.applicationInfo != null) {
    988             list.add(pi.applicationInfo);
    989         }
    990     }
    991 
    992     protected List<ApplicationInfo> getInstalledApplications(int userId) {
    993         final ArrayList<ApplicationInfo> ret = new ArrayList<>();
    994 
    995         addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_1, userId, false), ret);
    996         addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_2, userId, false), ret);
    997         addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_3, userId, false), ret);
    998         addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_4, userId, false), ret);
    999         addApplicationInfo(getInjectedPackageInfo(LAUNCHER_1, userId, false), ret);
   1000         addApplicationInfo(getInjectedPackageInfo(LAUNCHER_2, userId, false), ret);
   1001         addApplicationInfo(getInjectedPackageInfo(LAUNCHER_3, userId, false), ret);
   1002         addApplicationInfo(getInjectedPackageInfo(LAUNCHER_4, userId, false), ret);
   1003 
   1004         return ret;
   1005     }
   1006 
   1007     private void addPackageInfo(PackageInfo pi, List<PackageInfo> list) {
   1008         if (pi != null) {
   1009             list.add(pi);
   1010         }
   1011     }
   1012 
   1013     private List<PackageInfo> getInstalledPackagesWithUninstalled(int userId) {
   1014         final ArrayList<PackageInfo> ret = new ArrayList<>();
   1015 
   1016         addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_1, userId, false), ret);
   1017         addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_2, userId, false), ret);
   1018         addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_3, userId, false), ret);
   1019         addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_4, userId, false), ret);
   1020         addPackageInfo(getInjectedPackageInfo(LAUNCHER_1, userId, false), ret);
   1021         addPackageInfo(getInjectedPackageInfo(LAUNCHER_2, userId, false), ret);
   1022         addPackageInfo(getInjectedPackageInfo(LAUNCHER_3, userId, false), ret);
   1023         addPackageInfo(getInjectedPackageInfo(LAUNCHER_4, userId, false), ret);
   1024 
   1025         return ret;
   1026     }
   1027 
   1028     protected void addManifestShortcutResource(ComponentName activity, int resId) {
   1029         final String packageName = activity.getPackageName();
   1030         LinkedHashMap<ComponentName, Integer> map = mActivityMetadataResId.get(packageName);
   1031         if (map == null) {
   1032             map = new LinkedHashMap<>();
   1033             mActivityMetadataResId.put(packageName, map);
   1034         }
   1035         map.put(activity, resId);
   1036     }
   1037 
   1038     protected PackageInfo injectGetActivitiesWithMetadata(String packageName, @UserIdInt int userId) {
   1039         final PackageInfo ret = getInjectedPackageInfo(packageName, userId,
   1040                 /* getSignatures=*/ false);
   1041 
   1042         final HashMap<ComponentName, Integer> activities = mActivityMetadataResId.get(packageName);
   1043         if (activities != null) {
   1044             final ArrayList<ActivityInfo> list = new ArrayList<>();
   1045 
   1046             for (ComponentName cn : activities.keySet()) {
   1047                 ActivityInfo ai = new ActivityInfo();
   1048                 ai.packageName = cn.getPackageName();
   1049                 ai.name = cn.getClassName();
   1050                 ai.metaData = new Bundle();
   1051                 ai.metaData.putInt(ShortcutParser.METADATA_KEY, activities.get(cn));
   1052                 ai.applicationInfo = ret.applicationInfo;
   1053                 list.add(ai);
   1054             }
   1055             ret.activities = list.toArray(new ActivityInfo[list.size()]);
   1056         }
   1057         return ret;
   1058     }
   1059 
   1060     protected XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
   1061         if (!ShortcutParser.METADATA_KEY.equals(key) || activityInfo.metaData == null) {
   1062             return null;
   1063         }
   1064         final int resId = activityInfo.metaData.getInt(key);
   1065         return getTestContext().getResources().getXml(resId);
   1066     }
   1067 
   1068     /** Replace the current calling package */
   1069     protected void setCaller(String packageName, int userId) {
   1070         mInjectedClientPackage = packageName;
   1071         mInjectedCallingUid =
   1072                 Preconditions.checkNotNull(getInjectedPackageInfo(packageName, userId, false),
   1073                         "Unknown package").applicationInfo.uid;
   1074 
   1075         // Set up LauncherApps for this caller.
   1076         final Pair<Integer, String> key = Pair.create(userId, packageName);
   1077         if (!mLauncherAppsMap.containsKey(key)) {
   1078             mLauncherAppsMap.put(key, new LauncherAppsTestable(mClientContext, mLauncherAppImpl));
   1079         }
   1080         mLauncherApps = mLauncherAppsMap.get(key);
   1081     }
   1082 
   1083     protected void setCaller(String packageName) {
   1084         setCaller(packageName, UserHandle.USER_SYSTEM);
   1085     }
   1086 
   1087     protected String getCallingPackage() {
   1088         return mInjectedClientPackage;
   1089     }
   1090 
   1091     protected void setDefaultLauncherChecker(BiPredicate<String, Integer> p) {
   1092         mDefaultLauncherChecker = p;
   1093     }
   1094 
   1095     protected void runWithCaller(String packageName, int userId, Runnable r) {
   1096         final String previousPackage = mInjectedClientPackage;
   1097         final int previousUserId = UserHandle.getUserId(mInjectedCallingUid);
   1098 
   1099         setCaller(packageName, userId);
   1100 
   1101         r.run();
   1102 
   1103         setCaller(previousPackage, previousUserId);
   1104     }
   1105 
   1106     protected void runWithSystemUid(Runnable r) {
   1107         final int origUid = mInjectedCallingUid;
   1108         mInjectedCallingUid = Process.SYSTEM_UID;
   1109         r.run();
   1110         mInjectedCallingUid = origUid;
   1111     }
   1112 
   1113     protected void lookupAndFillInResourceNames(ShortcutInfo si) {
   1114         runWithSystemUid(() -> si.lookupAndFillInResourceNames(
   1115                 mService.injectGetResourcesForApplicationAsUser(si.getPackage(), si.getUserId())));
   1116     }
   1117 
   1118     protected int getCallingUserId() {
   1119         return UserHandle.getUserId(mInjectedCallingUid);
   1120     }
   1121 
   1122     protected UserHandle getCallingUser() {
   1123         return UserHandle.of(getCallingUserId());
   1124     }
   1125 
   1126     /** For debugging */
   1127     protected void dumpsysOnLogcat() {
   1128         dumpsysOnLogcat("");
   1129     }
   1130 
   1131     protected void dumpsysOnLogcat(String message) {
   1132         dumpsysOnLogcat(message, false);
   1133     }
   1134 
   1135     protected void dumpsysOnLogcat(String message, boolean force) {
   1136         if (force || !ENABLE_DUMP) return;
   1137 
   1138         Log.v(TAG, "Dumping ShortcutService: " + message);
   1139         for (String line : dumpsys(null).split("\n")) {
   1140             Log.v(TAG, line);
   1141         }
   1142     }
   1143 
   1144     protected String dumpCheckin() {
   1145         return dumpsys(new String[]{"--checkin"});
   1146     }
   1147 
   1148     private String dumpsys(String[] args) {
   1149         final ArrayList<String> origPermissions = new ArrayList<>(mCallerPermissions);
   1150         mCallerPermissions.add(android.Manifest.permission.DUMP);
   1151         try {
   1152             final ByteArrayOutputStream out = new ByteArrayOutputStream();
   1153             final PrintWriter pw = new PrintWriter(out);
   1154             mService.dump(/* fd */ null, pw, args);
   1155             pw.close();
   1156 
   1157             return out.toString();
   1158         } finally {
   1159             mCallerPermissions.clear();
   1160             mCallerPermissions.addAll(origPermissions);
   1161         }
   1162     }
   1163 
   1164     /**
   1165      * For debugging, dump arbitrary file on logcat.
   1166      */
   1167     protected void dumpFileOnLogcat(String path) {
   1168         dumpFileOnLogcat(path, "");
   1169     }
   1170 
   1171     protected void dumpFileOnLogcat(String path, String message) {
   1172         if (!ENABLE_DUMP) return;
   1173 
   1174         Log.v(TAG, "Dumping file: " + path + " " + message);
   1175         final StringBuilder sb = new StringBuilder();
   1176         try (BufferedReader br = new BufferedReader(new FileReader(path))) {
   1177             String line;
   1178             while ((line = br.readLine()) != null) {
   1179                 Log.v(TAG, line);
   1180             }
   1181         } catch (Exception e) {
   1182             Log.e(TAG, "Couldn't read file", e);
   1183             fail("Exception " + e);
   1184         }
   1185     }
   1186 
   1187     /**
   1188      * For debugging, dump the main state file on logcat.
   1189      */
   1190     protected void dumpBaseStateFile() {
   1191         mService.saveDirtyInfo();
   1192         dumpFileOnLogcat(mInjectedFilePathRoot.getAbsolutePath()
   1193                 + "/system/" + ShortcutService.FILENAME_BASE_STATE);
   1194     }
   1195 
   1196     /**
   1197      * For debugging, dump per-user state file on logcat.
   1198      */
   1199     protected void dumpUserFile(int userId) {
   1200         dumpUserFile(userId, "");
   1201     }
   1202 
   1203     protected void dumpUserFile(int userId, String message) {
   1204         mService.saveDirtyInfo();
   1205         dumpFileOnLogcat(mInjectedFilePathRoot.getAbsolutePath()
   1206                 + "/user-" + userId
   1207                 + "/" + ShortcutService.FILENAME_USER_PACKAGES, message);
   1208     }
   1209 
   1210     /**
   1211      * Make a shortcut with an ID.
   1212      */
   1213     protected ShortcutInfo makeShortcut(String id) {
   1214         return makeShortcut(
   1215                 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
   1216                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1217     }
   1218 
   1219     protected ShortcutInfo makeShortcutWithTitle(String id, String title) {
   1220         return makeShortcut(
   1221                 id, title, /* activity =*/ null, /* icon =*/ null,
   1222                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1223     }
   1224 
   1225     /**
   1226      * Make a shortcut with an ID and timestamp.
   1227      */
   1228     protected ShortcutInfo makeShortcutWithTimestamp(String id, long timestamp) {
   1229         final ShortcutInfo s = makeShortcut(
   1230                 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
   1231                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1232         s.setTimestamp(timestamp);
   1233         return s;
   1234     }
   1235 
   1236     /**
   1237      * Make a shortcut with an ID, a timestamp and an activity component
   1238      */
   1239     protected ShortcutInfo makeShortcutWithTimestampWithActivity(String id, long timestamp,
   1240             ComponentName activity) {
   1241         final ShortcutInfo s = makeShortcut(
   1242                 id, "Title-" + id, activity, /* icon =*/ null,
   1243                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1244         s.setTimestamp(timestamp);
   1245         return s;
   1246     }
   1247 
   1248     /**
   1249      * Make a shortcut with an ID and icon.
   1250      */
   1251     protected ShortcutInfo makeShortcutWithIcon(String id, Icon icon) {
   1252         return makeShortcut(
   1253                 id, "Title-" + id, /* activity =*/ null, icon,
   1254                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1255     }
   1256 
   1257     protected ShortcutInfo makePackageShortcut(String packageName, String id) {
   1258         String origCaller = getCallingPackage();
   1259 
   1260         setCaller(packageName);
   1261         ShortcutInfo s = makeShortcut(
   1262                 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
   1263                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1264         setCaller(origCaller); // restore the caller
   1265 
   1266         return s;
   1267     }
   1268 
   1269     /**
   1270      * Make multiple shortcuts with IDs.
   1271      */
   1272     protected List<ShortcutInfo> makeShortcuts(String... ids) {
   1273         final ArrayList<ShortcutInfo> ret = new ArrayList();
   1274         for (String id : ids) {
   1275             ret.add(makeShortcut(id));
   1276         }
   1277         return ret;
   1278     }
   1279 
   1280     protected ShortcutInfo.Builder makeShortcutBuilder() {
   1281         return new ShortcutInfo.Builder(mClientContext);
   1282     }
   1283 
   1284     protected ShortcutInfo makeShortcutWithActivity(String id, ComponentName activity) {
   1285         return makeShortcut(
   1286                 id, "Title-" + id, activity, /* icon =*/ null,
   1287                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1288     }
   1289 
   1290     protected ShortcutInfo makeShortcutWithIntent(String id, Intent intent) {
   1291         return makeShortcut(
   1292                 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
   1293                 intent, /* rank =*/ 0);
   1294     }
   1295 
   1296     protected ShortcutInfo makeShortcutWithActivityAndTitle(String id, ComponentName activity,
   1297             String title) {
   1298         return makeShortcut(
   1299                 id, title, activity, /* icon =*/ null,
   1300                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
   1301     }
   1302 
   1303     protected ShortcutInfo makeShortcutWithActivityAndRank(String id, ComponentName activity,
   1304             int rank) {
   1305         return makeShortcut(
   1306                 id, "Title-" + id, activity, /* icon =*/ null,
   1307                 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), rank);
   1308     }
   1309 
   1310     /**
   1311      * Make a shortcut with details.
   1312      */
   1313     protected ShortcutInfo makeShortcut(String id, String title, ComponentName activity,
   1314             Icon icon, Intent intent, int rank) {
   1315         final ShortcutInfo.Builder  b = new ShortcutInfo.Builder(mClientContext, id)
   1316                 .setActivity(new ComponentName(mClientContext.getPackageName(), "dummy"))
   1317                 .setShortLabel(title)
   1318                 .setRank(rank)
   1319                 .setIntent(intent);
   1320         if (icon != null) {
   1321             b.setIcon(icon);
   1322         }
   1323         if (activity != null) {
   1324             b.setActivity(activity);
   1325         }
   1326         final ShortcutInfo s = b.build();
   1327 
   1328         s.setTimestamp(mInjectedCurrentTimeMillis); // HACK
   1329 
   1330         return s;
   1331     }
   1332 
   1333     protected ShortcutInfo makeShortcutWithIntents(String id, Intent... intents) {
   1334         return makeShortcut(
   1335                 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
   1336                 intents, /* rank =*/ 0);
   1337     }
   1338 
   1339     /**
   1340      * Make a shortcut with details.
   1341      */
   1342     protected ShortcutInfo makeShortcut(String id, String title, ComponentName activity,
   1343             Icon icon, Intent[] intents, int rank) {
   1344         final ShortcutInfo.Builder  b = new ShortcutInfo.Builder(mClientContext, id)
   1345                 .setActivity(new ComponentName(mClientContext.getPackageName(), "dummy"))
   1346                 .setShortLabel(title)
   1347                 .setRank(rank)
   1348                 .setIntents(intents);
   1349         if (icon != null) {
   1350             b.setIcon(icon);
   1351         }
   1352         if (activity != null) {
   1353             b.setActivity(activity);
   1354         }
   1355         final ShortcutInfo s = b.build();
   1356 
   1357         s.setTimestamp(mInjectedCurrentTimeMillis); // HACK
   1358 
   1359         return s;
   1360     }
   1361 
   1362     /**
   1363      * Make a shortcut with details.
   1364      */
   1365     protected ShortcutInfo makeShortcutWithExtras(String id, Intent intent,
   1366             PersistableBundle extras) {
   1367         final ShortcutInfo.Builder  b = new ShortcutInfo.Builder(mClientContext, id)
   1368                 .setActivity(new ComponentName(mClientContext.getPackageName(), "dummy"))
   1369                 .setShortLabel("title-" + id)
   1370                 .setExtras(extras)
   1371                 .setIntent(intent);
   1372         final ShortcutInfo s = b.build();
   1373 
   1374         s.setTimestamp(mInjectedCurrentTimeMillis); // HACK
   1375 
   1376         return s;
   1377     }
   1378 
   1379     /**
   1380      * Make an intent.
   1381      */
   1382     protected Intent makeIntent(String action, Class<?> clazz, Object... bundleKeysAndValues) {
   1383         final Intent intent = new Intent(action);
   1384         intent.setComponent(makeComponent(clazz));
   1385         intent.replaceExtras(makeBundle(bundleKeysAndValues));
   1386         return intent;
   1387     }
   1388 
   1389     /**
   1390      * Make an component name, with the client context.
   1391      */
   1392     @NonNull
   1393     protected ComponentName makeComponent(Class<?> clazz) {
   1394         return new ComponentName(mClientContext, clazz);
   1395     }
   1396 
   1397     @NonNull
   1398     protected ShortcutInfo findById(List<ShortcutInfo> list, String id) {
   1399         for (ShortcutInfo s : list) {
   1400             if (s.getId().equals(id)) {
   1401                 return s;
   1402             }
   1403         }
   1404         fail("Shortcut with id " + id + " not found");
   1405         return null;
   1406     }
   1407 
   1408     protected void assertSystem() {
   1409         assertEquals("Caller must be system", Process.SYSTEM_UID, mInjectedCallingUid);
   1410     }
   1411 
   1412     protected void assertResetTimes(long expectedLastResetTime, long expectedNextResetTime) {
   1413         assertEquals(expectedLastResetTime, mService.getLastResetTimeLocked());
   1414         assertEquals(expectedNextResetTime, mService.getNextResetTimeLocked());
   1415     }
   1416 
   1417     public static List<ShortcutInfo> assertAllNotHaveIcon(
   1418             List<ShortcutInfo> actualShortcuts) {
   1419         for (ShortcutInfo s : actualShortcuts) {
   1420             assertNull("ID " + s.getId(), s.getIcon());
   1421         }
   1422         return actualShortcuts;
   1423     }
   1424 
   1425     @NonNull
   1426     protected List<ShortcutInfo> assertAllHaveFlags(@NonNull List<ShortcutInfo> actualShortcuts,
   1427             int shortcutFlags) {
   1428         for (ShortcutInfo s : actualShortcuts) {
   1429             assertTrue("ID " + s.getId() + " doesn't have flags " + shortcutFlags,
   1430                     s.hasFlags(shortcutFlags));
   1431         }
   1432         return actualShortcuts;
   1433     }
   1434 
   1435     protected ShortcutInfo getPackageShortcut(String packageName, String shortcutId, int userId) {
   1436         return mService.getPackageShortcutForTest(packageName, shortcutId, userId);
   1437     }
   1438 
   1439     protected void assertShortcutExists(String packageName, String shortcutId, int userId) {
   1440         assertTrue(getPackageShortcut(packageName, shortcutId, userId) != null);
   1441     }
   1442 
   1443     protected void assertShortcutNotExists(String packageName, String shortcutId, int userId) {
   1444         assertTrue(getPackageShortcut(packageName, shortcutId, userId) == null);
   1445     }
   1446 
   1447     protected Intent[] launchShortcutAndGetIntentsInner(Runnable shortcutStarter,
   1448             @NonNull String packageName, @NonNull String shortcutId, int userId) {
   1449         reset(mMockActivityManagerInternal);
   1450         shortcutStarter.run();
   1451 
   1452         final ArgumentCaptor<Intent[]> intentsCaptor = ArgumentCaptor.forClass(Intent[].class);
   1453         verify(mMockActivityManagerInternal).startActivitiesAsPackage(
   1454                 eq(packageName),
   1455                 eq(userId),
   1456                 intentsCaptor.capture(),
   1457                 any(Bundle.class));
   1458         return intentsCaptor.getValue();
   1459     }
   1460 
   1461     protected Intent[] launchShortcutAndGetIntents(
   1462             @NonNull String packageName, @NonNull String shortcutId, int userId) {
   1463         return launchShortcutAndGetIntentsInner(
   1464                 () -> {
   1465                     mLauncherApps.startShortcut(packageName, shortcutId, null, null,
   1466                             UserHandle.of(userId));
   1467                 }, packageName, shortcutId, userId
   1468         );
   1469     }
   1470 
   1471     protected Intent launchShortcutAndGetIntent(
   1472             @NonNull String packageName, @NonNull String shortcutId, int userId) {
   1473         final Intent[] intents = launchShortcutAndGetIntents(packageName, shortcutId, userId);
   1474         assertEquals(1, intents.length);
   1475         return intents[0];
   1476     }
   1477 
   1478     protected Intent[] launchShortcutAndGetIntents_withShortcutInfo(
   1479             @NonNull String packageName, @NonNull String shortcutId, int userId) {
   1480         return launchShortcutAndGetIntentsInner(
   1481                 () -> {
   1482                     mLauncherApps.startShortcut(
   1483                             getShortcutInfoAsLauncher(packageName, shortcutId, userId), null, null);
   1484                 }, packageName, shortcutId, userId
   1485         );
   1486     }
   1487 
   1488     protected Intent launchShortcutAndGetIntent_withShortcutInfo(
   1489             @NonNull String packageName, @NonNull String shortcutId, int userId) {
   1490         final Intent[] intents = launchShortcutAndGetIntents_withShortcutInfo(
   1491                 packageName, shortcutId, userId);
   1492         assertEquals(1, intents.length);
   1493         return intents[0];
   1494     }
   1495 
   1496     protected void assertShortcutLaunchable(@NonNull String packageName, @NonNull String shortcutId,
   1497             int userId) {
   1498         assertNotNull(launchShortcutAndGetIntent(packageName, shortcutId, userId));
   1499         assertNotNull(launchShortcutAndGetIntent_withShortcutInfo(packageName, shortcutId, userId));
   1500     }
   1501 
   1502     protected void assertShortcutNotLaunched(@NonNull String packageName,
   1503             @NonNull String shortcutId, int userId) {
   1504         reset(mMockActivityManagerInternal);
   1505         try {
   1506             mLauncherApps.startShortcut(packageName, shortcutId, null, null,
   1507                     UserHandle.of(userId));
   1508             fail("ActivityNotFoundException was not thrown");
   1509         } catch (ActivityNotFoundException expected) {
   1510         }
   1511         // This shouldn't have been called.
   1512         verify(mMockActivityManagerInternal, times(0)).startActivitiesAsPackage(
   1513                 anyString(),
   1514                 anyInt(),
   1515                 any(Intent[].class),
   1516                 any(Bundle.class));
   1517     }
   1518 
   1519     protected void assertStartShortcutThrowsException(@NonNull String packageName,
   1520             @NonNull String shortcutId, int userId, Class<?> expectedException) {
   1521         Exception thrown = null;
   1522         try {
   1523             mLauncherApps.startShortcut(packageName, shortcutId, null, null,
   1524                     UserHandle.of(userId));
   1525         } catch (Exception e) {
   1526             thrown = e;
   1527         }
   1528         assertNotNull("Exception was not thrown", thrown);
   1529         assertEquals("Exception type different", expectedException, thrown.getClass());
   1530     }
   1531 
   1532     protected void assertBitmapDirectories(int userId, String... expectedDirectories) {
   1533         final Set<String> expected = hashSet(set(expectedDirectories));
   1534 
   1535         final Set<String> actual = new HashSet<>();
   1536 
   1537         final File[] files = mService.getUserBitmapFilePath(userId).listFiles();
   1538         if (files != null) {
   1539             for (File child : files) {
   1540                 if (child.isDirectory()) {
   1541                     actual.add(child.getName());
   1542                 }
   1543             }
   1544         }
   1545 
   1546         assertEquals(expected, actual);
   1547     }
   1548 
   1549     protected void assertBitmapFiles(int userId, String packageName, String... expectedFiles) {
   1550         final Set<String> expected = hashSet(set(expectedFiles));
   1551 
   1552         final Set<String> actual = new HashSet<>();
   1553 
   1554         final File[] files = new File(mService.getUserBitmapFilePath(userId), packageName)
   1555                 .listFiles();
   1556         if (files != null) {
   1557             for (File child : files) {
   1558                 if (child.isFile()) {
   1559                     actual.add(child.getName());
   1560                 }
   1561             }
   1562         }
   1563 
   1564         assertEquals(expected, actual);
   1565     }
   1566 
   1567     protected String getBitmapFilename(int userId, String packageName, String shortcutId) {
   1568         final ShortcutInfo si = mService.getPackageShortcutForTest(packageName, shortcutId, userId);
   1569         if (si == null) {
   1570             return null;
   1571         }
   1572         return new File(si.getBitmapPath()).getName();
   1573     }
   1574 
   1575     /**
   1576      * @return all shortcuts stored internally for the caller.  This reflects the *internal* view
   1577      * of shortcuts, which may be different from what {@link #getCallerVisibleShortcuts} would
   1578      * return, because getCallerVisibleShortcuts() will get shortcuts from the proper "front door"
   1579      * which performs some extra checks, like {@link ShortcutPackage#onRestored}.
   1580      */
   1581     protected List<ShortcutInfo> getCallerShortcuts() {
   1582         final ShortcutPackage p = mService.getPackageShortcutForTest(
   1583                 getCallingPackage(), getCallingUserId());
   1584         return p == null ? null : p.getAllShortcutsForTest();
   1585     }
   1586 
   1587     /**
   1588      * @return all shortcuts owned by caller that are actually visible via ShortcutManager.
   1589      * See also {@link #getCallerShortcuts}.
   1590      */
   1591     protected List<ShortcutInfo> getCallerVisibleShortcuts() {
   1592         final ArrayList<ShortcutInfo> ret = new ArrayList<>();
   1593         ret.addAll(mManager.getDynamicShortcuts());
   1594         ret.addAll(mManager.getPinnedShortcuts());
   1595         ret.addAll(mManager.getManifestShortcuts());
   1596         return ret;
   1597     }
   1598 
   1599     protected ShortcutInfo getCallerShortcut(String shortcutId) {
   1600         return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId());
   1601     }
   1602 
   1603     protected List<ShortcutInfo> getLauncherShortcuts(String launcher, int userId, int queryFlags) {
   1604         final List<ShortcutInfo>[] ret = new List[1];
   1605         runWithCaller(launcher, userId, () -> {
   1606             final ShortcutQuery q = new ShortcutQuery();
   1607             q.setQueryFlags(queryFlags);
   1608             ret[0] = mLauncherApps.getShortcuts(q, UserHandle.of(userId));
   1609         });
   1610         return ret[0];
   1611     }
   1612 
   1613     protected List<ShortcutInfo> getLauncherPinnedShortcuts(String launcher, int userId) {
   1614         return getLauncherShortcuts(launcher, userId, ShortcutQuery.FLAG_GET_PINNED);
   1615     }
   1616 
   1617     protected ShortcutInfo getShortcutInfoAsLauncher(String packageName, String shortcutId,
   1618             int userId) {
   1619         final List<ShortcutInfo> infoList =
   1620                 mLauncherApps.getShortcutInfo(packageName, list(shortcutId),
   1621                         UserHandle.of(userId));
   1622         assertEquals("No shortcutInfo found (or too many of them)", 1, infoList.size());
   1623         return infoList.get(0);
   1624     }
   1625 
   1626     protected Intent genPackageAddIntent(String packageName, int userId) {
   1627         installPackage(userId, packageName);
   1628 
   1629         Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
   1630         i.setData(Uri.parse("package:" + packageName));
   1631         i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   1632         return i;
   1633     }
   1634 
   1635     protected Intent genPackageDeleteIntent(String pakcageName, int userId) {
   1636         uninstallPackage(userId, pakcageName);
   1637 
   1638         Intent i = new Intent(Intent.ACTION_PACKAGE_REMOVED);
   1639         i.setData(Uri.parse("package:" + pakcageName));
   1640         i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   1641         return i;
   1642     }
   1643 
   1644     protected Intent genPackageUpdateIntent(String pakcageName, int userId) {
   1645         installPackage(userId, pakcageName);
   1646 
   1647         Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
   1648         i.setData(Uri.parse("package:" + pakcageName));
   1649         i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   1650         i.putExtra(Intent.EXTRA_REPLACING, true);
   1651         return i;
   1652     }
   1653 
   1654     protected Intent genPackageChangedIntent(String pakcageName, int userId) {
   1655         Intent i = new Intent(Intent.ACTION_PACKAGE_CHANGED);
   1656         i.setData(Uri.parse("package:" + pakcageName));
   1657         i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   1658         return i;
   1659     }
   1660 
   1661     protected Intent genPackageDataClear(String packageName, int userId) {
   1662         Intent i = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED);
   1663         i.setData(Uri.parse("package:" + packageName));
   1664         i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   1665         return i;
   1666     }
   1667 
   1668     protected void assertExistsAndShadow(ShortcutPackageItem spi) {
   1669         assertNotNull(spi);
   1670         assertTrue(spi.getPackageInfo().isShadow());
   1671     }
   1672 
   1673     protected File makeFile(File baseDirectory, String... paths) {
   1674         File ret = baseDirectory;
   1675 
   1676         for (String path : paths) {
   1677             ret = new File(ret, path);
   1678         }
   1679 
   1680         return ret;
   1681     }
   1682 
   1683     protected boolean bitmapDirectoryExists(String packageName, int userId) {
   1684         final File path = new File(mService.getUserBitmapFilePath(userId), packageName);
   1685         return path.isDirectory();
   1686     }
   1687     protected static ShortcutQuery buildQuery(long changedSince,
   1688             String packageName, ComponentName componentName,
   1689             /* @ShortcutQuery.QueryFlags */ int flags) {
   1690         return buildQuery(changedSince, packageName, null, componentName, flags);
   1691     }
   1692 
   1693     protected static ShortcutQuery buildQuery(long changedSince,
   1694             String packageName, List<String> shortcutIds, ComponentName componentName,
   1695             /* @ShortcutQuery.QueryFlags */ int flags) {
   1696         final ShortcutQuery q = new ShortcutQuery();
   1697         q.setChangedSince(changedSince);
   1698         q.setPackage(packageName);
   1699         q.setShortcutIds(shortcutIds);
   1700         q.setActivity(componentName);
   1701         q.setQueryFlags(flags);
   1702         return q;
   1703     }
   1704 
   1705     protected static ShortcutQuery buildAllQuery(String packageName) {
   1706         final ShortcutQuery q = new ShortcutQuery();
   1707         q.setPackage(packageName);
   1708         q.setQueryFlags(ShortcutQuery.FLAG_GET_ALL_KINDS);
   1709         return q;
   1710     }
   1711 
   1712     protected static ShortcutQuery buildPinnedQuery(String packageName) {
   1713         final ShortcutQuery q = new ShortcutQuery();
   1714         q.setPackage(packageName);
   1715         q.setQueryFlags(ShortcutQuery.FLAG_GET_PINNED);
   1716         return q;
   1717     }
   1718 
   1719     protected static ShortcutQuery buildQueryWithFlags(int queryFlags) {
   1720         final ShortcutQuery q = new ShortcutQuery();
   1721         q.setQueryFlags(queryFlags);
   1722         return q;
   1723     }
   1724 
   1725     protected void backupAndRestore() {
   1726         int prevUid = mInjectedCallingUid;
   1727 
   1728         mInjectedCallingUid = Process.SYSTEM_UID; // Only system can call it.
   1729 
   1730         dumpsysOnLogcat("Before backup");
   1731 
   1732         final byte[] payload =  mService.getBackupPayload(USER_0);
   1733         if (ENABLE_DUMP) {
   1734             final String xml = new String(payload);
   1735             Log.v(TAG, "Backup payload:");
   1736             for (String line : xml.split("\n")) {
   1737                 Log.v(TAG, line);
   1738             }
   1739         }
   1740 
   1741         // Before doing anything else, uninstall all packages.
   1742         for (int userId : list(USER_0, USER_P0)) {
   1743             for (String pkg : list(CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
   1744                     LAUNCHER_1, LAUNCHER_2, LAUNCHER_3)) {
   1745                 uninstallPackage(userId, pkg);
   1746             }
   1747         }
   1748 
   1749         shutdownServices();
   1750 
   1751         deleteAllSavedFiles();
   1752 
   1753         initService();
   1754         mService.applyRestore(payload, USER_0);
   1755 
   1756         // handleUnlockUser will perform the gone package check, but it shouldn't remove
   1757         // shadow information.
   1758         mService.handleUnlockUser(USER_0);
   1759 
   1760         dumpsysOnLogcat("After restore");
   1761 
   1762         mInjectedCallingUid = prevUid;
   1763     }
   1764 
   1765     protected void prepareCrossProfileDataSet() {
   1766         mRunningUsers.put(USER_10, true); // this test needs user 10.
   1767 
   1768         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
   1769             assertTrue(mManager.setDynamicShortcuts(list(
   1770                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
   1771                     makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
   1772         });
   1773         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
   1774             assertTrue(mManager.setDynamicShortcuts(list(
   1775                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
   1776                     makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
   1777         });
   1778         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
   1779             assertTrue(mManager.setDynamicShortcuts(list(
   1780                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
   1781                     makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
   1782         });
   1783         runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
   1784             assertTrue(mManager.setDynamicShortcuts(list()));
   1785         });
   1786         runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
   1787             assertTrue(mManager.setDynamicShortcuts(list(
   1788                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
   1789                     makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
   1790         });
   1791         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
   1792             assertTrue(mManager.setDynamicShortcuts(list(
   1793                     makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"),
   1794                     makeShortcut("x4"), makeShortcut("x5"), makeShortcut("x6"))));
   1795         });
   1796 
   1797         runWithCaller(LAUNCHER_1, USER_0, () -> {
   1798             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
   1799             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s1", "s2"), HANDLE_USER_0);
   1800             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s1", "s2", "s3"), HANDLE_USER_0);
   1801 
   1802             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s4"), HANDLE_USER_P0);
   1803         });
   1804         runWithCaller(LAUNCHER_2, USER_0, () -> {
   1805             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
   1806             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s2", "s3"), HANDLE_USER_0);
   1807             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s2", "s3", "s4"), HANDLE_USER_0);
   1808 
   1809             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s5"), HANDLE_USER_P0);
   1810         });
   1811 
   1812         // Note LAUNCHER_3 has allowBackup=false.
   1813         runWithCaller(LAUNCHER_3, USER_0, () -> {
   1814             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
   1815             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4"), HANDLE_USER_0);
   1816             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5"), HANDLE_USER_0);
   1817 
   1818             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s6"), HANDLE_USER_P0);
   1819         });
   1820         runWithCaller(LAUNCHER_4, USER_0, () -> {
   1821             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), HANDLE_USER_0);
   1822             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), HANDLE_USER_0);
   1823             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list(), HANDLE_USER_0);
   1824             mLauncherApps.pinShortcuts(CALLING_PACKAGE_4, list(), HANDLE_USER_0);
   1825         });
   1826 
   1827         // Launcher on a managed profile is referring ot user 0!
   1828         runWithCaller(LAUNCHER_1, USER_P0, () -> {
   1829             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s4"), HANDLE_USER_0);
   1830             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4", "s5"), HANDLE_USER_0);
   1831             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5", "s6"),
   1832                     HANDLE_USER_0);
   1833 
   1834             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s4", "s1"), HANDLE_USER_P0);
   1835         });
   1836         runWithCaller(LAUNCHER_1, USER_10, () -> {
   1837             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("x4", "x5"), HANDLE_USER_10);
   1838             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("x4", "x5", "x6"), HANDLE_USER_10);
   1839             mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("x4", "x5", "x6", "x1"),
   1840                     HANDLE_USER_10);
   1841         });
   1842 
   1843         // Then remove some dynamic shortcuts.
   1844         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
   1845             assertTrue(mManager.setDynamicShortcuts(list(
   1846                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
   1847         });
   1848         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
   1849             assertTrue(mManager.setDynamicShortcuts(list(
   1850                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
   1851         });
   1852         runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
   1853             assertTrue(mManager.setDynamicShortcuts(list(
   1854                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
   1855         });
   1856         runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
   1857             assertTrue(mManager.setDynamicShortcuts(list()));
   1858         });
   1859         runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
   1860             assertTrue(mManager.setDynamicShortcuts(list(
   1861                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
   1862         });
   1863         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
   1864             assertTrue(mManager.setDynamicShortcuts(list(
   1865                     makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"))));
   1866         });
   1867     }
   1868 
   1869     public static List<ShortcutInfo> assertAllHaveIconResId(
   1870             List<ShortcutInfo> actualShortcuts) {
   1871         for (ShortcutInfo s : actualShortcuts) {
   1872             assertTrue("ID " + s.getId() + " not have icon res ID", s.hasIconResource());
   1873             assertFalse("ID " + s.getId() + " shouldn't have icon FD", s.hasIconFile());
   1874         }
   1875         return actualShortcuts;
   1876     }
   1877 
   1878     public static List<ShortcutInfo> assertAllHaveIconFile(
   1879             List<ShortcutInfo> actualShortcuts) {
   1880         for (ShortcutInfo s : actualShortcuts) {
   1881             assertFalse("ID " + s.getId() + " shouldn't have icon res ID", s.hasIconResource());
   1882             assertTrue("ID " + s.getId() + " not have icon FD", s.hasIconFile());
   1883         }
   1884         return actualShortcuts;
   1885     }
   1886 
   1887     public static List<ShortcutInfo> assertAllHaveIcon(
   1888             List<ShortcutInfo> actualShortcuts) {
   1889         for (ShortcutInfo s : actualShortcuts) {
   1890             assertTrue("ID " + s.getId() + " has no icon ", s.hasIconFile() || s.hasIconResource());
   1891         }
   1892         return actualShortcuts;
   1893     }
   1894 
   1895     public static List<ShortcutInfo> assertAllStringsResolved(
   1896             List<ShortcutInfo> actualShortcuts) {
   1897         for (ShortcutInfo s : actualShortcuts) {
   1898             assertTrue("ID " + s.getId(), s.hasStringResourcesResolved());
   1899         }
   1900         return actualShortcuts;
   1901     }
   1902 
   1903     public String readTestAsset(String assetPath) throws IOException {
   1904         final StringBuilder sb = new StringBuilder();
   1905         try (BufferedReader br = new BufferedReader(
   1906                 new InputStreamReader(
   1907                         getTestContext().getResources().getAssets().open(assetPath)))) {
   1908             String line;
   1909             while ((line = br.readLine()) != null) {
   1910                 sb.append(line);
   1911                 sb.append(System.lineSeparator());
   1912             }
   1913         }
   1914         return sb.toString();
   1915     }
   1916 
   1917     protected void prepareGetHomeActivitiesAsUser(ComponentName preferred,
   1918             List<ResolveInfo> candidates, int userId) {
   1919         doAnswer(inv -> {
   1920             ((List) inv.getArguments()[0]).addAll(candidates);
   1921             return preferred;
   1922         }).when(mMockPackageManagerInternal).getHomeActivitiesAsUser(any(List.class), eq(userId));
   1923     }
   1924 
   1925     protected static ComponentName cn(String packageName, String name) {
   1926         return new ComponentName(packageName, name);
   1927     }
   1928 
   1929     protected static ResolveInfo ri(String packageName, String name, boolean isSystem, int priority) {
   1930         final ResolveInfo ri = new ResolveInfo();
   1931         ri.activityInfo = new ActivityInfo();
   1932         ri.activityInfo.applicationInfo = new ApplicationInfo();
   1933 
   1934         ri.activityInfo.packageName = packageName;
   1935         ri.activityInfo.name = name;
   1936         if (isSystem) {
   1937             ri.activityInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   1938         }
   1939         ri.priority = priority;
   1940         return ri;
   1941     }
   1942 
   1943     protected static ResolveInfo getSystemLauncher() {
   1944         return ri(PACKAGE_SYSTEM_LAUNCHER, PACKAGE_SYSTEM_LAUNCHER_NAME, true,
   1945                 PACKAGE_SYSTEM_LAUNCHER_PRIORITY);
   1946     }
   1947 
   1948     protected static ResolveInfo getFallbackLauncher() {
   1949         return ri(PACKAGE_FALLBACK_LAUNCHER, PACKAGE_FALLBACK_LAUNCHER_NAME, true,
   1950                 PACKAGE_FALLBACK_LAUNCHER_PRIORITY);
   1951     }
   1952 }
   1953