ShortcutManagerTest2.java revision 51ab2b3fd04e24e0ca98afd1c1832d84f3a9e62c
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.assertExpectException; 19import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list; 20import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.parceled; 21import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set; 22 23import android.Manifest.permission; 24import android.app.ActivityManager; 25import android.content.ComponentName; 26import android.content.Intent; 27import android.content.pm.ShortcutInfo; 28import android.graphics.BitmapFactory; 29import android.graphics.drawable.Icon; 30import android.os.PersistableBundle; 31import android.os.UserHandle; 32import android.test.MoreAsserts; 33import android.test.suitebuilder.annotation.SmallTest; 34 35import com.android.frameworks.servicestests.R; 36import com.android.server.SystemService; 37 38/** 39 * Tests for ShortcutService and ShortcutManager. 40 * 41 m FrameworksServicesTests && 42 adb install \ 43 -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && 44 adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 \ 45 -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner 46 */ 47@SmallTest 48public class ShortcutManagerTest2 extends BaseShortcutManagerTest { 49 // ShortcutInfo tests 50 51 public void testShortcutInfoMissingMandatoryFields() { 52 assertExpectException( 53 IllegalArgumentException.class, 54 "ID must be provided", 55 () -> new ShortcutInfo.Builder(getTestContext()).build()); 56 assertExpectException( 57 NullPointerException.class, 58 "Intent action must be set", 59 () -> new ShortcutInfo.Builder(getTestContext()).setIntent(new Intent())); 60 assertExpectException( 61 NullPointerException.class, 62 "activity must be provided", 63 () -> new ShortcutInfo.Builder(getTestContext()).setId("id").build() 64 .enforceMandatoryFields()); 65 assertExpectException( 66 IllegalArgumentException.class, 67 "title must be provided", 68 () -> new ShortcutInfo.Builder(getTestContext()).setId("id") 69 .setActivity( 70 new ComponentName(getTestContext().getPackageName(), "s")) 71 .build() 72 .enforceMandatoryFields()); 73 assertExpectException( 74 NullPointerException.class, 75 "Intent must be provided", 76 () -> new ShortcutInfo.Builder(getTestContext()).setId("id") 77 .setActivity( 78 new ComponentName(getTestContext().getPackageName(), "s")) 79 .setTitle("x").build() 80 .enforceMandatoryFields()); 81 } 82 83 public void testShortcutInfoParcel() { 84 setCaller(CALLING_PACKAGE_1, USER_10); 85 ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext) 86 .setId("id") 87 .setTitle("title") 88 .setIntent(makeIntent("action", ShortcutActivity.class)) 89 .build()); 90 assertEquals(mClientContext.getPackageName(), si.getPackage()); 91 assertEquals(USER_10, si.getUserId()); 92 assertEquals(HANDLE_USER_10, si.getUserHandle()); 93 assertEquals("id", si.getId()); 94 assertEquals("title", si.getTitle()); 95 assertEquals("action", si.getIntent().getAction()); 96 97 PersistableBundle pb = new PersistableBundle(); 98 pb.putInt("k", 1); 99 100 si = new ShortcutInfo.Builder(getTestContext()) 101 .setId("id") 102 .setActivity(new ComponentName("a", "b")) 103 .setIcon(Icon.createWithResource(mClientContext, 123)) 104 .setTitle("title") 105 .setText("text") 106 .setDisabledMessage("dismes") 107 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 108 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 109 .setRank(123) 110 .setExtras(pb) 111 .build(); 112 si.addFlags(ShortcutInfo.FLAG_PINNED); 113 si.setBitmapPath("abc"); 114 si.setIconResourceId(456); 115 116 si = parceled(si); 117 118 assertEquals(getTestContext().getPackageName(), si.getPackage()); 119 assertEquals("id", si.getId()); 120 assertEquals(new ComponentName("a", "b"), si.getActivity()); 121 assertEquals(123, si.getIcon().getResId()); 122 assertEquals("title", si.getTitle()); 123 assertEquals("text", si.getText()); 124 assertEquals("dismes", si.getDisabledMessage()); 125 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 126 assertEquals("action", si.getIntent().getAction()); 127 assertEquals("val", si.getIntent().getStringExtra("key")); 128 assertEquals(123, si.getRank()); 129 assertEquals(1, si.getExtras().getInt("k")); 130 131 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 132 assertEquals("abc", si.getBitmapPath()); 133 assertEquals(456, si.getIconResourceId()); 134 } 135 136 public void testShortcutInfoParcel_resId() { 137 setCaller(CALLING_PACKAGE_1, USER_10); 138 ShortcutInfo si; 139 140 PersistableBundle pb = new PersistableBundle(); 141 pb.putInt("k", 1); 142 143 si = new ShortcutInfo.Builder(getTestContext()) 144 .setId("id") 145 .setActivity(new ComponentName("a", "b")) 146 .setIcon(Icon.createWithResource(mClientContext, 123)) 147 .setTitleResId(10) 148 .setTextResId(11) 149 .setDisabledMessageResId(12) 150 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 151 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 152 .setRank(123) 153 .setExtras(pb) 154 .build(); 155 si.addFlags(ShortcutInfo.FLAG_PINNED); 156 si.setBitmapPath("abc"); 157 si.setIconResourceId(456); 158 159 si = parceled(si); 160 161 assertEquals(getTestContext().getPackageName(), si.getPackage()); 162 assertEquals("id", si.getId()); 163 assertEquals(new ComponentName("a", "b"), si.getActivity()); 164 assertEquals(123, si.getIcon().getResId()); 165 assertEquals(10, si.getTitleResId()); 166 assertEquals(11, si.getTextResId()); 167 assertEquals(12, si.getDisabledMessageResourceId()); 168 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 169 assertEquals("action", si.getIntent().getAction()); 170 assertEquals("val", si.getIntent().getStringExtra("key")); 171 assertEquals(123, si.getRank()); 172 assertEquals(1, si.getExtras().getInt("k")); 173 174 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 175 assertEquals("abc", si.getBitmapPath()); 176 assertEquals(456, si.getIconResourceId()); 177 } 178 179 public void testShortcutInfoClone() { 180 setCaller(CALLING_PACKAGE_1, USER_11); 181 182 PersistableBundle pb = new PersistableBundle(); 183 pb.putInt("k", 1); 184 ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext) 185 .setId("id") 186 .setActivity(new ComponentName("a", "b")) 187 .setIcon(Icon.createWithResource(mClientContext, 123)) 188 .setTitle("title") 189 .setText("text") 190 .setDisabledMessage("dismes") 191 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 192 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 193 .setRank(123) 194 .setExtras(pb) 195 .build(); 196 sorig.addFlags(ShortcutInfo.FLAG_PINNED); 197 sorig.setBitmapPath("abc"); 198 sorig.setIconResourceId(456); 199 200 ShortcutInfo si = sorig.clone(/* clone flags*/ 0); 201 202 assertEquals(USER_11, si.getUserId()); 203 assertEquals(HANDLE_USER_11, si.getUserHandle()); 204 assertEquals(mClientContext.getPackageName(), si.getPackage()); 205 assertEquals("id", si.getId()); 206 assertEquals(new ComponentName("a", "b"), si.getActivity()); 207 assertEquals(123, si.getIcon().getResId()); 208 assertEquals("title", si.getTitle()); 209 assertEquals("text", si.getText()); 210 assertEquals("dismes", si.getDisabledMessage()); 211 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 212 assertEquals("action", si.getIntent().getAction()); 213 assertEquals("val", si.getIntent().getStringExtra("key")); 214 assertEquals(123, si.getRank()); 215 assertEquals(1, si.getExtras().getInt("k")); 216 217 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 218 assertEquals("abc", si.getBitmapPath()); 219 assertEquals(456, si.getIconResourceId()); 220 221 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR); 222 223 assertEquals(mClientContext.getPackageName(), si.getPackage()); 224 assertEquals("id", si.getId()); 225 assertEquals(new ComponentName("a", "b"), si.getActivity()); 226 assertEquals(null, si.getIcon()); 227 assertEquals("title", si.getTitle()); 228 assertEquals("text", si.getText()); 229 assertEquals("dismes", si.getDisabledMessage()); 230 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 231 assertEquals("action", si.getIntent().getAction()); 232 assertEquals("val", si.getIntent().getStringExtra("key")); 233 assertEquals(123, si.getRank()); 234 assertEquals(1, si.getExtras().getInt("k")); 235 236 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 237 assertEquals(null, si.getBitmapPath()); 238 239 assertEquals(456, si.getIconResourceId()); 240 241 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER); 242 243 assertEquals(mClientContext.getPackageName(), si.getPackage()); 244 assertEquals("id", si.getId()); 245 assertEquals(new ComponentName("a", "b"), si.getActivity()); 246 assertEquals(null, si.getIcon()); 247 assertEquals("title", si.getTitle()); 248 assertEquals("text", si.getText()); 249 assertEquals("dismes", si.getDisabledMessage()); 250 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 251 assertEquals(null, si.getIntent()); 252 assertEquals(123, si.getRank()); 253 assertEquals(1, si.getExtras().getInt("k")); 254 255 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 256 assertEquals(null, si.getBitmapPath()); 257 258 assertEquals(456, si.getIconResourceId()); 259 260 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO); 261 262 assertEquals(mClientContext.getPackageName(), si.getPackage()); 263 assertEquals("id", si.getId()); 264 assertEquals(null, si.getActivity()); 265 assertEquals(null, si.getIcon()); 266 assertEquals(null, si.getTitle()); 267 assertEquals(null, si.getText()); 268 assertEquals(null, si.getDisabledMessage()); 269 assertEquals(null, si.getCategories()); 270 assertEquals(null, si.getIntent()); 271 assertEquals(0, si.getRank()); 272 assertEquals(null, si.getExtras()); 273 274 assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags()); 275 assertEquals(null, si.getBitmapPath()); 276 277 assertEquals(456, si.getIconResourceId()); 278 } 279 280 public void testShortcutInfoClone_resId() { 281 setCaller(CALLING_PACKAGE_1, USER_11); 282 283 PersistableBundle pb = new PersistableBundle(); 284 pb.putInt("k", 1); 285 ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext) 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 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 293 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 294 .setRank(123) 295 .setExtras(pb) 296 .build(); 297 sorig.addFlags(ShortcutInfo.FLAG_PINNED); 298 sorig.setBitmapPath("abc"); 299 sorig.setIconResourceId(456); 300 301 ShortcutInfo si = sorig.clone(/* clone flags*/ 0); 302 303 assertEquals(USER_11, si.getUserId()); 304 assertEquals(HANDLE_USER_11, si.getUserHandle()); 305 assertEquals(mClientContext.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(11, si.getTextResId()); 311 assertEquals(12, si.getDisabledMessageResourceId()); 312 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 313 assertEquals("action", si.getIntent().getAction()); 314 assertEquals("val", si.getIntent().getStringExtra("key")); 315 assertEquals(123, si.getRank()); 316 assertEquals(1, si.getExtras().getInt("k")); 317 318 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 319 assertEquals("abc", si.getBitmapPath()); 320 assertEquals(456, si.getIconResourceId()); 321 322 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR); 323 324 assertEquals(mClientContext.getPackageName(), si.getPackage()); 325 assertEquals("id", si.getId()); 326 assertEquals(new ComponentName("a", "b"), si.getActivity()); 327 assertEquals(null, si.getIcon()); 328 assertEquals(10, si.getTitleResId()); 329 assertEquals(11, si.getTextResId()); 330 assertEquals(12, si.getDisabledMessageResourceId()); 331 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 332 assertEquals("action", si.getIntent().getAction()); 333 assertEquals("val", si.getIntent().getStringExtra("key")); 334 assertEquals(123, si.getRank()); 335 assertEquals(1, si.getExtras().getInt("k")); 336 337 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 338 assertEquals(null, si.getBitmapPath()); 339 340 assertEquals(456, si.getIconResourceId()); 341 342 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER); 343 344 assertEquals(mClientContext.getPackageName(), si.getPackage()); 345 assertEquals("id", si.getId()); 346 assertEquals(new ComponentName("a", "b"), si.getActivity()); 347 assertEquals(null, si.getIcon()); 348 assertEquals(10, si.getTitleResId()); 349 assertEquals(11, si.getTextResId()); 350 assertEquals(12, si.getDisabledMessageResourceId()); 351 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 352 assertEquals(null, si.getIntent()); 353 assertEquals(123, si.getRank()); 354 assertEquals(1, si.getExtras().getInt("k")); 355 356 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 357 assertEquals(null, si.getBitmapPath()); 358 359 assertEquals(456, si.getIconResourceId()); 360 361 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO); 362 363 assertEquals(mClientContext.getPackageName(), si.getPackage()); 364 assertEquals("id", si.getId()); 365 assertEquals(null, si.getActivity()); 366 assertEquals(null, si.getIcon()); 367 assertEquals(0, si.getTitleResId()); 368 assertEquals(0, si.getTextResId()); 369 assertEquals(0, si.getDisabledMessageResourceId()); 370 assertEquals(null, si.getCategories()); 371 assertEquals(null, si.getIntent()); 372 assertEquals(0, si.getRank()); 373 assertEquals(null, si.getExtras()); 374 375 assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags()); 376 assertEquals(null, si.getBitmapPath()); 377 378 assertEquals(456, si.getIconResourceId()); 379 } 380 381 public void testShortcutInfoClone_minimum() { 382 PersistableBundle pb = new PersistableBundle(); 383 pb.putInt("k", 1); 384 ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext()) 385 .setId("id") 386 .setTitle("title") 387 .setIntent(makeIntent("action", ShortcutActivity.class)) 388 .build(); 389 ShortcutInfo si = sorig.clone(/* clone flags*/ 0); 390 391 assertEquals(getTestContext().getPackageName(), si.getPackage()); 392 assertEquals("id", si.getId()); 393 assertEquals("title", si.getTitle()); 394 assertEquals("action", si.getIntent().getAction()); 395 assertEquals(null, si.getCategories()); 396 397 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR); 398 399 assertEquals(getTestContext().getPackageName(), si.getPackage()); 400 assertEquals("id", si.getId()); 401 assertEquals("title", si.getTitle()); 402 assertEquals("action", si.getIntent().getAction()); 403 assertEquals(null, si.getCategories()); 404 405 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER); 406 407 assertEquals(getTestContext().getPackageName(), si.getPackage()); 408 assertEquals("id", si.getId()); 409 assertEquals("title", si.getTitle()); 410 assertEquals(null, si.getIntent()); 411 assertEquals(null, si.getCategories()); 412 413 si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO); 414 415 assertEquals(getTestContext().getPackageName(), si.getPackage()); 416 assertEquals("id", si.getId()); 417 assertEquals(null, si.getTitle()); 418 assertEquals(null, si.getIntent()); 419 assertEquals(null, si.getCategories()); 420 } 421 422 public void testShortcutInfoCopyNonNullFieldsFrom() throws InterruptedException { 423 PersistableBundle pb = new PersistableBundle(); 424 pb.putInt("k", 1); 425 ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext()) 426 .setId("id") 427 .setActivity(new ComponentName("a", "b")) 428 .setIcon(Icon.createWithResource(mClientContext, 123)) 429 .setTitle("title") 430 .setText("text") 431 .setDisabledMessage("dismes") 432 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 433 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 434 .setRank(123) 435 .setExtras(pb) 436 .build(); 437 sorig.addFlags(ShortcutInfo.FLAG_PINNED); 438 sorig.setBitmapPath("abc"); 439 sorig.setIconResourceId(456); 440 441 ShortcutInfo si; 442 443 si = sorig.clone(/* flags=*/ 0); 444 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 445 .setActivity(new ComponentName("x", "y")).build()); 446 assertEquals("text", si.getText()); 447 assertEquals(new ComponentName("x", "y"), si.getActivity()); 448 449 si = sorig.clone(/* flags=*/ 0); 450 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 451 .setIcon(Icon.createWithResource(mClientContext, 456)).build()); 452 assertEquals("text", si.getText()); 453 assertEquals(456, si.getIcon().getResId()); 454 455 si = sorig.clone(/* flags=*/ 0); 456 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 457 .setTitle("xyz").build()); 458 assertEquals("text", si.getText()); 459 assertEquals("xyz", si.getTitle()); 460 assertEquals(0, si.getTitleResId()); 461 462 si = sorig.clone(/* flags=*/ 0); 463 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 464 .setTitleResId(123).build()); 465 assertEquals("text", si.getText()); 466 assertEquals(null, si.getTitle()); 467 assertEquals(123, si.getTitleResId()); 468 469 si = sorig.clone(/* flags=*/ 0); 470 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 471 .setText("xxx").build()); 472 assertEquals(123, si.getRank()); 473 assertEquals("xxx", si.getText()); 474 assertEquals(0, si.getTextResId()); 475 476 si = sorig.clone(/* flags=*/ 0); 477 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 478 .setTextResId(1111).build()); 479 assertEquals(123, si.getRank()); 480 assertEquals(null, si.getText()); 481 assertEquals(1111, si.getTextResId()); 482 483 si = sorig.clone(/* flags=*/ 0); 484 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 485 .setDisabledMessage("xxx").build()); 486 assertEquals(123, si.getRank()); 487 assertEquals("xxx", si.getDisabledMessage()); 488 assertEquals(0, si.getDisabledMessageResourceId()); 489 490 si = sorig.clone(/* flags=*/ 0); 491 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 492 .setDisabledMessageResId(11111).build()); 493 assertEquals(123, si.getRank()); 494 assertEquals(null, si.getDisabledMessage()); 495 assertEquals(11111, si.getDisabledMessageResourceId()); 496 497 si = sorig.clone(/* flags=*/ 0); 498 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 499 .setCategories(set()).build()); 500 assertEquals("text", si.getText()); 501 assertEquals(set(), si.getCategories()); 502 503 si = sorig.clone(/* flags=*/ 0); 504 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 505 .setCategories(set("x")).build()); 506 assertEquals("text", si.getText()); 507 assertEquals(set("x"), si.getCategories()); 508 509 si = sorig.clone(/* flags=*/ 0); 510 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 511 .setIntent(makeIntent("action2", ShortcutActivity.class)).build()); 512 assertEquals("text", si.getText()); 513 assertEquals("action2", si.getIntent().getAction()); 514 assertEquals(null, si.getIntent().getStringExtra("key")); 515 516 si = sorig.clone(/* flags=*/ 0); 517 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 518 .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build()); 519 assertEquals("text", si.getText()); 520 assertEquals("action3", si.getIntent().getAction()); 521 assertEquals("x", si.getIntent().getStringExtra("key")); 522 523 si = sorig.clone(/* flags=*/ 0); 524 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 525 .setRank(999).build()); 526 assertEquals("text", si.getText()); 527 assertEquals(999, si.getRank()); 528 529 530 PersistableBundle pb2 = new PersistableBundle(); 531 pb2.putInt("x", 99); 532 533 si = sorig.clone(/* flags=*/ 0); 534 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 535 .setExtras(pb2).build()); 536 assertEquals("text", si.getText()); 537 assertEquals(99, si.getExtras().getInt("x")); 538 539 // Make sure the timestamp gets updated too. 540 541 final long timestamp = si.getLastChangedTimestamp(); 542 Thread.sleep(2); 543 544 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 545 .setTitle("xyz").build()); 546 547 assertTrue(si.getLastChangedTimestamp() > timestamp); 548 } 549 550 public void testShortcutInfoCopyNonNullFieldsFrom_resId() throws InterruptedException { 551 PersistableBundle pb = new PersistableBundle(); 552 pb.putInt("k", 1); 553 ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext()) 554 .setId("id") 555 .setActivity(new ComponentName("a", "b")) 556 .setIcon(Icon.createWithResource(mClientContext, 123)) 557 .setTitleResId(10) 558 .setTextResId(11) 559 .setDisabledMessageResId(12) 560 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 561 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 562 .setRank(123) 563 .setExtras(pb) 564 .build(); 565 sorig.addFlags(ShortcutInfo.FLAG_PINNED); 566 sorig.setBitmapPath("abc"); 567 sorig.setIconResourceId(456); 568 569 ShortcutInfo si; 570 571 si = sorig.clone(/* flags=*/ 0); 572 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 573 .setActivity(new ComponentName("x", "y")).build()); 574 assertEquals(11, si.getTextResId()); 575 assertEquals(new ComponentName("x", "y"), si.getActivity()); 576 577 si = sorig.clone(/* flags=*/ 0); 578 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 579 .setIcon(Icon.createWithResource(mClientContext, 456)).build()); 580 assertEquals(11, si.getTextResId()); 581 assertEquals(456, si.getIcon().getResId()); 582 583 si = sorig.clone(/* flags=*/ 0); 584 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 585 .setTitle("xyz").build()); 586 assertEquals(11, si.getTextResId()); 587 assertEquals("xyz", si.getTitle()); 588 assertEquals(0, si.getTitleResId()); 589 590 si = sorig.clone(/* flags=*/ 0); 591 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 592 .setTitleResId(123).build()); 593 assertEquals(11, si.getTextResId()); 594 assertEquals(null, si.getTitle()); 595 assertEquals(123, si.getTitleResId()); 596 597 si = sorig.clone(/* flags=*/ 0); 598 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 599 .setText("xxx").build()); 600 assertEquals(123, si.getRank()); 601 assertEquals("xxx", si.getText()); 602 assertEquals(0, si.getTextResId()); 603 604 si = sorig.clone(/* flags=*/ 0); 605 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 606 .setTextResId(1111).build()); 607 assertEquals(123, si.getRank()); 608 assertEquals(null, si.getText()); 609 assertEquals(1111, si.getTextResId()); 610 611 si = sorig.clone(/* flags=*/ 0); 612 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 613 .setDisabledMessage("xxx").build()); 614 assertEquals(123, si.getRank()); 615 assertEquals("xxx", si.getDisabledMessage()); 616 assertEquals(0, si.getDisabledMessageResourceId()); 617 618 si = sorig.clone(/* flags=*/ 0); 619 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 620 .setDisabledMessageResId(11111).build()); 621 assertEquals(123, si.getRank()); 622 assertEquals(null, si.getDisabledMessage()); 623 assertEquals(11111, si.getDisabledMessageResourceId()); 624 625 si = sorig.clone(/* flags=*/ 0); 626 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 627 .setCategories(set()).build()); 628 assertEquals(11, si.getTextResId()); 629 assertEquals(set(), si.getCategories()); 630 631 si = sorig.clone(/* flags=*/ 0); 632 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 633 .setCategories(set("x")).build()); 634 assertEquals(11, si.getTextResId()); 635 assertEquals(set("x"), si.getCategories()); 636 637 si = sorig.clone(/* flags=*/ 0); 638 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 639 .setIntent(makeIntent("action2", ShortcutActivity.class)).build()); 640 assertEquals(11, si.getTextResId()); 641 assertEquals("action2", si.getIntent().getAction()); 642 assertEquals(null, si.getIntent().getStringExtra("key")); 643 644 si = sorig.clone(/* flags=*/ 0); 645 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 646 .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build()); 647 assertEquals(11, si.getTextResId()); 648 assertEquals("action3", si.getIntent().getAction()); 649 assertEquals("x", si.getIntent().getStringExtra("key")); 650 651 si = sorig.clone(/* flags=*/ 0); 652 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 653 .setRank(999).build()); 654 assertEquals(11, si.getTextResId()); 655 assertEquals(999, si.getRank()); 656 657 658 PersistableBundle pb2 = new PersistableBundle(); 659 pb2.putInt("x", 99); 660 661 si = sorig.clone(/* flags=*/ 0); 662 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 663 .setExtras(pb2).build()); 664 assertEquals(11, si.getTextResId()); 665 assertEquals(99, si.getExtras().getInt("x")); 666 667 // Make sure the timestamp gets updated too. 668 669 final long timestamp = si.getLastChangedTimestamp(); 670 Thread.sleep(2); 671 672 si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id") 673 .setTitle("xyz").build()); 674 675 assertTrue(si.getLastChangedTimestamp() > timestamp); 676 } 677 678 public void testShortcutInfoSaveAndLoad() throws InterruptedException { 679 setCaller(CALLING_PACKAGE_1, USER_10); 680 681 final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource( 682 getTestContext().getResources(), R.drawable.black_32x32)); 683 684 PersistableBundle pb = new PersistableBundle(); 685 pb.putInt("k", 1); 686 ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext) 687 .setId("id") 688 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class)) 689 .setIcon(bmp32x32) 690 .setTitle("title") 691 .setText("text") 692 .setDisabledMessage("dismes") 693 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 694 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 695 .setRank(123) 696 .setExtras(pb) 697 .build(); 698 699 mManager.addDynamicShortcuts(list(sorig)); 700 701 Thread.sleep(2); 702 final long now = System.currentTimeMillis(); 703 704 // Save and load. 705 mService.saveDirtyInfo(); 706 initService(); 707 mService.handleUnlockUser(USER_10); 708 709 ShortcutInfo si; 710 si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10); 711 712 assertEquals(USER_10, si.getUserId()); 713 assertEquals(HANDLE_USER_10, si.getUserHandle()); 714 assertEquals(CALLING_PACKAGE_1, si.getPackage()); 715 assertEquals("id", si.getId()); 716 assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName()); 717 assertEquals(null, si.getIcon()); 718 assertEquals("title", si.getTitle()); 719 assertEquals("text", si.getText()); 720 assertEquals("dismes", si.getDisabledMessage()); 721 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 722 assertEquals("action", si.getIntent().getAction()); 723 assertEquals("val", si.getIntent().getStringExtra("key")); 724 assertEquals(123, si.getRank()); 725 assertEquals(1, si.getExtras().getInt("k")); 726 727 assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags()); 728 assertNotNull(si.getBitmapPath()); // Something should be set. 729 assertEquals(0, si.getIconResourceId()); 730 assertTrue(si.getLastChangedTimestamp() < now); 731 } 732 733 public void testShortcutInfoSaveAndLoad_resId() throws InterruptedException { 734 setCaller(CALLING_PACKAGE_1, USER_10); 735 736 final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource( 737 getTestContext().getResources(), R.drawable.black_32x32)); 738 739 PersistableBundle pb = new PersistableBundle(); 740 pb.putInt("k", 1); 741 ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext) 742 .setId("id") 743 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class)) 744 .setIcon(bmp32x32) 745 .setTitleResId(10) 746 .setTextResId(11) 747 .setDisabledMessageResId(12) 748 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 749 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 750 .setRank(123) 751 .setExtras(pb) 752 .build(); 753 754 mManager.addDynamicShortcuts(list(sorig)); 755 756 Thread.sleep(2); 757 final long now = System.currentTimeMillis(); 758 759 // Save and load. 760 mService.saveDirtyInfo(); 761 initService(); 762 mService.handleUnlockUser(USER_10); 763 764 ShortcutInfo si; 765 si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10); 766 767 assertEquals(USER_10, si.getUserId()); 768 assertEquals(HANDLE_USER_10, si.getUserHandle()); 769 assertEquals(CALLING_PACKAGE_1, si.getPackage()); 770 assertEquals("id", si.getId()); 771 assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName()); 772 assertEquals(null, si.getIcon()); 773 assertEquals(10, si.getTitleResId()); 774 assertEquals(11, si.getTextResId()); 775 assertEquals(12, si.getDisabledMessageResourceId()); 776 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 777 assertEquals("action", si.getIntent().getAction()); 778 assertEquals("val", si.getIntent().getStringExtra("key")); 779 assertEquals(123, si.getRank()); 780 assertEquals(1, si.getExtras().getInt("k")); 781 782 assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags()); 783 assertNotNull(si.getBitmapPath()); // Something should be set. 784 assertEquals(0, si.getIconResourceId()); 785 assertTrue(si.getLastChangedTimestamp() < now); 786 } 787 788 public void testShortcutInfoSaveAndLoad_forBackup() { 789 setCaller(CALLING_PACKAGE_1, USER_0); 790 791 final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource( 792 getTestContext().getResources(), R.drawable.black_32x32)); 793 794 PersistableBundle pb = new PersistableBundle(); 795 pb.putInt("k", 1); 796 ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext) 797 .setId("id") 798 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class)) 799 .setIcon(bmp32x32) 800 .setTitle("title") 801 .setText("text") 802 .setDisabledMessage("dismes") 803 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 804 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 805 .setRank(123) 806 .setExtras(pb) 807 .build(); 808 809 mManager.addDynamicShortcuts(list(sorig)); 810 811 // Dynamic shortcuts won't be backed up, so we need to pin it. 812 setCaller(LAUNCHER_1, USER_0); 813 mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0); 814 815 // Do backup & restore. 816 backupAndRestore(); 817 818 mService.handleUnlockUser(USER_0); // Load user-0. 819 820 ShortcutInfo si; 821 si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0); 822 823 assertEquals(CALLING_PACKAGE_1, si.getPackage()); 824 assertEquals("id", si.getId()); 825 assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName()); 826 assertEquals(null, si.getIcon()); 827 assertEquals("title", si.getTitle()); 828 assertEquals("text", si.getText()); 829 assertEquals("dismes", si.getDisabledMessage()); 830 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 831 assertEquals("action", si.getIntent().getAction()); 832 assertEquals("val", si.getIntent().getStringExtra("key")); 833 assertEquals(123, si.getRank()); 834 assertEquals(1, si.getExtras().getInt("k")); 835 836 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 837 assertNull(si.getBitmapPath()); // No icon. 838 assertEquals(0, si.getIconResourceId()); 839 } 840 841 public void testShortcutInfoSaveAndLoad_forBackup_resId() { 842 setCaller(CALLING_PACKAGE_1, USER_0); 843 844 final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource( 845 getTestContext().getResources(), R.drawable.black_32x32)); 846 847 PersistableBundle pb = new PersistableBundle(); 848 pb.putInt("k", 1); 849 ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext) 850 .setId("id") 851 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class)) 852 .setIcon(bmp32x32) 853 .setTitleResId(10) 854 .setTextResId(11) 855 .setDisabledMessageResId(12) 856 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 857 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 858 .setRank(123) 859 .setExtras(pb) 860 .build(); 861 862 mManager.addDynamicShortcuts(list(sorig)); 863 864 // Dynamic shortcuts won't be backed up, so we need to pin it. 865 setCaller(LAUNCHER_1, USER_0); 866 mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0); 867 868 // Do backup & restore. 869 backupAndRestore(); 870 871 mService.handleUnlockUser(USER_0); // Load user-0. 872 873 ShortcutInfo si; 874 si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0); 875 876 assertEquals(CALLING_PACKAGE_1, si.getPackage()); 877 assertEquals("id", si.getId()); 878 assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName()); 879 assertEquals(null, si.getIcon()); 880 assertEquals(10, si.getTitleResId()); 881 assertEquals(11, si.getTextResId()); 882 assertEquals(12, si.getDisabledMessageResourceId()); 883 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 884 assertEquals("action", si.getIntent().getAction()); 885 assertEquals("val", si.getIntent().getStringExtra("key")); 886 assertEquals(123, si.getRank()); 887 assertEquals(1, si.getExtras().getInt("k")); 888 889 assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags()); 890 assertNull(si.getBitmapPath()); // No icon. 891 assertEquals(0, si.getIconResourceId()); 892 } 893 894 895 public void testThrottling() { 896 final ShortcutInfo si1 = makeShortcut("shortcut1"); 897 898 assertTrue(mManager.setDynamicShortcuts(list(si1))); 899 assertEquals(2, mManager.getRemainingCallCount()); 900 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 901 902 mInjectedCurrentTimeMillis++; 903 assertTrue(mManager.setDynamicShortcuts(list(si1))); 904 assertEquals(1, mManager.getRemainingCallCount()); 905 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 906 907 mInjectedCurrentTimeMillis++; 908 assertTrue(mManager.setDynamicShortcuts(list(si1))); 909 assertEquals(0, mManager.getRemainingCallCount()); 910 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 911 912 // Reached the max 913 914 mInjectedCurrentTimeMillis++; 915 assertFalse(mManager.setDynamicShortcuts(list(si1))); 916 assertEquals(0, mManager.getRemainingCallCount()); 917 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 918 919 // Still throttled 920 mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1; 921 assertFalse(mManager.setDynamicShortcuts(list(si1))); 922 assertEquals(0, mManager.getRemainingCallCount()); 923 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 924 925 // Now it should work. 926 mInjectedCurrentTimeMillis++; 927 assertTrue(mManager.setDynamicShortcuts(list(si1))); // fail 928 assertEquals(2, mManager.getRemainingCallCount()); 929 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 930 931 mInjectedCurrentTimeMillis++; 932 assertTrue(mManager.setDynamicShortcuts(list(si1))); 933 assertEquals(1, mManager.getRemainingCallCount()); 934 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 935 936 mInjectedCurrentTimeMillis++; 937 assertTrue(mManager.setDynamicShortcuts(list(si1))); 938 assertEquals(0, mManager.getRemainingCallCount()); 939 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 940 941 mInjectedCurrentTimeMillis++; 942 assertFalse(mManager.setDynamicShortcuts(list(si1))); 943 assertEquals(0, mManager.getRemainingCallCount()); 944 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 945 946 // 4 hours later... 947 mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL; 948 assertTrue(mManager.setDynamicShortcuts(list(si1))); 949 assertEquals(2, mManager.getRemainingCallCount()); 950 assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime()); 951 952 mInjectedCurrentTimeMillis++; 953 assertTrue(mManager.setDynamicShortcuts(list(si1))); 954 assertEquals(1, mManager.getRemainingCallCount()); 955 assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime()); 956 957 // Make sure getRemainingCallCount() itself gets reset without calling setDynamicShortcuts(). 958 mInjectedCurrentTimeMillis = START_TIME + 8 * INTERVAL; 959 assertEquals(3, mManager.getRemainingCallCount()); 960 assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime()); 961 962 mInjectedCurrentTimeMillis++; 963 assertTrue(mManager.setDynamicShortcuts(list(si1))); 964 assertEquals(2, mManager.getRemainingCallCount()); 965 assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime()); 966 } 967 968 public void testThrottling_rewind() { 969 final ShortcutInfo si1 = makeShortcut("shortcut1"); 970 971 assertTrue(mManager.setDynamicShortcuts(list(si1))); 972 assertEquals(2, mManager.getRemainingCallCount()); 973 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 974 975 mInjectedCurrentTimeMillis = 12345; // Clock reset! 976 977 // Since the clock looks invalid, the counter shouldn't have reset. 978 assertEquals(2, mManager.getRemainingCallCount()); 979 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 980 981 // Forward again. Still haven't reset yet. 982 mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1; 983 assertEquals(2, mManager.getRemainingCallCount()); 984 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 985 986 // Now rewind -- this will reset the counters. 987 mInjectedCurrentTimeMillis = START_TIME - 100000; 988 assertEquals(3, mManager.getRemainingCallCount()); 989 990 assertTrue(mManager.setDynamicShortcuts(list(si1))); 991 assertEquals(2, mManager.getRemainingCallCount()); 992 993 // Forward again, should be reset now. 994 mInjectedCurrentTimeMillis += INTERVAL; 995 assertEquals(3, mManager.getRemainingCallCount()); 996 } 997 998 public void testThrottling_perPackage() { 999 final ShortcutInfo si1 = makeShortcut("shortcut1"); 1000 1001 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1002 assertEquals(2, mManager.getRemainingCallCount()); 1003 1004 mInjectedCurrentTimeMillis++; 1005 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1006 assertEquals(1, mManager.getRemainingCallCount()); 1007 1008 mInjectedCurrentTimeMillis++; 1009 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1010 assertEquals(0, mManager.getRemainingCallCount()); 1011 1012 // Reached the max 1013 1014 mInjectedCurrentTimeMillis++; 1015 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1016 1017 // Try from a different caller. 1018 mInjectedClientPackage = CALLING_PACKAGE_2; 1019 mInjectedCallingUid = CALLING_UID_2; 1020 1021 // Need to create a new one wit the updated package name. 1022 final ShortcutInfo si2 = makeShortcut("shortcut1"); 1023 1024 assertEquals(3, mManager.getRemainingCallCount()); 1025 1026 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1027 assertEquals(2, mManager.getRemainingCallCount()); 1028 1029 mInjectedCurrentTimeMillis++; 1030 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1031 assertEquals(1, mManager.getRemainingCallCount()); 1032 1033 // Back to the original caller, still throttled. 1034 mInjectedClientPackage = CALLING_PACKAGE_1; 1035 mInjectedCallingUid = CALLING_UID_1; 1036 1037 mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1; 1038 assertEquals(0, mManager.getRemainingCallCount()); 1039 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1040 assertEquals(0, mManager.getRemainingCallCount()); 1041 1042 // Now it should work. 1043 mInjectedCurrentTimeMillis++; 1044 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1045 1046 mInjectedCurrentTimeMillis++; 1047 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1048 1049 mInjectedCurrentTimeMillis++; 1050 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1051 1052 mInjectedCurrentTimeMillis++; 1053 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1054 1055 mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL; 1056 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1057 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1058 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1059 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1060 1061 mInjectedClientPackage = CALLING_PACKAGE_2; 1062 mInjectedCallingUid = CALLING_UID_2; 1063 1064 assertEquals(3, mManager.getRemainingCallCount()); 1065 1066 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1067 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1068 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1069 assertFalse(mManager.setDynamicShortcuts(list(si2))); 1070 } 1071 1072 public void testThrottling_localeChanges() { 1073 prepareCrossProfileDataSet(); 1074 1075 dumpsysOnLogcat("Before save & load"); 1076 1077 mService.saveDirtyInfo(); 1078 initService(); 1079 1080 final long origSequenceNumber = mService.getLocaleChangeSequenceNumber(); 1081 1082 // onSystemLocaleChangedNoLock before boot completed will be ignored. 1083 mInternal.onSystemLocaleChangedNoLock(); 1084 assertEquals(origSequenceNumber, mService.getLocaleChangeSequenceNumber()); 1085 1086 mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); 1087 mInternal.onSystemLocaleChangedNoLock(); 1088 assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber()); 1089 1090 // Note at this point only user-0 is loaded, and the counters are reset for this user, 1091 // but it will work for other users too, because we persist when 1092 1093 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1094 assertEquals(3, mManager.getRemainingCallCount()); 1095 }); 1096 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1097 assertEquals(3, mManager.getRemainingCallCount()); 1098 }); 1099 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1100 assertEquals(3, mManager.getRemainingCallCount()); 1101 }); 1102 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1103 assertEquals(3, mManager.getRemainingCallCount()); 1104 }); 1105 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1106 assertEquals(3, mManager.getRemainingCallCount()); 1107 }); 1108 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1109 assertEquals(3, mManager.getRemainingCallCount()); 1110 }); 1111 1112 mService.saveDirtyInfo(); 1113 initService(); 1114 1115 // Make sure the counter is persisted. 1116 assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber()); 1117 } 1118 1119 public void testThrottling_foreground() throws Exception { 1120 prepareCrossProfileDataSet(); 1121 1122 dumpsysOnLogcat("Before save & load"); 1123 1124 mService.saveDirtyInfo(); 1125 initService(); 1126 1127 // We need to update the current time from time to time, since some of the internal checks 1128 // rely on the time being correctly incremented. 1129 mInjectedCurrentTimeMillis++; 1130 1131 // First, all packages have less than 3 (== initial value) remaining calls. 1132 1133 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1134 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1135 }); 1136 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1137 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1138 }); 1139 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1140 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1141 }); 1142 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1143 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1144 }); 1145 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1146 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1147 }); 1148 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1149 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1150 }); 1151 1152 mInjectedCurrentTimeMillis++; 1153 1154 // State changed, but not foreground, so no resetting. 1155 mService.mUidObserver.onUidStateChanged( 1156 CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING); 1157 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1158 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1159 }); 1160 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1161 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1162 }); 1163 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1164 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1165 }); 1166 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1167 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1168 }); 1169 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1170 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1171 }); 1172 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1173 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1174 }); 1175 1176 mInjectedCurrentTimeMillis++; 1177 1178 // State changed, package1 foreground, reset. 1179 mService.mUidObserver.onUidStateChanged( 1180 CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 1181 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1182 assertEquals(3, mManager.getRemainingCallCount()); 1183 }); 1184 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1185 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1186 }); 1187 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1188 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1189 }); 1190 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1191 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1192 }); 1193 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1194 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1195 }); 1196 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1197 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1198 }); 1199 mService.mUidObserver.onUidStateChanged( 1200 CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING); 1201 1202 mInjectedCurrentTimeMillis++; 1203 1204 // Different app comes to foreground briefly, and goes back to background. 1205 // Now, make sure package 2's counter is reset, even in this case. 1206 mService.mUidObserver.onUidStateChanged( 1207 CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 1208 mService.mUidObserver.onUidStateChanged( 1209 CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING); 1210 1211 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1212 assertEquals(3, mManager.getRemainingCallCount()); 1213 }); 1214 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1215 assertEquals(3, mManager.getRemainingCallCount()); 1216 }); 1217 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1218 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1219 }); 1220 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1221 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1222 }); 1223 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1224 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1225 }); 1226 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1227 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1228 }); 1229 1230 mInjectedCurrentTimeMillis++; 1231 1232 // Do the same thing one more time. This would catch the bug with mixuing up 1233 // the current time and the elapsed time. 1234 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1235 mManager.updateShortcuts(list(makeShortcut("s"))); 1236 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1237 }); 1238 1239 mService.mUidObserver.onUidStateChanged( 1240 CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 1241 mService.mUidObserver.onUidStateChanged( 1242 CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING); 1243 1244 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1245 assertEquals(3, mManager.getRemainingCallCount()); 1246 }); 1247 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1248 assertEquals(3, mManager.getRemainingCallCount()); 1249 }); 1250 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1251 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1252 }); 1253 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1254 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1255 }); 1256 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1257 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1258 }); 1259 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1260 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1261 }); 1262 1263 mInjectedCurrentTimeMillis++; 1264 1265 // Package 1 on user-10 comes to foreground. 1266 // Now, also try calling some APIs and make sure foreground apps don't get throttled. 1267 mService.mUidObserver.onUidStateChanged( 1268 UserHandle.getUid(USER_10, CALLING_UID_1), 1269 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 1270 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1271 assertEquals(3, mManager.getRemainingCallCount()); 1272 1273 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1274 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1275 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1276 1277 assertEquals(0, mManager.getRemainingCallCount()); 1278 }); 1279 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1280 assertEquals(3, mManager.getRemainingCallCount()); 1281 1282 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1283 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1284 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1285 1286 assertEquals(0, mManager.getRemainingCallCount()); 1287 }); 1288 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1289 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1290 1291 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1292 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1293 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1294 1295 assertEquals(0, mManager.getRemainingCallCount()); 1296 }); 1297 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1298 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1299 1300 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1301 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1302 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1303 1304 assertEquals(0, mManager.getRemainingCallCount()); 1305 }); 1306 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1307 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1308 1309 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1310 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1311 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1312 1313 assertEquals(0, mManager.getRemainingCallCount()); 1314 }); 1315 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1316 assertEquals(3, mManager.getRemainingCallCount()); 1317 1318 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1319 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1320 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1321 1322 assertEquals(3, mManager.getRemainingCallCount()); // Still 3! 1323 }); 1324 } 1325 1326 1327 public void testThrottling_resetByInternalCall() throws Exception { 1328 prepareCrossProfileDataSet(); 1329 1330 dumpsysOnLogcat("Before save & load"); 1331 1332 mService.saveDirtyInfo(); 1333 initService(); 1334 1335 // First, all packages have less than 3 (== initial value) remaining calls. 1336 1337 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1338 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1339 }); 1340 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1341 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1342 }); 1343 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1344 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1345 }); 1346 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1347 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1348 }); 1349 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1350 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1351 }); 1352 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1353 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1354 }); 1355 1356 // Simulate a call from sys UI. 1357 mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING); 1358 mService.onApplicationActive(CALLING_PACKAGE_1, USER_0); 1359 1360 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1361 assertEquals(3, mManager.getRemainingCallCount()); 1362 }); 1363 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1364 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1365 }); 1366 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1367 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1368 }); 1369 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1370 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1371 }); 1372 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1373 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1374 }); 1375 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1376 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1377 }); 1378 1379 mService.onApplicationActive(CALLING_PACKAGE_3, USER_0); 1380 1381 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1382 assertEquals(3, mManager.getRemainingCallCount()); 1383 }); 1384 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1385 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1386 }); 1387 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1388 assertEquals(3, mManager.getRemainingCallCount()); 1389 }); 1390 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1391 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1392 }); 1393 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1394 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1395 }); 1396 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1397 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1398 }); 1399 1400 mService.onApplicationActive(CALLING_PACKAGE_1, USER_10); 1401 1402 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1403 assertEquals(3, mManager.getRemainingCallCount()); 1404 }); 1405 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1406 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1407 }); 1408 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1409 assertEquals(3, mManager.getRemainingCallCount()); 1410 }); 1411 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1412 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1413 }); 1414 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1415 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1416 }); 1417 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1418 assertEquals(3, mManager.getRemainingCallCount()); 1419 }); 1420 } 1421} 1422