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