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