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