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