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 android.content.pm.cts.shortcutmanager; 17 18 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*; 19 20 import android.app.Activity; 21 import android.app.ActivityManager; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.ContextWrapper; 25 import android.content.Intent; 26 import android.content.LocusId; 27 import android.content.pm.LauncherApps; 28 import android.content.pm.LauncherApps.ShortcutQuery; 29 import android.content.pm.PackageManager; 30 import android.content.pm.ShortcutInfo; 31 import android.content.pm.ShortcutManager; 32 import android.content.res.Resources; 33 import android.graphics.drawable.AdaptiveIconDrawable; 34 import android.graphics.drawable.Drawable; 35 import android.graphics.drawable.Icon; 36 import android.os.Bundle; 37 import android.os.PersistableBundle; 38 import android.os.StrictMode; 39 import android.os.StrictMode.ThreadPolicy; 40 import android.os.UserHandle; 41 import android.provider.DeviceConfig; 42 import android.test.InstrumentationTestCase; 43 import android.text.TextUtils; 44 45 import androidx.annotation.NonNull; 46 47 import com.android.compatibility.common.util.SystemUtil; 48 49 import java.util.ArrayList; 50 import java.util.HashMap; 51 import java.util.List; 52 import java.util.Map; 53 import java.util.concurrent.atomic.AtomicReference; 54 55 public abstract class ShortcutManagerCtsTestsBase extends InstrumentationTestCase { 56 protected static final String TAG = "ShortcutCTS"; 57 58 private static final boolean DUMPSYS_IN_TEARDOWN = false; // DO NOT SUBMIT WITH true 59 60 /** 61 * Whether to enable strict mode or not. 62 * 63 * TODO Enable it after fixing b/68051728. Somehow violations would happen on the dashboard 64 * only and can't reproduce it locally. 65 */ 66 private static final boolean ENABLE_STRICT_MODE = false; 67 68 private static class SpoofingContext extends ContextWrapper { 69 private final String mPackageName; 70 SpoofingContext(Context base, String packageName)71 public SpoofingContext(Context base, String packageName) { 72 super(base); 73 mPackageName = packageName; 74 } 75 76 @Override getPackageName()77 public String getPackageName() { 78 return mPackageName; 79 } 80 } 81 82 private Context mCurrentCallerPackage; 83 private int mUserId; 84 private UserHandle mUserHandle; 85 86 private String mOriginalLauncher; 87 88 protected Context mPackageContext1; 89 protected Context mPackageContext2; 90 protected Context mPackageContext3; 91 protected Context mPackageContext4; 92 93 protected Context mLauncherContext1; 94 protected Context mLauncherContext2; 95 protected Context mLauncherContext3; 96 protected Context mLauncherContext4; 97 98 private LauncherApps mLauncherApps1; 99 private LauncherApps mLauncherApps2; 100 private LauncherApps mLauncherApps3; 101 private LauncherApps mLauncherApps4; 102 103 private Map<Context, ShortcutManager> mManagers = new HashMap<>(); 104 private Map<Context, LauncherApps> mLauncherAppses = new HashMap<>(); 105 106 private ShortcutManager mCurrentManager; 107 private LauncherApps mCurrentLauncherApps; 108 109 private static final String[] ACTIVITIES_WITH_MANIFEST_SHORTCUTS = { 110 "Launcher_manifest_1", 111 "Launcher_manifest_2", 112 "Launcher_manifest_3", 113 "Launcher_manifest_4a", 114 "Launcher_manifest_4b", 115 "Launcher_manifest_error_1", 116 "Launcher_manifest_error_2", 117 "Launcher_manifest_error_3" 118 }; 119 120 private ComponentName mTargetActivityOverride; 121 122 private static class ShortcutActivity extends Activity { 123 } 124 125 @Override setUp()126 protected void setUp() throws Exception { 127 super.setUp(); 128 129 mUserId = getTestContext().getUserId(); 130 mUserHandle = android.os.Process.myUserHandle(); 131 132 resetConfig(getInstrumentation()); 133 final String config = getOverrideConfig(); 134 if (config != null) { 135 overrideConfig(getInstrumentation(), config); 136 } 137 mOriginalLauncher = getDefaultLauncher(getInstrumentation()); 138 139 mPackageContext1 = new SpoofingContext(getTestContext(), 140 "android.content.pm.cts.shortcutmanager.packages.package1"); 141 mPackageContext2 = new SpoofingContext(getTestContext(), 142 "android.content.pm.cts.shortcutmanager.packages.package2"); 143 mPackageContext3 = new SpoofingContext(getTestContext(), 144 "android.content.pm.cts.shortcutmanager.packages.package3"); 145 mPackageContext4 = new SpoofingContext(getTestContext(), 146 "android.content.pm.cts.shortcutmanager.packages.package4"); 147 mLauncherContext1 = new SpoofingContext(getTestContext(), 148 "android.content.pm.cts.shortcutmanager.packages.launcher1"); 149 mLauncherContext2 = new SpoofingContext(getTestContext(), 150 "android.content.pm.cts.shortcutmanager.packages.launcher2"); 151 mLauncherContext3 = new SpoofingContext(getTestContext(), 152 "android.content.pm.cts.shortcutmanager.packages.launcher3"); 153 mLauncherContext4 = new SpoofingContext(getTestContext(), 154 "android.content.pm.cts.shortcutmanager.packages.launcher4"); 155 156 mLauncherApps1 = new LauncherApps(mLauncherContext1); 157 mLauncherApps2 = new LauncherApps(mLauncherContext2); 158 mLauncherApps3 = new LauncherApps(mLauncherContext3); 159 mLauncherApps4 = new LauncherApps(mLauncherContext4); 160 161 clearShortcuts(getInstrumentation(), mUserId, mPackageContext1.getPackageName()); 162 clearShortcuts(getInstrumentation(), mUserId, mPackageContext2.getPackageName()); 163 clearShortcuts(getInstrumentation(), mUserId, mPackageContext3.getPackageName()); 164 clearShortcuts(getInstrumentation(), mUserId, mPackageContext4.getPackageName()); 165 166 setCurrentCaller(mPackageContext1); 167 168 // Make sure shortcuts are removed. 169 withCallers(getAllPublishers(), () -> { 170 // Clear all shortcuts. 171 clearShortcuts(getInstrumentation(), mUserId, getCurrentCallingPackage()); 172 173 disableActivitiesWithManifestShortucts(); 174 175 assertEquals("for " + getCurrentCallingPackage(), 176 0, getManager().getDynamicShortcuts().size()); 177 assertEquals("for " + getCurrentCallingPackage(), 178 0, getManager().getPinnedShortcuts().size()); 179 assertEquals("for " + getCurrentCallingPackage(), 180 0, getManager().getManifestShortcuts().size()); 181 }); 182 } 183 184 @Override tearDown()185 protected void tearDown() throws Exception { 186 if (DUMPSYS_IN_TEARDOWN) { 187 dumpsysShortcut(getInstrumentation()); 188 } 189 190 withCallers(getAllPublishers(), () -> disableActivitiesWithManifestShortucts()); 191 192 resetConfig(getInstrumentation()); 193 194 if (!TextUtils.isEmpty(mOriginalLauncher)) { 195 setDefaultLauncher(getInstrumentation(), mOriginalLauncher); 196 } 197 198 super.tearDown(); 199 } 200 getTestContext()201 protected Context getTestContext() { 202 return getInstrumentation().getContext(); 203 } 204 getUserHandle()205 protected UserHandle getUserHandle() { 206 return mUserHandle; 207 } 208 getAllPublishers()209 protected List<Context> getAllPublishers() { 210 // 4 has a different signature, so we can't call for it. 211 return list(mPackageContext1, mPackageContext2, mPackageContext3); 212 } 213 getAllLaunchers()214 protected List<Context> getAllLaunchers() { 215 // 4 has a different signature, so we can't call for it. 216 return list(mLauncherContext1, mLauncherContext2, mLauncherContext3); 217 } 218 getAllCallers()219 protected List<Context> getAllCallers() { 220 return list( 221 mPackageContext1, mPackageContext2, mPackageContext3, mPackageContext4, 222 mLauncherContext1, mLauncherContext2, mLauncherContext3, mLauncherContext4); 223 } 224 getActivity(String className)225 protected ComponentName getActivity(String className) { 226 return new ComponentName(getCurrentCallingPackage(), 227 "android.content.pm.cts.shortcutmanager.packages." + className); 228 229 } 230 disableActivitiesWithManifestShortucts()231 protected void disableActivitiesWithManifestShortucts() { 232 if (getManager().getManifestShortcuts().size() > 0) { 233 // Disable DISABLED_ACTIVITIES 234 for (String className : ACTIVITIES_WITH_MANIFEST_SHORTCUTS) { 235 enableManifestActivity(className, false); 236 } 237 } 238 } 239 enableManifestActivity(String className, boolean enabled)240 protected void enableManifestActivity(String className, boolean enabled) { 241 getTestContext().getPackageManager().setComponentEnabledSetting(getActivity(className), 242 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 243 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 244 PackageManager.DONT_KILL_APP); 245 } 246 setTargetActivityOverride(String className)247 protected void setTargetActivityOverride(String className) { 248 mTargetActivityOverride = getActivity(className); 249 } 250 251 withCallers(List<Context> callers, Runnable r)252 protected void withCallers(List<Context> callers, Runnable r) { 253 for (Context c : callers) { 254 runWithCaller(c, r); 255 } 256 } 257 getOverrideConfig()258 protected String getOverrideConfig() { 259 return null; 260 } 261 setCurrentCaller(Context callerContext)262 protected void setCurrentCaller(Context callerContext) { 263 mCurrentCallerPackage = callerContext; 264 265 if (!mManagers.containsKey(mCurrentCallerPackage)) { 266 mManagers.put(mCurrentCallerPackage, new ShortcutManager(mCurrentCallerPackage)); 267 } 268 mCurrentManager = mManagers.get(mCurrentCallerPackage); 269 270 if (!mLauncherAppses.containsKey(mCurrentCallerPackage)) { 271 mLauncherAppses.put(mCurrentCallerPackage, new LauncherApps(mCurrentCallerPackage)); 272 } 273 mCurrentLauncherApps = mLauncherAppses.get(mCurrentCallerPackage); 274 275 mTargetActivityOverride = null; 276 } 277 getCurrentCallerContext()278 protected Context getCurrentCallerContext() { 279 return mCurrentCallerPackage; 280 } 281 getCurrentCallingPackage()282 protected String getCurrentCallingPackage() { 283 return getCurrentCallerContext().getPackageName(); 284 } 285 getManager()286 protected ShortcutManager getManager() { 287 return mCurrentManager; 288 } 289 getLauncherApps()290 protected LauncherApps getLauncherApps() { 291 return mCurrentLauncherApps; 292 } 293 runWithStrictMode(Runnable r)294 protected void runWithStrictMode(Runnable r) { 295 final ThreadPolicy oldPolicy = StrictMode.getThreadPolicy(); 296 try { 297 if (ENABLE_STRICT_MODE) { 298 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 299 .detectAll() 300 .penaltyDeath() 301 .build()); 302 } 303 r.run(); 304 } finally { 305 StrictMode.setThreadPolicy(oldPolicy); 306 } 307 } 308 runWithNoStrictMode(Runnable r)309 protected void runWithNoStrictMode(Runnable r) { 310 final ThreadPolicy oldPolicy = StrictMode.getThreadPolicy(); 311 try { 312 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 313 .permitAll() 314 .build()); 315 r.run(); 316 } finally { 317 StrictMode.setThreadPolicy(oldPolicy); 318 } 319 } 320 runWithCaller(Context callerContext, Runnable r)321 protected void runWithCaller(Context callerContext, Runnable r) { 322 final Context prev = mCurrentCallerPackage; 323 324 setCurrentCaller(callerContext); 325 326 r.run(); 327 328 setCurrentCaller(prev); 329 } 330 runWithCallerWithStrictMode(Context callerContext, Runnable r)331 protected void runWithCallerWithStrictMode(Context callerContext, Runnable r) { 332 runWithCaller(callerContext, () -> runWithStrictMode(r)); 333 } 334 runWithCallerWithNoStrictMode(Context callerContext, Runnable r)335 protected void runWithCallerWithNoStrictMode(Context callerContext, Runnable r) { 336 runWithCaller(callerContext, () -> runWithNoStrictMode(r)); 337 } 338 makeBundle(Object... keysAndValues)339 public static Bundle makeBundle(Object... keysAndValues) { 340 assertTrue((keysAndValues.length % 2) == 0); 341 342 if (keysAndValues.length == 0) { 343 return null; 344 } 345 final Bundle ret = new Bundle(); 346 347 for (int i = keysAndValues.length - 2; i >= 0; i -= 2) { 348 final String key = keysAndValues[i].toString(); 349 final Object value = keysAndValues[i + 1]; 350 351 if (value == null) { 352 ret.putString(key, null); 353 } else if (value instanceof Integer) { 354 ret.putInt(key, (Integer) value); 355 } else if (value instanceof String) { 356 ret.putString(key, (String) value); 357 } else if (value instanceof Bundle) { 358 ret.putBundle(key, (Bundle) value); 359 } else { 360 fail("Type not supported yet: " + value.getClass().getName()); 361 } 362 } 363 return ret; 364 } 365 makePersistableBundle(Object... keysAndValues)366 public static PersistableBundle makePersistableBundle(Object... keysAndValues) { 367 assertTrue((keysAndValues.length % 2) == 0); 368 369 if (keysAndValues.length == 0) { 370 return null; 371 } 372 final PersistableBundle ret = new PersistableBundle(); 373 374 for (int i = keysAndValues.length - 2; i >= 0; i -= 2) { 375 final String key = keysAndValues[i].toString(); 376 final Object value = keysAndValues[i + 1]; 377 378 if (value == null) { 379 ret.putString(key, null); 380 } else if (value instanceof Integer) { 381 ret.putInt(key, (Integer) value); 382 } else if (value instanceof String) { 383 ret.putString(key, (String) value); 384 } else if (value instanceof PersistableBundle) { 385 ret.putPersistableBundle(key, (PersistableBundle) value); 386 } else { 387 fail("Type not supported yet: " + value.getClass().getName()); 388 } 389 } 390 return ret; 391 } 392 393 /** 394 * Make a shortcut with an ID. 395 */ makeShortcut(String id)396 protected ShortcutInfo makeShortcut(String id) { 397 return makeShortcut(id, "Title-" + id); 398 } 399 400 /** 401 * Make a shortcut with an ID and explicit rank. 402 */ makeShortcutWithRank(String id, int rank)403 protected ShortcutInfo makeShortcutWithRank(String id, int rank) { 404 return makeShortcut( 405 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null, 406 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), rank, /* locusId =*/ null, 407 /* longLived =*/ false); 408 } 409 410 /** 411 * Make a shortcut with an ID and a locus ID. 412 */ makeShortcutWithLocusId(String id, String locusId)413 protected ShortcutInfo makeShortcutWithLocusId(String id, String locusId) { 414 return makeShortcut( 415 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null, 416 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0, 417 new LocusId(locusId), /* longLived =*/ false); 418 } 419 420 /** 421 * Make a shortcut with an ID and a title. 422 */ makeShortcut(String id, String shortLabel)423 protected ShortcutInfo makeShortcut(String id, String shortLabel) { 424 return makeShortcut( 425 id, shortLabel, /* activity =*/ null, /* icon =*/ null, 426 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0, 427 /* locusId =*/ null, /* longLived =*/ false); 428 } 429 makeShortcut(String id, ComponentName activity)430 protected ShortcutInfo makeShortcut(String id, ComponentName activity) { 431 return makeShortcut( 432 id, "Title-" + id, activity, /* icon =*/ null, 433 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0, 434 /* locusId =*/ null, /* longLived =*/ false); 435 } 436 437 /** 438 * Make a shortcut with an ID and icon. 439 */ makeShortcutWithIcon(String id, Icon icon)440 protected ShortcutInfo makeShortcutWithIcon(String id, Icon icon) { 441 return makeShortcut( 442 id, "Title-" + id, /* activity =*/ null, icon, 443 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0, 444 /* locusId =*/ null, /* longLived =*/ false); 445 } 446 447 /** 448 * Make a long-lived shortcut with an ID. 449 */ makeLongLivedShortcut(String id)450 protected ShortcutInfo makeLongLivedShortcut(String id) { 451 return makeShortcut( 452 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null, 453 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0, 454 /* locusId =*/ null, /* longLived =*/ true); 455 } 456 457 /** 458 * Make a shortcut excluded from launcher with an ID. 459 */ makeShortcutExcludedFromLauncher(String id)460 protected ShortcutInfo makeShortcutExcludedFromLauncher(String id) { 461 return makeShortcut( 462 id, "Title-" + id, /* activity =*/ null, /* icon =*/ null, 463 makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0, 464 /* locusId =*/ null, /* longLived =*/ true, 465 /* excludedSurfaces */ ShortcutInfo.SURFACE_LAUNCHER); 466 } 467 468 /** 469 * Make multiple shortcuts with IDs. 470 */ makeShortcuts(String... ids)471 protected List<ShortcutInfo> makeShortcuts(String... ids) { 472 final ArrayList<ShortcutInfo> ret = new ArrayList(); 473 for (String id : ids) { 474 ret.add(makeShortcut(id)); 475 } 476 return ret; 477 } 478 479 /** 480 * Makes an array of shortcut IDs. 481 * For example, makeIds("sX", 4, 9) will return {"sX4", "sX5", "sX6", "sX7", "sX8", "sX9"}. 482 */ makeIds(String prefix, int first, int last)483 protected String[] makeIds(String prefix, int first, int last) { 484 final int len = last - first + 1; 485 final String[] ret = new String[len]; 486 for (int i = 0; i < len; i++) { 487 ret[i] = prefix + (first + i); 488 } 489 return ret; 490 } 491 makeShortcutBuilder(String id)492 protected ShortcutInfo.Builder makeShortcutBuilder(String id) { 493 return new ShortcutInfo.Builder(getCurrentCallerContext(), id); 494 } 495 496 /** 497 * Make a shortcut with details. 498 */ makeShortcut(String id, String shortLabel, ComponentName activity, Icon icon, Intent intent, int rank, LocusId locusId, boolean longLived)499 protected ShortcutInfo makeShortcut(String id, String shortLabel, ComponentName activity, 500 Icon icon, Intent intent, int rank, LocusId locusId, boolean longLived) { 501 return makeShortcut(id, shortLabel, activity, icon, intent, rank, locusId, longLived, 0); 502 } 503 504 /** 505 * Make a shortcut with details. 506 */ makeShortcut(String id, String shortLabel, ComponentName activity, Icon icon, Intent intent, int rank, LocusId locusId, boolean longLived, int excludedSurfaces)507 protected ShortcutInfo makeShortcut(String id, String shortLabel, ComponentName activity, 508 Icon icon, Intent intent, int rank, LocusId locusId, boolean longLived, 509 int excludedSurfaces) { 510 final ShortcutInfo.Builder b = makeShortcutBuilder(id) 511 .setShortLabel(shortLabel) 512 .setRank(rank) 513 .setIntent(intent) 514 .setLongLived(longLived) 515 .setExcludedFromSurfaces(excludedSurfaces); 516 if (activity != null) { 517 b.setActivity(activity); 518 } else if (mTargetActivityOverride != null) { 519 b.setActivity(mTargetActivityOverride); 520 } 521 if (icon != null) { 522 b.setIcon(icon); 523 } 524 if (locusId != null) { 525 b.setLocusId(locusId); 526 } 527 return b.build(); 528 } 529 530 /** 531 * Make an intent. 532 */ makeIntent(String action, Class<?> clazz, Object... bundleKeysAndValues)533 protected Intent makeIntent(String action, Class<?> clazz, Object... bundleKeysAndValues) { 534 final Intent intent = new Intent(action); 535 intent.setComponent(makeComponent(clazz)); 536 intent.replaceExtras(makeBundle(bundleKeysAndValues)); 537 return intent; 538 } 539 540 /** 541 * Make an component name, with the client context. 542 */ 543 @NonNull makeComponent(Class<?> clazz)544 protected ComponentName makeComponent(Class<?> clazz) { 545 return new ComponentName(getCurrentCallerContext(), clazz); 546 } 547 getIconAsLauncher(Context launcherContext, String packageName, String shortcutId)548 protected Drawable getIconAsLauncher(Context launcherContext, String packageName, 549 String shortcutId) { 550 return getIconAsLauncher(launcherContext, packageName, shortcutId, /* withBadge=*/ true); 551 } 552 getIconAsLauncher(Context launcherContext, String packageName, String shortcutId, boolean withBadge)553 protected Drawable getIconAsLauncher(Context launcherContext, String packageName, 554 String shortcutId, boolean withBadge) { 555 runWithNoStrictMode(() -> setDefaultLauncher(getInstrumentation(), launcherContext)); 556 557 final AtomicReference<Drawable> ret = new AtomicReference<>(); 558 559 runWithCallerWithNoStrictMode(launcherContext, () -> { 560 final ShortcutQuery q = new ShortcutQuery() 561 .setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC 562 | ShortcutQuery.FLAG_MATCH_MANIFEST 563 | ShortcutQuery.FLAG_MATCH_PINNED 564 | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY) 565 .setPackage(packageName) 566 .setShortcutIds(list(shortcutId)); 567 final List<ShortcutInfo> found = getLauncherApps().getShortcuts(q, getUserHandle()); 568 569 assertEquals("Shortcut not found", 1, found.size()); 570 571 if (withBadge) { 572 ret.set(getLauncherApps().getShortcutBadgedIconDrawable(found.get(0), 0)); 573 } else { 574 ret.set(getLauncherApps().getShortcutIconDrawable(found.get(0), 0)); 575 } 576 }); 577 return ret.get(); 578 } 579 assertIconDimensions(Context launcherContext, String packageName, String shortcutId, Icon expectedIcon)580 protected void assertIconDimensions(Context launcherContext, String packageName, 581 String shortcutId, Icon expectedIcon) { 582 final Drawable actual = getIconAsLauncher(launcherContext, packageName, shortcutId); 583 if (actual == null && expectedIcon == null) { 584 return; // okay 585 } 586 final Drawable expected = expectedIcon.loadDrawable(getTestContext()); 587 assertEquals(expected.getIntrinsicWidth(), actual.getIntrinsicWidth()); 588 assertEquals(expected.getIntrinsicHeight(), actual.getIntrinsicHeight()); 589 } 590 assertIconDimensions(Icon expectedIcon, Drawable actual)591 protected void assertIconDimensions(Icon expectedIcon, Drawable actual) { 592 if (actual == null && expectedIcon == null) { 593 return; // okay 594 } 595 final Drawable expected = expectedIcon.loadDrawable(getTestContext()); 596 597 if (expected instanceof AdaptiveIconDrawable) { 598 assertTrue(actual instanceof AdaptiveIconDrawable); 599 } 600 assertEquals(expected.getIntrinsicWidth(), actual.getIntrinsicWidth()); 601 assertEquals(expected.getIntrinsicHeight(), actual.getIntrinsicHeight()); 602 } 603 loadPackageDrawableIcon(Context packageContext, String resName)604 protected Icon loadPackageDrawableIcon(Context packageContext, String resName) 605 throws Exception { 606 final Resources res = getTestContext().getPackageManager().getResourcesForApplication( 607 packageContext.getPackageName()); 608 609 // Note the resource package names don't have the numbers. 610 final int id = res.getIdentifier(resName, "drawable", 611 "android.content.pm.cts.shortcutmanager.packages"); 612 if (id == 0) { 613 fail("Drawable " + resName + " is not found in package " 614 + packageContext.getPackageName()); 615 } 616 return Icon.createWithResource(packageContext, id); 617 } 618 loadCallerDrawableIcon(String resName)619 protected Icon loadCallerDrawableIcon(String resName) throws Exception { 620 return loadPackageDrawableIcon(getCurrentCallerContext(), resName); 621 } 622 getShortcutsAsLauncher(int flags, String packageName)623 protected List<ShortcutInfo> getShortcutsAsLauncher(int flags, String packageName) { 624 return getShortcutsAsLauncher(flags, packageName, null, 0, null, null); 625 } 626 getShortcutsAsLauncher( int flags, String packageName, String activityName, long changedSince, List<String> ids, List<LocusId> locusIds)627 protected List<ShortcutInfo> getShortcutsAsLauncher( 628 int flags, String packageName, String activityName, 629 long changedSince, List<String> ids, List<LocusId> locusIds) { 630 final ShortcutQuery q = new ShortcutQuery(); 631 q.setQueryFlags(flags); 632 if (packageName != null) { 633 q.setPackage(packageName); 634 if (activityName != null) { 635 q.setActivity(new ComponentName(packageName, 636 "android.content.pm.cts.shortcutmanager.packages." + activityName)); 637 } 638 } 639 q.setChangedSince(changedSince); 640 if (ids != null && ids.size() > 0) { 641 q.setShortcutIds(ids); 642 } 643 if (locusIds != null && locusIds.size() > 0) { 644 q.setLocusIds(locusIds); 645 } 646 return getLauncherApps().getShortcuts(q, getUserHandle()); 647 } 648 isAppSearchEnabled()649 protected boolean isAppSearchEnabled() { 650 return SystemUtil.runWithShellPermissionIdentity(() -> 651 DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, 652 "shortcut_appsearch_integration", true)) 653 && !getTestContext().getSystemService(ActivityManager.class).isLowRamDevice(); 654 } 655 } 656