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