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