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