1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.server.pm; 17 18import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBundlesEqual; 19import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException; 20import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith; 21import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list; 22import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makeBundle; 23import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.parceled; 24import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set; 25 26import static org.mockito.Matchers.anyInt; 27import static org.mockito.Matchers.anyString; 28import static org.mockito.Matchers.eq; 29import static org.mockito.Mockito.reset; 30import static org.mockito.Mockito.times; 31import static org.mockito.Mockito.verify; 32 33import android.Manifest.permission; 34import android.app.ActivityManager; 35import android.content.ComponentName; 36import android.content.Intent; 37import android.content.pm.ShortcutInfo; 38import android.content.res.Resources; 39import android.graphics.BitmapFactory; 40import android.graphics.drawable.Icon; 41import android.net.Uri; 42import android.os.PersistableBundle; 43import android.os.UserHandle; 44import android.test.MoreAsserts; 45import android.test.suitebuilder.annotation.SmallTest; 46 47import com.android.frameworks.servicestests.R; 48import com.android.server.pm.ShortcutUser.PackageWithUser; 49 50import java.io.File; 51import java.io.FileWriter; 52import java.io.IOException; 53import java.io.PrintWriter; 54import java.io.StringWriter; 55import java.io.Writer; 56import 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 68public 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, si.getFlags()); 1135 assertNull(si.getBitmapPath()); // No icon. 1136 assertEquals(0, si.getIconResourceId()); 1137 1138 // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank. 1139 si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0); 1140 assertEquals(0, si.getRank()); 1141 } 1142 1143 public void testShortcutInfoSaveAndLoad_forBackup_resId() { 1144 setCaller(CALLING_PACKAGE_1, USER_0); 1145 1146 final Icon res32x32 = Icon.createWithResource(mClientContext, R.drawable.black_32x32); 1147 1148 PersistableBundle pb = new PersistableBundle(); 1149 pb.putInt("k", 1); 1150 ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext) 1151 .setId("id") 1152 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class)) 1153 .setIcon(res32x32) 1154 .setTitleResId(10) 1155 .setTextResId(11) 1156 .setDisabledMessageResId(12) 1157 .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz")) 1158 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 1159 .setRank(123) 1160 .setExtras(pb) 1161 .build(); 1162 1163 ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext) 1164 .setId("id2") 1165 .setTitle("x") 1166 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class)) 1167 .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val")) 1168 .setRank(456) 1169 .build(); 1170 1171 mManager.addDynamicShortcuts(list(sorig, sorig2)); 1172 1173 // Dynamic shortcuts won't be backed up, so we need to pin it. 1174 setCaller(LAUNCHER_1, USER_0); 1175 mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0); 1176 1177 // Do backup & restore. 1178 backupAndRestore(); 1179 1180 mService.handleUnlockUser(USER_0); // Load user-0. 1181 1182 ShortcutInfo si; 1183 si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0); 1184 1185 assertEquals(CALLING_PACKAGE_1, si.getPackage()); 1186 assertEquals("id", si.getId()); 1187 assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName()); 1188 assertEquals(null, si.getIcon()); 1189 assertEquals(10, si.getTitleResId()); 1190 assertEquals("r10", si.getTitleResName()); 1191 assertEquals(11, si.getTextResId()); 1192 assertEquals("r11", si.getTextResName()); 1193 assertEquals(12, si.getDisabledMessageResourceId()); 1194 assertEquals("r12", si.getDisabledMessageResName()); 1195 assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories()); 1196 assertEquals("action", si.getIntent().getAction()); 1197 assertEquals("val", si.getIntent().getStringExtra("key")); 1198 assertEquals(0, si.getRank()); 1199 assertEquals(1, si.getExtras().getInt("k")); 1200 1201 assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags()); 1202 assertNull(si.getBitmapPath()); // No icon. 1203 assertEquals(0, si.getIconResourceId()); 1204 assertEquals(null, si.getIconResName()); 1205 1206 // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank. 1207 si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0); 1208 assertEquals(0, si.getRank()); 1209 } 1210 1211 private void checkShortcutInfoSaveAndLoad_intents(Intent intent) { 1212 assertTrue(mManager.setDynamicShortcuts(list( 1213 makeShortcutWithIntent("s1", intent)))); 1214 initService(); 1215 mService.handleUnlockUser(USER_0); 1216 1217 assertWith(getCallerShortcuts()) 1218 .haveIds("s1") 1219 .forShortcutWithId("s1", si -> { 1220 assertEquals(intent.getAction(), si.getIntent().getAction()); 1221 assertEquals(intent.getData(), si.getIntent().getData()); 1222 assertEquals(intent.getComponent(), si.getIntent().getComponent()); 1223 assertBundlesEqual(intent.getExtras(), si.getIntent().getExtras()); 1224 }); 1225 } 1226 1227 private void checkShortcutInfoSaveAndLoad_intents(Intent... intents) { 1228 assertTrue(mManager.setDynamicShortcuts(list( 1229 makeShortcutWithIntents("s1", intents)))); 1230 initService(); 1231 mService.handleUnlockUser(USER_0); 1232 1233 assertWith(getCallerShortcuts()) 1234 .haveIds("s1") 1235 .forShortcutWithId("s1", si -> { 1236 1237 final Intent[] actual = si.getIntents(); 1238 assertEquals(intents.length, actual.length); 1239 1240 for (int i = 0; i < intents.length; i++) { 1241 assertEquals(intents[i].getAction(), actual[i].getAction()); 1242 assertEquals(intents[i].getData(), actual[i].getData()); 1243 assertEquals(intents[i].getComponent(), actual[i].getComponent()); 1244 assertEquals(intents[i].getFlags(), actual[i].getFlags()); 1245 assertBundlesEqual(intents[i].getExtras(), actual[i].getExtras()); 1246 } 1247 }); 1248 } 1249 1250 public void testShortcutInfoSaveAndLoad_intents() { 1251 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW)); 1252 1253 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1254 1255 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN)); 1256 1257 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1258 1259 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW, 1260 Uri.parse("http://www.example.com/"))); 1261 1262 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1263 1264 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN, 1265 Uri.parse("http://www.example.com/"))); 1266 1267 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1268 1269 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW) 1270 .setComponent(new ComponentName("a", "b"))); 1271 1272 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1273 1274 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN) 1275 .setComponent(new ComponentName("a", "b"))); 1276 1277 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1278 1279 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_VIEW) 1280 .putExtras(makeBundle("a", "b"))); 1281 1282 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1283 1284 1285 checkShortcutInfoSaveAndLoad_intents(new Intent(Intent.ACTION_MAIN) 1286 .putExtras(makeBundle("a", "b"))); 1287 1288 mInjectedCurrentTimeMillis += INTERVAL; // reset throttling. 1289 1290 // Multi-intents 1291 checkShortcutInfoSaveAndLoad_intents( 1292 new Intent(Intent.ACTION_MAIN).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK), 1293 new Intent(Intent.ACTION_VIEW).setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) 1294 ); 1295 1296 checkShortcutInfoSaveAndLoad_intents( 1297 new Intent(Intent.ACTION_MAIN).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) 1298 .setComponent(new ComponentName("a", "b")), 1299 new Intent(Intent.ACTION_VIEW) 1300 .setComponent(new ComponentName("a", "b")) 1301 ); 1302 1303 checkShortcutInfoSaveAndLoad_intents( 1304 new Intent(Intent.ACTION_MAIN) 1305 .setComponent(new ComponentName("a", "b")), 1306 new Intent(Intent.ACTION_VIEW).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) 1307 .setComponent(new ComponentName("a", "b")), 1308 new Intent("xyz").setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK 1309 | Intent.FILL_IN_COMPONENT) 1310 .setComponent(new ComponentName("a", "b")).putExtras( 1311 makeBundle("xx", "yy")) 1312 ); 1313 } 1314 1315 public void testThrottling() { 1316 final ShortcutInfo si1 = makeShortcut("shortcut1"); 1317 1318 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1319 assertEquals(2, mManager.getRemainingCallCount()); 1320 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1321 1322 mInjectedCurrentTimeMillis++; 1323 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1324 assertEquals(1, mManager.getRemainingCallCount()); 1325 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1326 1327 mInjectedCurrentTimeMillis++; 1328 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1329 assertEquals(0, mManager.getRemainingCallCount()); 1330 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1331 1332 // Reached the max 1333 1334 mInjectedCurrentTimeMillis++; 1335 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1336 assertEquals(0, mManager.getRemainingCallCount()); 1337 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1338 1339 // Still throttled 1340 mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1; 1341 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1342 assertEquals(0, mManager.getRemainingCallCount()); 1343 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1344 1345 // Now it should work. 1346 mInjectedCurrentTimeMillis++; 1347 assertTrue(mManager.setDynamicShortcuts(list(si1))); // fail 1348 assertEquals(2, mManager.getRemainingCallCount()); 1349 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 1350 1351 mInjectedCurrentTimeMillis++; 1352 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1353 assertEquals(1, mManager.getRemainingCallCount()); 1354 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 1355 1356 mInjectedCurrentTimeMillis++; 1357 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1358 assertEquals(0, mManager.getRemainingCallCount()); 1359 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 1360 1361 mInjectedCurrentTimeMillis++; 1362 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1363 assertEquals(0, mManager.getRemainingCallCount()); 1364 assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime()); 1365 1366 // 4 hours later... 1367 mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL; 1368 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1369 assertEquals(2, mManager.getRemainingCallCount()); 1370 assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime()); 1371 1372 mInjectedCurrentTimeMillis++; 1373 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1374 assertEquals(1, mManager.getRemainingCallCount()); 1375 assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime()); 1376 1377 // Make sure getRemainingCallCount() itself gets reset without calling setDynamicShortcuts(). 1378 mInjectedCurrentTimeMillis = START_TIME + 8 * INTERVAL; 1379 assertEquals(3, mManager.getRemainingCallCount()); 1380 assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime()); 1381 1382 mInjectedCurrentTimeMillis++; 1383 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1384 assertEquals(2, mManager.getRemainingCallCount()); 1385 assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime()); 1386 } 1387 1388 public void testThrottling_rewind() { 1389 final ShortcutInfo si1 = makeShortcut("shortcut1"); 1390 1391 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1392 assertEquals(2, mManager.getRemainingCallCount()); 1393 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1394 1395 mInjectedCurrentTimeMillis = 12345; // Clock reset! 1396 1397 // Since the clock looks invalid, the counter shouldn't have reset. 1398 assertEquals(2, mManager.getRemainingCallCount()); 1399 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1400 1401 // Forward again. Still haven't reset yet. 1402 mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1; 1403 assertEquals(2, mManager.getRemainingCallCount()); 1404 assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); 1405 1406 // Now rewind -- this will reset the counters. 1407 mInjectedCurrentTimeMillis = START_TIME - 100000; 1408 assertEquals(3, mManager.getRemainingCallCount()); 1409 1410 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1411 assertEquals(2, mManager.getRemainingCallCount()); 1412 1413 // Forward again, should be reset now. 1414 mInjectedCurrentTimeMillis += INTERVAL; 1415 assertEquals(3, mManager.getRemainingCallCount()); 1416 } 1417 1418 public void testThrottling_perPackage() { 1419 final ShortcutInfo si1 = makeShortcut("shortcut1"); 1420 1421 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1422 assertEquals(2, mManager.getRemainingCallCount()); 1423 1424 mInjectedCurrentTimeMillis++; 1425 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1426 assertEquals(1, mManager.getRemainingCallCount()); 1427 1428 mInjectedCurrentTimeMillis++; 1429 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1430 assertEquals(0, mManager.getRemainingCallCount()); 1431 1432 // Reached the max 1433 1434 mInjectedCurrentTimeMillis++; 1435 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1436 1437 // Try from a different caller. 1438 mInjectedClientPackage = CALLING_PACKAGE_2; 1439 mInjectedCallingUid = CALLING_UID_2; 1440 1441 // Need to create a new one wit the updated package name. 1442 final ShortcutInfo si2 = makeShortcut("shortcut1"); 1443 1444 assertEquals(3, mManager.getRemainingCallCount()); 1445 1446 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1447 assertEquals(2, mManager.getRemainingCallCount()); 1448 1449 mInjectedCurrentTimeMillis++; 1450 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1451 assertEquals(1, mManager.getRemainingCallCount()); 1452 1453 // Back to the original caller, still throttled. 1454 mInjectedClientPackage = CALLING_PACKAGE_1; 1455 mInjectedCallingUid = CALLING_UID_1; 1456 1457 mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1; 1458 assertEquals(0, mManager.getRemainingCallCount()); 1459 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1460 assertEquals(0, mManager.getRemainingCallCount()); 1461 1462 // Now it should work. 1463 mInjectedCurrentTimeMillis++; 1464 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1465 1466 mInjectedCurrentTimeMillis++; 1467 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1468 1469 mInjectedCurrentTimeMillis++; 1470 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1471 1472 mInjectedCurrentTimeMillis++; 1473 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1474 1475 mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL; 1476 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1477 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1478 assertTrue(mManager.setDynamicShortcuts(list(si1))); 1479 assertFalse(mManager.setDynamicShortcuts(list(si1))); 1480 1481 mInjectedClientPackage = CALLING_PACKAGE_2; 1482 mInjectedCallingUid = CALLING_UID_2; 1483 1484 assertEquals(3, mManager.getRemainingCallCount()); 1485 1486 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1487 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1488 assertTrue(mManager.setDynamicShortcuts(list(si2))); 1489 assertFalse(mManager.setDynamicShortcuts(list(si2))); 1490 } 1491 1492 public void testThrottling_localeChanges() { 1493 prepareCrossProfileDataSet(); 1494 1495 dumpsysOnLogcat("Before save & load"); 1496 1497 mService.saveDirtyInfo(); 1498 initService(); 1499 1500 mInjectedLocale = Locale.CHINA; 1501 mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED)); 1502 1503 // Note at this point only user-0 is loaded, and the counters are reset for this user, 1504 // but it will work for other users too because we check the locale change at any 1505 // API entry point. 1506 1507 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1508 assertEquals(3, mManager.getRemainingCallCount()); 1509 }); 1510 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1511 assertEquals(3, mManager.getRemainingCallCount()); 1512 }); 1513 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1514 assertEquals(3, mManager.getRemainingCallCount()); 1515 }); 1516 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1517 assertEquals(3, mManager.getRemainingCallCount()); 1518 }); 1519 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1520 assertEquals(3, mManager.getRemainingCallCount()); 1521 }); 1522 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1523 assertEquals(3, mManager.getRemainingCallCount()); 1524 }); 1525 1526 // Make sure even if we receive ACTION_LOCALE_CHANGED, if the locale hasn't actually 1527 // changed, we don't reset throttling. 1528 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1529 mManager.updateShortcuts(list()); 1530 assertEquals(2, mManager.getRemainingCallCount()); 1531 }); 1532 1533 mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED)); 1534 1535 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1536 assertEquals(2, mManager.getRemainingCallCount()); // Still 2. 1537 }); 1538 1539 mService.saveDirtyInfo(); 1540 initService(); 1541 1542 // The locale should be persisted, so it still shouldn't reset throttling. 1543 mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED)); 1544 1545 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1546 assertEquals(2, mManager.getRemainingCallCount()); // Still 2. 1547 }); 1548 } 1549 1550 public void testThrottling_foreground() throws Exception { 1551 prepareCrossProfileDataSet(); 1552 1553 dumpsysOnLogcat("Before save & load"); 1554 1555 mService.saveDirtyInfo(); 1556 initService(); 1557 1558 // We need to update the current time from time to time, since some of the internal checks 1559 // rely on the time being correctly incremented. 1560 mInjectedCurrentTimeMillis++; 1561 1562 // First, all packages have less than 3 (== initial value) remaining calls. 1563 1564 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1565 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1566 }); 1567 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1568 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1569 }); 1570 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1571 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1572 }); 1573 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1574 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1575 }); 1576 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1577 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1578 }); 1579 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1580 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1581 }); 1582 1583 mInjectedCurrentTimeMillis++; 1584 1585 // State changed, but not foreground, so no resetting. 1586 mService.mUidObserver.onUidStateChanged( 1587 CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0); 1588 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1589 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1590 }); 1591 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1592 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1593 }); 1594 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1595 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1596 }); 1597 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1598 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1599 }); 1600 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1601 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1602 }); 1603 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1604 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1605 }); 1606 1607 mInjectedCurrentTimeMillis++; 1608 1609 // State changed, package1 foreground, reset. 1610 mService.mUidObserver.onUidStateChanged( 1611 CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); 1612 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1613 assertEquals(3, mManager.getRemainingCallCount()); 1614 }); 1615 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1616 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1617 }); 1618 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1619 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1620 }); 1621 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1622 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1623 }); 1624 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1625 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1626 }); 1627 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1628 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1629 }); 1630 mService.mUidObserver.onUidStateChanged( 1631 CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0); 1632 1633 mInjectedCurrentTimeMillis++; 1634 1635 // Different app comes to foreground briefly, and goes back to background. 1636 // Now, make sure package 2's counter is reset, even in this case. 1637 mService.mUidObserver.onUidStateChanged( 1638 CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); 1639 mService.mUidObserver.onUidStateChanged( 1640 CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0); 1641 1642 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1643 assertEquals(3, mManager.getRemainingCallCount()); 1644 }); 1645 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1646 assertEquals(3, mManager.getRemainingCallCount()); 1647 }); 1648 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1649 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1650 }); 1651 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1652 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1653 }); 1654 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1655 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1656 }); 1657 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1658 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1659 }); 1660 1661 mInjectedCurrentTimeMillis++; 1662 1663 // Do the same thing one more time. This would catch the bug with mixuing up 1664 // the current time and the elapsed time. 1665 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1666 mManager.updateShortcuts(list(makeShortcut("s"))); 1667 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1668 }); 1669 1670 mService.mUidObserver.onUidStateChanged( 1671 CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); 1672 mService.mUidObserver.onUidStateChanged( 1673 CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0); 1674 1675 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1676 assertEquals(3, mManager.getRemainingCallCount()); 1677 }); 1678 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1679 assertEquals(3, mManager.getRemainingCallCount()); 1680 }); 1681 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1682 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1683 }); 1684 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1685 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1686 }); 1687 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1688 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1689 }); 1690 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1691 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1692 }); 1693 1694 mInjectedCurrentTimeMillis++; 1695 1696 // Package 1 on user-10 comes to foreground. 1697 // Now, also try calling some APIs and make sure foreground apps don't get throttled. 1698 mService.mUidObserver.onUidStateChanged( 1699 UserHandle.getUid(USER_10, CALLING_UID_1), 1700 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); 1701 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1702 assertEquals(3, mManager.getRemainingCallCount()); 1703 assertFalse(mManager.isRateLimitingActive()); 1704 1705 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1706 1707 assertEquals(2, mManager.getRemainingCallCount()); 1708 assertFalse(mManager.isRateLimitingActive()); 1709 1710 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1711 1712 assertEquals(1, mManager.getRemainingCallCount()); 1713 assertFalse(mManager.isRateLimitingActive()); 1714 1715 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1716 1717 assertEquals(0, mManager.getRemainingCallCount()); 1718 assertTrue(mManager.isRateLimitingActive()); 1719 }); 1720 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1721 assertEquals(3, mManager.getRemainingCallCount()); 1722 1723 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1724 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1725 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1726 1727 assertEquals(0, mManager.getRemainingCallCount()); 1728 assertTrue(mManager.isRateLimitingActive()); 1729 }); 1730 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1731 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1732 1733 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1734 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1735 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1736 1737 assertEquals(0, mManager.getRemainingCallCount()); 1738 assertTrue(mManager.isRateLimitingActive()); 1739 }); 1740 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1741 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1742 1743 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1744 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1745 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1746 1747 assertEquals(0, mManager.getRemainingCallCount()); 1748 assertTrue(mManager.isRateLimitingActive()); 1749 }); 1750 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1751 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1752 1753 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1754 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1755 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1756 1757 assertEquals(0, mManager.getRemainingCallCount()); 1758 assertTrue(mManager.isRateLimitingActive()); 1759 }); 1760 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1761 assertEquals(3, mManager.getRemainingCallCount()); 1762 1763 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1764 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1765 mManager.setDynamicShortcuts(list(makeShortcut("s"))); 1766 1767 assertEquals(3, mManager.getRemainingCallCount()); // Still 3! 1768 assertFalse(mManager.isRateLimitingActive()); 1769 }); 1770 } 1771 1772 1773 public void testThrottling_resetByInternalCall() throws Exception { 1774 prepareCrossProfileDataSet(); 1775 1776 dumpsysOnLogcat("Before save & load"); 1777 1778 mService.saveDirtyInfo(); 1779 initService(); 1780 1781 // First, all packages have less than 3 (== initial value) remaining calls. 1782 1783 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1784 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1785 }); 1786 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1787 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1788 }); 1789 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1790 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1791 }); 1792 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1793 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1794 }); 1795 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1796 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1797 }); 1798 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1799 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1800 }); 1801 1802 // Simulate a call from sys UI. 1803 mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING); 1804 mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0); 1805 1806 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1807 assertEquals(3, mManager.getRemainingCallCount()); 1808 }); 1809 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1810 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1811 }); 1812 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1813 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1814 }); 1815 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1816 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1817 }); 1818 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1819 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1820 }); 1821 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1822 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1823 }); 1824 1825 mManager.onApplicationActive(CALLING_PACKAGE_3, USER_0); 1826 1827 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1828 assertEquals(3, mManager.getRemainingCallCount()); 1829 }); 1830 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1831 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1832 }); 1833 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1834 assertEquals(3, mManager.getRemainingCallCount()); 1835 }); 1836 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1837 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1838 }); 1839 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1840 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1841 }); 1842 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1843 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1844 }); 1845 1846 mManager.onApplicationActive(CALLING_PACKAGE_1, USER_10); 1847 1848 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 1849 assertEquals(3, mManager.getRemainingCallCount()); 1850 }); 1851 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 1852 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1853 }); 1854 runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { 1855 assertEquals(3, mManager.getRemainingCallCount()); 1856 }); 1857 runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { 1858 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1859 }); 1860 runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { 1861 MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount()); 1862 }); 1863 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1864 assertEquals(3, mManager.getRemainingCallCount()); 1865 }); 1866 } 1867 1868 public void testReportShortcutUsed() { 1869 mRunningUsers.put(USER_10, true); 1870 1871 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 1872 reset(mMockUsageStatsManagerInternal); 1873 1874 // Report with an nonexistent shortcut. 1875 mManager.reportShortcutUsed("s1"); 1876 verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage( 1877 anyString(), anyString(), anyInt()); 1878 1879 // Publish s2, but s1 still doesn't exist. 1880 mManager.setDynamicShortcuts(list(makeShortcut("s2"))); 1881 mManager.reportShortcutUsed("s1"); 1882 verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage( 1883 anyString(), anyString(), anyInt()); 1884 1885 mManager.reportShortcutUsed("s2"); 1886 verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage( 1887 eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_10)); 1888 1889 }); 1890 runWithCaller(CALLING_PACKAGE_2, USER_10, () -> { 1891 // Try with a different package. 1892 reset(mMockUsageStatsManagerInternal); 1893 1894 // Report with an nonexistent shortcut. 1895 mManager.reportShortcutUsed("s2"); 1896 verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage( 1897 anyString(), anyString(), anyInt()); 1898 1899 // Publish s2, but s1 still doesn't exist. 1900 mManager.setDynamicShortcuts(list(makeShortcut("s3"))); 1901 mManager.reportShortcutUsed("s2"); 1902 verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage( 1903 anyString(), anyString(), anyInt()); 1904 1905 mManager.reportShortcutUsed("s3"); 1906 verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage( 1907 eq(CALLING_PACKAGE_2), eq("s3"), eq(USER_10)); 1908 1909 }); 1910 } 1911 1912 // Test for a ShortcutInfo method. 1913 public void testGetResourcePackageName() { 1914 assertEquals(null, ShortcutInfo.getResourcePackageName("")); 1915 assertEquals(null, ShortcutInfo.getResourcePackageName("abc")); 1916 assertEquals("p", ShortcutInfo.getResourcePackageName("p:")); 1917 assertEquals("p", ShortcutInfo.getResourcePackageName("p:xx")); 1918 assertEquals("pac", ShortcutInfo.getResourcePackageName("pac:")); 1919 } 1920 1921 // Test for a ShortcutInfo method. 1922 public void testGetResourceTypeName() { 1923 assertEquals(null, ShortcutInfo.getResourceTypeName("")); 1924 assertEquals(null, ShortcutInfo.getResourceTypeName(":")); 1925 assertEquals(null, ShortcutInfo.getResourceTypeName("/")); 1926 assertEquals(null, ShortcutInfo.getResourceTypeName("/:")); 1927 assertEquals("a", ShortcutInfo.getResourceTypeName(":a/")); 1928 assertEquals("type", ShortcutInfo.getResourceTypeName("xxx:type/yyy")); 1929 } 1930 1931 // Test for a ShortcutInfo method. 1932 public void testGetResourceTypeAndEntryName() { 1933 assertEquals(null, ShortcutInfo.getResourceTypeAndEntryName("")); 1934 assertEquals(null, ShortcutInfo.getResourceTypeAndEntryName("abc")); 1935 assertEquals("", ShortcutInfo.getResourceTypeAndEntryName("p:")); 1936 assertEquals("x", ShortcutInfo.getResourceTypeAndEntryName(":x")); 1937 assertEquals("x", ShortcutInfo.getResourceTypeAndEntryName("p:x")); 1938 assertEquals("xyz", ShortcutInfo.getResourceTypeAndEntryName("pac:xyz")); 1939 } 1940 1941 // Test for a ShortcutInfo method. 1942 public void testGetResourceEntryName() { 1943 assertEquals(null, ShortcutInfo.getResourceEntryName("")); 1944 assertEquals(null, ShortcutInfo.getResourceEntryName("ab:")); 1945 assertEquals("", ShortcutInfo.getResourceEntryName("/")); 1946 assertEquals("abc", ShortcutInfo.getResourceEntryName("/abc")); 1947 assertEquals("abc", ShortcutInfo.getResourceEntryName("xyz/abc")); 1948 } 1949 1950 // Test for a ShortcutInfo method. 1951 public void testLookUpResourceName_systemResources() { 1952 // For android system resources, lookUpResourceName will simply return the value as a 1953 // string, regardless of "withType". 1954 final Resources res = getTestContext().getResources(); 1955 1956 assertEquals("" + android.R.string.cancel, ShortcutInfo.lookUpResourceName(res, 1957 android.R.string.cancel, true, getTestContext().getPackageName())); 1958 assertEquals("" + android.R.drawable.alert_dark_frame, ShortcutInfo.lookUpResourceName(res, 1959 android.R.drawable.alert_dark_frame, true, getTestContext().getPackageName())); 1960 assertEquals("" + android.R.string.cancel, ShortcutInfo.lookUpResourceName(res, 1961 android.R.string.cancel, false, getTestContext().getPackageName())); 1962 } 1963 1964 public void testLookUpResourceName_appResources() { 1965 final Resources res = getTestContext().getResources(); 1966 1967 assertEquals("shortcut_text1", ShortcutInfo.lookUpResourceName(res, 1968 R.string.shortcut_text1, false, getTestContext().getPackageName())); 1969 assertEquals("string/shortcut_text1", ShortcutInfo.lookUpResourceName(res, 1970 R.string.shortcut_text1, true, getTestContext().getPackageName())); 1971 1972 assertEquals("black_16x64", ShortcutInfo.lookUpResourceName(res, 1973 R.drawable.black_16x64, false, getTestContext().getPackageName())); 1974 assertEquals("drawable/black_16x64", ShortcutInfo.lookUpResourceName(res, 1975 R.drawable.black_16x64, true, getTestContext().getPackageName())); 1976 } 1977 1978 // Test for a ShortcutInfo method. 1979 public void testLookUpResourceId_systemResources() { 1980 final Resources res = getTestContext().getResources(); 1981 1982 assertEquals(android.R.string.cancel, ShortcutInfo.lookUpResourceId(res, 1983 "" + android.R.string.cancel, null, 1984 getTestContext().getPackageName())); 1985 assertEquals(android.R.drawable.alert_dark_frame, ShortcutInfo.lookUpResourceId(res, 1986 "" + android.R.drawable.alert_dark_frame, null, 1987 getTestContext().getPackageName())); 1988 } 1989 1990 // Test for a ShortcutInfo method. 1991 public void testLookUpResourceId_appResources() { 1992 final Resources res = getTestContext().getResources(); 1993 1994 assertEquals(R.string.shortcut_text1, 1995 ShortcutInfo.lookUpResourceId(res, "shortcut_text1", "string", 1996 getTestContext().getPackageName())); 1997 1998 assertEquals(R.string.shortcut_text1, 1999 ShortcutInfo.lookUpResourceId(res, "string/shortcut_text1", null, 2000 getTestContext().getPackageName())); 2001 2002 assertEquals(R.drawable.black_16x64, 2003 ShortcutInfo.lookUpResourceId(res, "black_16x64", "drawable", 2004 getTestContext().getPackageName())); 2005 2006 assertEquals(R.drawable.black_16x64, 2007 ShortcutInfo.lookUpResourceId(res, "drawable/black_16x64", null, 2008 getTestContext().getPackageName())); 2009 } 2010 2011 public void testDumpCheckin() throws IOException { 2012 prepareCrossProfileDataSet(); 2013 2014 // prepareCrossProfileDataSet() doesn't set any icons, so do set here. 2015 final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32); 2016 final Icon res64x64 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64); 2017 final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource( 2018 getTestContext().getResources(), R.drawable.black_32x32)); 2019 final Icon bmp64x64 = Icon.createWithBitmap(BitmapFactory.decodeResource( 2020 getTestContext().getResources(), R.drawable.black_64x64)); 2021 2022 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 2023 assertTrue(mManager.setDynamicShortcuts(list( 2024 makeShortcutWithIcon("res32x32", res32x32), 2025 makeShortcutWithIcon("res64x64", res64x64), 2026 makeShortcutWithIcon("bmp32x32", bmp32x32), 2027 makeShortcutWithIcon("bmp64x64", bmp64x64)))); 2028 }); 2029 2030 // We can't predict the compressed bitmap sizes, so get the real sizes here. 2031 final long bitmapTotal = 2032 new File(getBitmapAbsPath(USER_0, CALLING_PACKAGE_2, "bmp32x32")).length() + 2033 new File(getBitmapAbsPath(USER_0, CALLING_PACKAGE_2, "bmp64x64")).length(); 2034 2035 // Read the expected output and inject the bitmap size. 2036 final String expected = readTestAsset("shortcut/dumpsys_expected.txt") 2037 .replace("***BITMAP_SIZE***", String.valueOf(bitmapTotal)); 2038 2039 assertEquals(expected, dumpCheckin()); 2040 } 2041 2042 /** 2043 * Make sure the legacy file format that only supported a single intent per shortcut 2044 * can still be read. 2045 */ 2046 public void testLoadLegacySavedFile() throws Exception { 2047 final File path = mService.getUserFile(USER_0); 2048 path.getParentFile().mkdirs(); 2049 try (Writer w = new FileWriter(path)) { 2050 w.write(readTestAsset("shortcut/shortcut_legacy_file.xml")); 2051 }; 2052 initService(); 2053 mService.handleUnlockUser(USER_0); 2054 2055 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 2056 assertWith(getCallerShortcuts()) 2057 .haveIds("manifest-shortcut-storage") 2058 .forShortcutWithId("manifest-shortcut-storage", si -> { 2059 assertEquals("android.settings.INTERNAL_STORAGE_SETTINGS", 2060 si.getIntent().getAction()); 2061 assertEquals(12345, si.getIntent().getIntExtra("key", 0)); 2062 }); 2063 }); 2064 } 2065 2066 public void testIsUserUnlocked() { 2067 mRunningUsers.clear(); 2068 mUnlockedUsers.clear(); 2069 2070 assertFalse(mService.isUserUnlockedL(USER_0)); 2071 assertFalse(mService.isUserUnlockedL(USER_10)); 2072 2073 // Start user 0, still locked. 2074 mRunningUsers.put(USER_0, true); 2075 assertFalse(mService.isUserUnlockedL(USER_0)); 2076 assertFalse(mService.isUserUnlockedL(USER_10)); 2077 2078 // Unlock user. 2079 mUnlockedUsers.put(USER_0, true); 2080 assertTrue(mService.isUserUnlockedL(USER_0)); 2081 assertFalse(mService.isUserUnlockedL(USER_10)); 2082 2083 // Clear again. 2084 mRunningUsers.clear(); 2085 mUnlockedUsers.clear(); 2086 2087 // Directly call the lifecycle event. Now also locked. 2088 mService.handleUnlockUser(USER_0); 2089 assertTrue(mService.isUserUnlockedL(USER_0)); 2090 assertFalse(mService.isUserUnlockedL(USER_10)); 2091 2092 // Directly call the stop lifecycle event. Goes back to the initial state. 2093 mService.handleStopUser(USER_0); 2094 assertFalse(mService.isUserUnlockedL(USER_0)); 2095 assertFalse(mService.isUserUnlockedL(USER_10)); 2096 } 2097 2098 public void testEphemeralApp() { 2099 mRunningUsers.put(USER_10, true); // this test needs user 10. 2100 2101 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 2102 assertWith(mManager.getDynamicShortcuts()).isEmpty(); 2103 }); 2104 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 2105 assertWith(mManager.getDynamicShortcuts()).isEmpty(); 2106 }); 2107 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 2108 assertWith(mManager.getDynamicShortcuts()).isEmpty(); 2109 }); 2110 // Make package 1 ephemeral. 2111 mEphemeralPackages.add(PackageWithUser.of(USER_0, CALLING_PACKAGE_1)); 2112 2113 runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { 2114 assertExpectException(IllegalStateException.class, "Ephemeral apps", () -> { 2115 mManager.getDynamicShortcuts(); 2116 }); 2117 }); 2118 runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { 2119 assertWith(mManager.getDynamicShortcuts()).isEmpty(); 2120 }); 2121 runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { 2122 assertWith(mManager.getDynamicShortcuts()).isEmpty(); 2123 }); 2124 } 2125} 2126