1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app.role.cts; 18 19 import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity; 20 import static com.android.compatibility.common.util.SystemUtil.runShellCommand; 21 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 22 import static com.android.compatibility.common.util.UiAutomatorUtils.waitFindObject; 23 import static com.android.compatibility.common.util.UiAutomatorUtils.waitFindObjectOrNull; 24 25 import static com.google.common.truth.Truth.assertThat; 26 27 import static org.junit.Assert.assertThrows; 28 import static org.junit.Assert.fail; 29 import static org.junit.Assume.assumeTrue; 30 31 import android.app.Activity; 32 import android.app.Instrumentation; 33 import android.app.role.OnRoleHoldersChangedListener; 34 import android.app.role.RoleManager; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.pm.PackageManager; 39 import android.content.pm.PermissionInfo; 40 import android.os.Build; 41 import android.os.Process; 42 import android.os.UserHandle; 43 import android.provider.Settings; 44 import android.provider.Telephony; 45 import android.support.test.uiautomator.By; 46 import android.support.test.uiautomator.BySelector; 47 import android.support.test.uiautomator.UiObject2; 48 import android.support.test.uiautomator.UiObjectNotFoundException; 49 import android.util.Pair; 50 51 import androidx.annotation.NonNull; 52 import androidx.annotation.Nullable; 53 import androidx.test.InstrumentationRegistry; 54 import androidx.test.filters.SdkSuppress; 55 import androidx.test.rule.ActivityTestRule; 56 import androidx.test.runner.AndroidJUnit4; 57 58 import com.android.compatibility.common.util.DisableAnimationRule; 59 import com.android.compatibility.common.util.FreezeRotationRule; 60 import com.android.compatibility.common.util.TestUtils; 61 import com.android.compatibility.common.util.ThrowingRunnable; 62 import com.android.compatibility.common.util.UiAutomatorUtils; 63 64 import org.junit.After; 65 import org.junit.Before; 66 import org.junit.Rule; 67 import org.junit.Test; 68 import org.junit.runner.RunWith; 69 70 import java.io.IOException; 71 import java.util.Collections; 72 import java.util.List; 73 import java.util.Objects; 74 import java.util.concurrent.CompletableFuture; 75 import java.util.concurrent.TimeUnit; 76 import java.util.concurrent.TimeoutException; 77 import java.util.function.Consumer; 78 79 /** 80 * Tests {@link RoleManager}. 81 */ 82 @RunWith(AndroidJUnit4.class) 83 public class RoleManagerTest { 84 85 private static final long TIMEOUT_MILLIS = 15 * 1000; 86 87 private static final long UNEXPECTED_TIMEOUT_MILLIS = 1000; 88 89 private static final String ROLE_NAME = RoleManager.ROLE_BROWSER; 90 private static final String ROLE_SHORT_LABEL = "Browser app"; 91 92 private static final String APP_APK_PATH = "/data/local/tmp/cts/role/CtsRoleTestApp.apk"; 93 private static final String APP_PACKAGE_NAME = "android.app.role.cts.app"; 94 private static final String APP_LABEL = "CtsRoleTestApp"; 95 private static final String APP_IS_ROLE_HELD_ACTIVITY_NAME = APP_PACKAGE_NAME 96 + ".IsRoleHeldActivity"; 97 private static final String APP_IS_ROLE_HELD_EXTRA_IS_ROLE_HELD = APP_PACKAGE_NAME 98 + ".extra.IS_ROLE_HELD"; 99 private static final String APP_REQUEST_ROLE_ACTIVITY_NAME = APP_PACKAGE_NAME 100 + ".RequestRoleActivity"; 101 private static final String APP_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME = APP_PACKAGE_NAME 102 + ".ChangeDefaultDialerActivity"; 103 private static final String APP_CHANGE_DEFAULT_SMS_ACTIVITY_NAME = APP_PACKAGE_NAME 104 + ".ChangeDefaultSmsActivity"; 105 106 private static final String APP_28_APK_PATH = "/data/local/tmp/cts/role/CtsRoleTestApp28.apk"; 107 private static final String APP_28_PACKAGE_NAME = "android.app.role.cts.app28"; 108 private static final String APP_28_LABEL = "CtsRoleTestApp28"; 109 private static final String APP_28_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME = APP_28_PACKAGE_NAME 110 + ".ChangeDefaultDialerActivity"; 111 private static final String APP_28_CHANGE_DEFAULT_SMS_ACTIVITY_NAME = APP_28_PACKAGE_NAME 112 + ".ChangeDefaultSmsActivity"; 113 114 private static final String APP_33_WITHOUT_INCALLSERVICE_APK_PATH = 115 "/data/local/tmp/cts/role/CtsRoleTestApp33WithoutInCallService.apk"; 116 private static final String APP_33_WITHOUT_INCALLSERVICE_PACKAGE_NAME = 117 "android.app.role.cts.app33WithoutInCallService"; 118 119 private static final String PERMISSION_MANAGE_ROLES_FROM_CONTROLLER = 120 "com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER"; 121 122 private static final Instrumentation sInstrumentation = 123 InstrumentationRegistry.getInstrumentation(); 124 private static final Context sContext = InstrumentationRegistry.getTargetContext(); 125 private static final PackageManager sPackageManager = sContext.getPackageManager(); 126 private static final RoleManager sRoleManager = sContext.getSystemService(RoleManager.class); 127 128 @Rule 129 public DisableAnimationRule mDisableAnimationRule = new DisableAnimationRule(); 130 131 @Rule 132 public FreezeRotationRule mFreezeRotationRule = new FreezeRotationRule(); 133 134 @Rule 135 public ActivityTestRule<WaitForResultActivity> mActivityRule = 136 new ActivityTestRule<>(WaitForResultActivity.class); 137 138 private String mRoleHolder; 139 140 @Before saveRoleHolder()141 public void saveRoleHolder() throws Exception { 142 List<String> roleHolders = getRoleHolders(ROLE_NAME); 143 mRoleHolder = !roleHolders.isEmpty() ? roleHolders.get(0) : null; 144 145 if (Objects.equals(mRoleHolder, APP_PACKAGE_NAME)) { 146 removeRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 147 mRoleHolder = null; 148 } 149 } 150 151 @After restoreRoleHolder()152 public void restoreRoleHolder() throws Exception { 153 removeRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 154 155 if (mRoleHolder != null) { 156 addRoleHolder(ROLE_NAME, mRoleHolder); 157 } 158 159 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, false); 160 } 161 162 @Before installApp()163 public void installApp() throws Exception { 164 installPackage(APP_APK_PATH); 165 installPackage(APP_28_APK_PATH); 166 installPackage(APP_33_WITHOUT_INCALLSERVICE_APK_PATH); 167 } 168 169 @After uninstallApp()170 public void uninstallApp() throws Exception { 171 uninstallPackage(APP_PACKAGE_NAME); 172 uninstallPackage(APP_28_PACKAGE_NAME); 173 uninstallPackage(APP_33_WITHOUT_INCALLSERVICE_PACKAGE_NAME); 174 } 175 176 @Before wakeUpScreen()177 public void wakeUpScreen() throws IOException { 178 runShellCommand(sInstrumentation, "input keyevent KEYCODE_WAKEUP"); 179 } 180 181 @Before closeNotificationShade()182 public void closeNotificationShade() { 183 sContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); 184 } 185 186 @Test requestRoleIntentHasPermissionControllerPackage()187 public void requestRoleIntentHasPermissionControllerPackage() throws Exception { 188 Intent intent = sRoleManager.createRequestRoleIntent(ROLE_NAME); 189 190 assertThat(intent.getPackage()).isEqualTo( 191 sPackageManager.getPermissionControllerPackageName()); 192 } 193 194 @Test requestRoleIntentHasExtraRoleName()195 public void requestRoleIntentHasExtraRoleName() throws Exception { 196 Intent intent = sRoleManager.createRequestRoleIntent(ROLE_NAME); 197 198 assertThat(intent.getStringExtra(Intent.EXTRA_ROLE_NAME)).isEqualTo(ROLE_NAME); 199 } 200 201 @Test requestRoleAndDenyThenIsNotRoleHolder()202 public void requestRoleAndDenyThenIsNotRoleHolder() throws Exception { 203 requestRole(ROLE_NAME); 204 respondToRoleRequest(false); 205 206 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, false); 207 } 208 209 @Test requestRoleAndAllowThenIsRoleHolder()210 public void requestRoleAndAllowThenIsRoleHolder() throws Exception { 211 requestRole(ROLE_NAME); 212 respondToRoleRequest(true); 213 214 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, true); 215 } 216 217 @Test requestRoleFirstTimeNoDontAskAgain()218 public void requestRoleFirstTimeNoDontAskAgain() throws Exception { 219 requestRole(ROLE_NAME); 220 UiObject2 dontAskAgainCheck = findDontAskAgainCheck(false); 221 222 assertThat(dontAskAgainCheck).isNull(); 223 224 respondToRoleRequest(false); 225 } 226 227 @Test requestRoleAndDenyThenHasDontAskAgain()228 public void requestRoleAndDenyThenHasDontAskAgain() throws Exception { 229 requestRole(ROLE_NAME); 230 respondToRoleRequest(false); 231 232 requestRole(ROLE_NAME); 233 UiObject2 dontAskAgainCheck = findDontAskAgainCheck(); 234 235 assertThat(dontAskAgainCheck).isNotNull(); 236 237 respondToRoleRequest(false); 238 } 239 240 @Test requestRoleAndDenyWithDontAskAgainReturnsCanceled()241 public void requestRoleAndDenyWithDontAskAgainReturnsCanceled() throws Exception { 242 requestRole(ROLE_NAME); 243 respondToRoleRequest(false); 244 245 requestRole(ROLE_NAME); 246 findDontAskAgainCheck().click(); 247 Pair<Integer, Intent> result = clickButtonAndWaitForResult(true); 248 249 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 250 } 251 252 @Test requestRoleAndDenyWithDontAskAgainThenDeniedAutomatically()253 public void requestRoleAndDenyWithDontAskAgainThenDeniedAutomatically() throws Exception { 254 requestRole(ROLE_NAME); 255 respondToRoleRequest(false); 256 257 requestRole(ROLE_NAME); 258 findDontAskAgainCheck().click(); 259 clickButtonAndWaitForResult(true); 260 261 requestRole(ROLE_NAME); 262 Pair<Integer, Intent> result = waitForResult(); 263 264 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 265 } 266 267 @Test requestRoleAndDenyWithDontAskAgainAndClearDataThenShowsUiWithoutDontAskAgain()268 public void requestRoleAndDenyWithDontAskAgainAndClearDataThenShowsUiWithoutDontAskAgain() 269 throws Exception { 270 requestRole(ROLE_NAME); 271 respondToRoleRequest(false); 272 273 requestRole(ROLE_NAME); 274 findDontAskAgainCheck().click(); 275 clickButtonAndWaitForResult(true); 276 // Wait for the RequestRoleActivity inside the test app to be removed from our task so that 277 // when the test app is force stopped, our task isn't force finished and our 278 // WaitForResultActivity can survive. 279 Thread.sleep(5000); 280 281 clearPackageData(APP_PACKAGE_NAME); 282 // Wait for the don't ask again to be forgotten. 283 Thread.sleep(5000); 284 285 TestUtils.waitUntil("Find and respond to request role UI", () -> { 286 requestRole(ROLE_NAME); 287 UiObject2 cancelButton = waitFindObjectOrNull(By.res("android:id/button2")); 288 if (cancelButton == null) { 289 // Dialog not found, try again later. 290 return false; 291 } 292 UiObject2 dontAskAgainCheck = findDontAskAgainCheck(false); 293 294 assertThat(dontAskAgainCheck).isNull(); 295 296 respondToRoleRequest(false); 297 return true; 298 }); 299 } 300 301 @Test requestRoleAndDenyWithDontAskAgainAndReinstallThenShowsUiWithoutDontAskAgain()302 public void requestRoleAndDenyWithDontAskAgainAndReinstallThenShowsUiWithoutDontAskAgain() 303 throws Exception { 304 requestRole(ROLE_NAME); 305 respondToRoleRequest(false); 306 307 requestRole(ROLE_NAME); 308 findDontAskAgainCheck().click(); 309 clickButtonAndWaitForResult(true); 310 // Wait for the RequestRoleActivity inside the test app to be removed from our task so that 311 // when the test app is uninstalled, our task isn't force finished and our 312 // WaitForResultActivity can survive. 313 Thread.sleep(5000); 314 315 uninstallPackage(APP_PACKAGE_NAME); 316 // Wait for the don't ask again to be forgotten. 317 Thread.sleep(5000); 318 installPackage(APP_APK_PATH); 319 320 TestUtils.waitUntil("Find and respond to request role UI", () -> { 321 requestRole(ROLE_NAME); 322 UiObject2 cancelButton = waitFindObjectOrNull(By.res("android:id/button2")); 323 if (cancelButton == null) { 324 // Dialog not found, try again later. 325 return false; 326 } 327 UiObject2 dontAskAgainCheck = findDontAskAgainCheck(false); 328 329 assertThat(dontAskAgainCheck).isNull(); 330 331 respondToRoleRequest(false); 332 return true; 333 }); 334 } 335 336 @Test requestInvalidRoleThenDeniedAutomatically()337 public void requestInvalidRoleThenDeniedAutomatically() throws Exception { 338 requestRole("invalid"); 339 Pair<Integer, Intent> result = waitForResult(); 340 341 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 342 } 343 344 @Test requestUnqualifiedRoleThenDeniedAutomatically()345 public void requestUnqualifiedRoleThenDeniedAutomatically() throws Exception { 346 requestRole(RoleManager.ROLE_HOME); 347 Pair<Integer, Intent> result = waitForResult(); 348 349 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 350 } 351 352 @Test requestAssistantRoleThenDeniedAutomatically()353 public void requestAssistantRoleThenDeniedAutomatically() throws Exception { 354 requestRole(RoleManager.ROLE_ASSISTANT); 355 Pair<Integer, Intent> result = waitForResult(); 356 357 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 358 } 359 360 @Test requestHoldingRoleThenAllowedAutomatically()361 public void requestHoldingRoleThenAllowedAutomatically() throws Exception { 362 requestRole(ROLE_NAME); 363 respondToRoleRequest(true); 364 365 requestRole(ROLE_NAME); 366 Pair<Integer, Intent> result = waitForResult(); 367 368 assertThat(result.first).isEqualTo(Activity.RESULT_OK); 369 } 370 requestRole(@onNull String roleName)371 private void requestRole(@NonNull String roleName) { 372 Intent intent = new Intent() 373 .setComponent(new ComponentName(APP_PACKAGE_NAME, APP_REQUEST_ROLE_ACTIVITY_NAME)) 374 .putExtra(Intent.EXTRA_ROLE_NAME, roleName); 375 mActivityRule.getActivity().startActivityToWaitForResult(intent); 376 } 377 respondToRoleRequest(boolean allow)378 private void respondToRoleRequest(boolean allow) 379 throws InterruptedException, UiObjectNotFoundException { 380 if (allow) { 381 waitFindObject(By.text(APP_LABEL)).click(); 382 } 383 Pair<Integer, Intent> result = clickButtonAndWaitForResult(allow); 384 int expectedResult = allow ? Activity.RESULT_OK : Activity.RESULT_CANCELED; 385 386 assertThat(result.first).isEqualTo(expectedResult); 387 } 388 389 @Nullable findDontAskAgainCheck(boolean expected)390 private UiObject2 findDontAskAgainCheck(boolean expected) throws UiObjectNotFoundException { 391 BySelector selector = By.res("com.android.permissioncontroller:id/dont_ask_again"); 392 return expected 393 ? waitFindObject(selector) 394 : waitFindObjectOrNull(selector, UNEXPECTED_TIMEOUT_MILLIS); 395 } 396 397 @Nullable findDontAskAgainCheck()398 private UiObject2 findDontAskAgainCheck() throws UiObjectNotFoundException { 399 return findDontAskAgainCheck(true); 400 } 401 402 @NonNull clickButtonAndWaitForResult(boolean positive)403 private Pair<Integer, Intent> clickButtonAndWaitForResult(boolean positive) 404 throws InterruptedException, UiObjectNotFoundException { 405 waitFindObject(By.res(positive ? "android:id/button1" : "android:id/button2")).click(); 406 return waitForResult(); 407 } 408 409 @NonNull waitForResult()410 private Pair<Integer, Intent> waitForResult() throws InterruptedException { 411 return mActivityRule.getActivity().waitForActivityResult(TIMEOUT_MILLIS); 412 } 413 clearPackageData(@onNull String packageName)414 private void clearPackageData(@NonNull String packageName) { 415 runShellCommand("pm clear --user " + Process.myUserHandle().getIdentifier() + " " 416 + packageName); 417 } 418 installPackage(@onNull String apkPath)419 private void installPackage(@NonNull String apkPath) { 420 runShellCommand("pm install -r --user " + Process.myUserHandle().getIdentifier() + " " 421 + apkPath); 422 } 423 uninstallPackage(@onNull String packageName)424 private void uninstallPackage(@NonNull String packageName) { 425 runShellCommand("pm uninstall --user " + Process.myUserHandle().getIdentifier() + " " 426 + packageName); 427 } 428 429 @Test targetCurrentSdkAndChangeDefaultDialerThenDeniedAutomatically()430 public void targetCurrentSdkAndChangeDefaultDialerThenDeniedAutomatically() throws Exception { 431 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_DIALER)); 432 433 WaitForResultActivity activity = mActivityRule.getActivity(); 434 activity.startActivityToWaitForResult(new Intent() 435 .setComponent(new ComponentName(APP_PACKAGE_NAME, 436 APP_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME)) 437 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME)); 438 Pair<Integer, Intent> result = activity.waitForActivityResult(TIMEOUT_MILLIS); 439 440 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 441 } 442 443 @Test targetCurrentSdkAndChangeDefaultSmsThenDeniedAutomatically()444 public void targetCurrentSdkAndChangeDefaultSmsThenDeniedAutomatically() throws Exception { 445 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 446 447 WaitForResultActivity activity = mActivityRule.getActivity(); 448 activity.startActivityToWaitForResult(new Intent() 449 .setComponent(new ComponentName(APP_PACKAGE_NAME, 450 APP_CHANGE_DEFAULT_SMS_ACTIVITY_NAME)) 451 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME)); 452 Pair<Integer, Intent> result = activity.waitForActivityResult(TIMEOUT_MILLIS); 453 454 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 455 } 456 457 @Test targetSdk28AndChangeDefaultDialerAndAllowThenIsDefaultDialer()458 public void targetSdk28AndChangeDefaultDialerAndAllowThenIsDefaultDialer() throws Exception { 459 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_DIALER)); 460 461 sContext.startActivity(new Intent() 462 .setComponent(new ComponentName(APP_28_PACKAGE_NAME, 463 APP_28_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME)) 464 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_28_PACKAGE_NAME) 465 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 466 waitFindObject(By.text(APP_28_LABEL)).click(); 467 waitFindObject(By.res("android:id/button1")).click(); 468 469 // TODO(b/149037075): Use TelecomManager.getDefaultDialerPackage() once the bug is fixed. 470 //TelecomManager telecomManager = sContext.getSystemService(TelecomManager.class); 471 //TestUtils.waitUntil("App is not set as default dialer app", () -> Objects.equals( 472 // telecomManager.getDefaultDialerPackage(), APP_28_PACKAGE_NAME)); 473 TestUtils.waitUntil("App is not set as default dialer app", () -> 474 getRoleHolders(RoleManager.ROLE_DIALER).contains(APP_28_PACKAGE_NAME)); 475 } 476 477 @Test targetSdk28AndChangeDefaultSmsAndAllowThenIsDefaultSms()478 public void targetSdk28AndChangeDefaultSmsAndAllowThenIsDefaultSms() throws Exception { 479 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 480 481 sContext.startActivity(new Intent() 482 .setComponent(new ComponentName(APP_28_PACKAGE_NAME, 483 APP_28_CHANGE_DEFAULT_SMS_ACTIVITY_NAME)) 484 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_28_PACKAGE_NAME) 485 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 486 waitFindObject(By.text(APP_28_LABEL)).click(); 487 waitFindObject(By.res("android:id/button1")).click(); 488 489 TestUtils.waitUntil("App is not set as default sms app", () -> Objects.equals( 490 Telephony.Sms.getDefaultSmsPackage(sContext), APP_28_PACKAGE_NAME)); 491 } 492 493 @Test targetSdk28AndChangeDefaultDialerForAnotherAppThenDeniedAutomatically()494 public void targetSdk28AndChangeDefaultDialerForAnotherAppThenDeniedAutomatically() 495 throws Exception { 496 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_DIALER)); 497 498 WaitForResultActivity activity = mActivityRule.getActivity(); 499 activity.startActivityToWaitForResult(new Intent() 500 .setComponent(new ComponentName(APP_28_PACKAGE_NAME, 501 APP_28_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME)) 502 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME)); 503 Pair<Integer, Intent> result = activity.waitForActivityResult(TIMEOUT_MILLIS); 504 505 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 506 } 507 508 @Test targetSdk28AndChangeDefaultSmsForAnotherAppThenDeniedAutomatically()509 public void targetSdk28AndChangeDefaultSmsForAnotherAppThenDeniedAutomatically() 510 throws Exception { 511 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 512 513 WaitForResultActivity activity = mActivityRule.getActivity(); 514 activity.startActivityToWaitForResult(new Intent() 515 .setComponent(new ComponentName(APP_28_PACKAGE_NAME, 516 APP_28_CHANGE_DEFAULT_SMS_ACTIVITY_NAME)) 517 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME)); 518 Pair<Integer, Intent> result = activity.waitForActivityResult(TIMEOUT_MILLIS); 519 520 assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED); 521 } 522 523 @Test 524 public void targetSdk28AndChangeDefaultDialerForAnotherAppAsHolderAndAllowThenTheOtherAppIsDefaultDialer()525 targetSdk28AndChangeDefaultDialerForAnotherAppAsHolderAndAllowThenTheOtherAppIsDefaultDialer() 526 throws Exception { 527 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_DIALER)); 528 529 addRoleHolder(RoleManager.ROLE_DIALER, APP_28_PACKAGE_NAME); 530 sContext.startActivity(new Intent() 531 .setComponent(new ComponentName(APP_28_PACKAGE_NAME, 532 APP_28_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME)) 533 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) 534 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 535 waitFindObject(By.text(APP_LABEL)).click(); 536 waitFindObject(By.res("android:id/button1")).click(); 537 538 // TODO(b/149037075): Use TelecomManager.getDefaultDialerPackage() once the bug is fixed. 539 //TelecomManager telecomManager = sContext.getSystemService(TelecomManager.class); 540 //TestUtils.waitUntil("App is not set as default dialer app", () -> Objects.equals( 541 // telecomManager.getDefaultDialerPackage(), APP_PACKAGE_NAME)); 542 TestUtils.waitUntil("App is not set as default dialer app", () -> 543 getRoleHolders(RoleManager.ROLE_DIALER).contains(APP_PACKAGE_NAME)); 544 } 545 546 @Test 547 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu") testHoldDialerRoleRequirementWithInCallServiceAndSdk()548 public void testHoldDialerRoleRequirementWithInCallServiceAndSdk() 549 throws Exception { 550 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_DIALER)); 551 // target below sdk 33 without InCallService component can hold dialer role 552 addRoleHolder( 553 RoleManager.ROLE_DIALER, APP_28_PACKAGE_NAME, true); 554 assertIsRoleHolder( 555 RoleManager.ROLE_DIALER, APP_28_PACKAGE_NAME, true); 556 // target sdk 33 without InCallService component cannot hold dialer role 557 addRoleHolder( 558 RoleManager.ROLE_DIALER, APP_33_WITHOUT_INCALLSERVICE_PACKAGE_NAME, false); 559 assertIsRoleHolder( 560 RoleManager.ROLE_DIALER, APP_33_WITHOUT_INCALLSERVICE_PACKAGE_NAME, false); 561 // target sdk 33 with InCallService component can hold dialer role 562 addRoleHolder( 563 RoleManager.ROLE_DIALER, APP_PACKAGE_NAME, true); 564 assertIsRoleHolder( 565 RoleManager.ROLE_DIALER, APP_PACKAGE_NAME, true); 566 } 567 568 @Test 569 public void targetSdk28AndChangeDefaultSmsForAnotherAppAsHolderAndAllowThenTheOtherAppIsDefaultSms()570 targetSdk28AndChangeDefaultSmsForAnotherAppAsHolderAndAllowThenTheOtherAppIsDefaultSms() 571 throws Exception { 572 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 573 574 addRoleHolder(RoleManager.ROLE_SMS, APP_28_PACKAGE_NAME); 575 sContext.startActivity(new Intent() 576 .setComponent(new ComponentName(APP_28_PACKAGE_NAME, 577 APP_28_CHANGE_DEFAULT_SMS_ACTIVITY_NAME)) 578 .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) 579 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 580 waitFindObject(By.text(APP_LABEL)).click(); 581 waitFindObject(By.res("android:id/button1")).click(); 582 583 TestUtils.waitUntil("App is not set as default sms app", () -> Objects.equals( 584 Telephony.Sms.getDefaultSmsPackage(sContext), APP_PACKAGE_NAME)); 585 } 586 587 @Test openDefaultAppDetailsThenIsNotDefaultApp()588 public void openDefaultAppDetailsThenIsNotDefaultApp() throws Exception { 589 runWithShellPermissionIdentity(() -> sContext.startActivity(new Intent( 590 Intent.ACTION_MANAGE_DEFAULT_APP) 591 .addCategory(Intent.CATEGORY_DEFAULT) 592 .putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NAME) 593 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 594 | Intent.FLAG_ACTIVITY_CLEAR_TASK))); 595 596 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(false)) 597 .hasDescendant(By.text(APP_LABEL))); 598 599 pressBack(); 600 } 601 602 @Test openDefaultAppDetailsAndSetDefaultAppThenIsDefaultApp()603 public void openDefaultAppDetailsAndSetDefaultAppThenIsDefaultApp() throws Exception { 604 runWithShellPermissionIdentity(() -> sContext.startActivity(new Intent( 605 Intent.ACTION_MANAGE_DEFAULT_APP) 606 .addCategory(Intent.CATEGORY_DEFAULT) 607 .putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NAME) 608 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 609 | Intent.FLAG_ACTIVITY_CLEAR_TASK))); 610 waitForIdle(); 611 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(false)) 612 .hasDescendant(By.text(APP_LABEL))).click(); 613 614 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(true)) 615 .hasDescendant(By.text(APP_LABEL))); 616 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, true); 617 618 pressBack(); 619 } 620 621 @Test openDefaultAppDetailsAndSetDefaultAppAndSetAnotherThenIsNotDefaultApp()622 public void openDefaultAppDetailsAndSetDefaultAppAndSetAnotherThenIsNotDefaultApp() 623 throws Exception { 624 runWithShellPermissionIdentity(() -> sContext.startActivity(new Intent( 625 Intent.ACTION_MANAGE_DEFAULT_APP) 626 .addCategory(Intent.CATEGORY_DEFAULT) 627 .putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NAME) 628 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 629 | Intent.FLAG_ACTIVITY_CLEAR_TASK))); 630 waitForIdle(); 631 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(false)) 632 .hasDescendant(By.text(APP_LABEL))).click(); 633 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(true)) 634 .hasDescendant(By.text(APP_LABEL))); 635 waitForIdle(); 636 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(false))).click(); 637 638 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(false)) 639 .hasDescendant(By.text(APP_LABEL))); 640 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, false); 641 642 pressBack(); 643 } 644 645 @Test openDefaultAppListThenHasDefaultApp()646 public void openDefaultAppListThenHasDefaultApp() throws Exception { 647 sContext.startActivity(new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS) 648 .addCategory(Intent.CATEGORY_DEFAULT) 649 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)); 650 651 waitFindObject(By.text(ROLE_SHORT_LABEL)); 652 653 pressBack(); 654 } 655 656 @Test openDefaultAppListThenIsNotDefaultAppInList()657 public void openDefaultAppListThenIsNotDefaultAppInList() throws Exception { 658 sContext.startActivity(new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS) 659 .addCategory(Intent.CATEGORY_DEFAULT) 660 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)); 661 662 assertThat(waitFindObjectOrNull(By.text(APP_LABEL), UNEXPECTED_TIMEOUT_MILLIS)) 663 .isNull(); 664 665 pressBack(); 666 } 667 668 @Test openDefaultAppListAndSetDefaultAppThenIsDefaultApp()669 public void openDefaultAppListAndSetDefaultAppThenIsDefaultApp() throws Exception { 670 sContext.startActivity(new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS) 671 .addCategory(Intent.CATEGORY_DEFAULT) 672 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)); 673 waitForIdle(); 674 waitFindObject(By.text(ROLE_SHORT_LABEL)).click(); 675 waitForIdle(); 676 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(false)) 677 .hasDescendant(By.text(APP_LABEL))).click(); 678 679 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(true)) 680 .hasDescendant(By.text(APP_LABEL))); 681 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, true); 682 683 pressBack(); 684 pressBack(); 685 } 686 687 @Test openDefaultAppListAndSetDefaultAppThenIsDefaultAppInList()688 public void openDefaultAppListAndSetDefaultAppThenIsDefaultAppInList() throws Exception { 689 sContext.startActivity(new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS) 690 .addCategory(Intent.CATEGORY_DEFAULT) 691 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)); 692 waitForIdle(); 693 waitFindObject(By.text(ROLE_SHORT_LABEL)).click(); 694 waitForIdle(); 695 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(false)) 696 .hasDescendant(By.text(APP_LABEL))).click(); 697 waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).checked(true)) 698 .hasDescendant(By.text(APP_LABEL))); 699 pressBack(); 700 701 waitFindObject(By.text(APP_LABEL)); 702 703 pressBack(); 704 } 705 waitForIdle()706 private static void waitForIdle() { 707 UiAutomatorUtils.getUiDevice().waitForIdle(); 708 } 709 pressBack()710 private static void pressBack() { 711 UiAutomatorUtils.getUiDevice().pressBack(); 712 waitForIdle(); 713 } 714 715 @Test roleIsAvailable()716 public void roleIsAvailable() { 717 assertThat(sRoleManager.isRoleAvailable(ROLE_NAME)).isTrue(); 718 } 719 720 @Test dontAddRoleHolderThenRoleIsNotHeld()721 public void dontAddRoleHolderThenRoleIsNotHeld() throws Exception { 722 assertRoleIsHeld(ROLE_NAME, false); 723 } 724 725 @Test addRoleHolderThenRoleIsHeld()726 public void addRoleHolderThenRoleIsHeld() throws Exception { 727 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 728 729 assertRoleIsHeld(ROLE_NAME, true); 730 } 731 732 @Test addAndRemoveRoleHolderThenRoleIsNotHeld()733 public void addAndRemoveRoleHolderThenRoleIsNotHeld() throws Exception { 734 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 735 removeRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 736 737 assertRoleIsHeld(ROLE_NAME, false); 738 } 739 assertRoleIsHeld(@onNull String roleName, boolean isHeld)740 private void assertRoleIsHeld(@NonNull String roleName, boolean isHeld) 741 throws InterruptedException { 742 Intent intent = new Intent() 743 .setComponent(new ComponentName(APP_PACKAGE_NAME, APP_IS_ROLE_HELD_ACTIVITY_NAME)) 744 .putExtra(Intent.EXTRA_ROLE_NAME, roleName); 745 WaitForResultActivity activity = mActivityRule.getActivity(); 746 activity.startActivityToWaitForResult(intent); 747 Pair<Integer, Intent> result = activity.waitForActivityResult(TIMEOUT_MILLIS); 748 749 assertThat(result.first).isEqualTo(Activity.RESULT_OK); 750 assertThat(result.second).isNotNull(); 751 assertThat(result.second.hasExtra(APP_IS_ROLE_HELD_EXTRA_IS_ROLE_HELD)).isTrue(); 752 assertThat(result.second.getBooleanExtra(APP_IS_ROLE_HELD_EXTRA_IS_ROLE_HELD, false)) 753 .isEqualTo(isHeld); 754 } 755 756 @Test dontAddRoleHolderThenIsNotRoleHolder()757 public void dontAddRoleHolderThenIsNotRoleHolder() throws Exception { 758 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, false); 759 } 760 761 @Test addRoleHolderThenIsRoleHolder()762 public void addRoleHolderThenIsRoleHolder() throws Exception { 763 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 764 765 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, true); 766 } 767 768 @Test addAndRemoveRoleHolderThenIsNotRoleHolder()769 public void addAndRemoveRoleHolderThenIsNotRoleHolder() throws Exception { 770 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 771 removeRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 772 773 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, false); 774 } 775 776 @Test addAndClearRoleHoldersThenIsNotRoleHolder()777 public void addAndClearRoleHoldersThenIsNotRoleHolder() throws Exception { 778 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 779 clearRoleHolders(ROLE_NAME); 780 781 assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, false); 782 } 783 784 @Test addInvalidRoleHolderThenFails()785 public void addInvalidRoleHolderThenFails() throws Exception { 786 addRoleHolder("invalid", APP_PACKAGE_NAME, false); 787 } 788 789 @Test addUnqualifiedRoleHolderThenFails()790 public void addUnqualifiedRoleHolderThenFails() throws Exception { 791 addRoleHolder(RoleManager.ROLE_HOME, APP_PACKAGE_NAME, false); 792 } 793 794 @Test removeInvalidRoleHolderThenFails()795 public void removeInvalidRoleHolderThenFails() throws Exception { 796 removeRoleHolder("invalid", APP_PACKAGE_NAME, false); 797 } 798 799 @Test clearInvalidRoleHoldersThenFails()800 public void clearInvalidRoleHoldersThenFails() throws Exception { 801 clearRoleHolders("invalid", false); 802 } 803 804 @Test addOnRoleHoldersChangedListenerAndAddRoleHolderThenIsNotified()805 public void addOnRoleHoldersChangedListenerAndAddRoleHolderThenIsNotified() throws Exception { 806 assertOnRoleHoldersChangedListenerIsNotified(() -> addRoleHolder(ROLE_NAME, 807 APP_PACKAGE_NAME)); 808 } 809 810 @Test addOnRoleHoldersChangedListenerAndRemoveRoleHolderThenIsNotified()811 public void addOnRoleHoldersChangedListenerAndRemoveRoleHolderThenIsNotified() 812 throws Exception { 813 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 814 815 assertOnRoleHoldersChangedListenerIsNotified(() -> removeRoleHolder(ROLE_NAME, 816 APP_PACKAGE_NAME)); 817 } 818 819 @Test addOnRoleHoldersChangedListenerAndClearRoleHoldersThenIsNotified()820 public void addOnRoleHoldersChangedListenerAndClearRoleHoldersThenIsNotified() 821 throws Exception { 822 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 823 824 assertOnRoleHoldersChangedListenerIsNotified(() -> clearRoleHolders(ROLE_NAME)); 825 } 826 assertOnRoleHoldersChangedListenerIsNotified(@onNull ThrowingRunnable runnable)827 private void assertOnRoleHoldersChangedListenerIsNotified(@NonNull ThrowingRunnable runnable) 828 throws Exception { 829 ListenerFuture future = new ListenerFuture(); 830 UserHandle user = Process.myUserHandle(); 831 runWithShellPermissionIdentity(() -> sRoleManager.addOnRoleHoldersChangedListenerAsUser( 832 sContext.getMainExecutor(), future, user)); 833 Pair<String, UserHandle> result; 834 try { 835 runnable.run(); 836 result = future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 837 } finally { 838 runWithShellPermissionIdentity(() -> 839 sRoleManager.removeOnRoleHoldersChangedListenerAsUser(future, user)); 840 } 841 842 assertThat(result.first).isEqualTo(ROLE_NAME); 843 assertThat(result.second).isEqualTo(user); 844 } 845 846 @Test addAndRemoveOnRoleHoldersChangedListenerAndAddRoleHolderThenIsNotNotified()847 public void addAndRemoveOnRoleHoldersChangedListenerAndAddRoleHolderThenIsNotNotified() 848 throws Exception { 849 ListenerFuture future = new ListenerFuture(); 850 UserHandle user = Process.myUserHandle(); 851 runWithShellPermissionIdentity(() -> { 852 sRoleManager.addOnRoleHoldersChangedListenerAsUser(sContext.getMainExecutor(), future, 853 user); 854 sRoleManager.removeOnRoleHoldersChangedListenerAsUser(future, user); 855 }); 856 addRoleHolder(ROLE_NAME, APP_PACKAGE_NAME); 857 858 try { 859 future.get(UNEXPECTED_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 860 } catch (TimeoutException e) { 861 // Expected 862 return; 863 } 864 throw new AssertionError("OnRoleHoldersChangedListener was notified after removal"); 865 } 866 867 @Test setRoleNamesFromControllerShouldRequireManageRolesFromControllerPermission()868 public void setRoleNamesFromControllerShouldRequireManageRolesFromControllerPermission() { 869 assertRequiresManageRolesFromControllerPermission( 870 () -> sRoleManager.setRoleNamesFromController(Collections.emptyList()), 871 "setRoleNamesFromController"); 872 } 873 874 @Test addRoleHolderFromControllerShouldRequireManageRolesFromControllerPermission()875 public void addRoleHolderFromControllerShouldRequireManageRolesFromControllerPermission() { 876 assertRequiresManageRolesFromControllerPermission( 877 () -> sRoleManager.addRoleHolderFromController(ROLE_NAME, APP_PACKAGE_NAME), 878 "addRoleHolderFromController"); 879 } 880 881 @Test removeRoleHolderFromControllerShouldRequireManageRolesFromControllerPermission()882 public void removeRoleHolderFromControllerShouldRequireManageRolesFromControllerPermission() { 883 assertRequiresManageRolesFromControllerPermission( 884 () -> sRoleManager.removeRoleHolderFromController(ROLE_NAME, APP_PACKAGE_NAME), 885 "removeRoleHolderFromController"); 886 } 887 888 @Test getHeldRolesFromControllerShouldRequireManageRolesFromControllerPermission()889 public void getHeldRolesFromControllerShouldRequireManageRolesFromControllerPermission() { 890 assertRequiresManageRolesFromControllerPermission( 891 () -> sRoleManager.getHeldRolesFromController(APP_PACKAGE_NAME), 892 "getHeldRolesFromController"); 893 } 894 assertRequiresManageRolesFromControllerPermission(@onNull Runnable runnable, @NonNull String methodName)895 private void assertRequiresManageRolesFromControllerPermission(@NonNull Runnable runnable, 896 @NonNull String methodName) { 897 try { 898 runnable.run(); 899 } catch (SecurityException e) { 900 if (e.getMessage().contains(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)) { 901 // Expected 902 return; 903 } 904 throw e; 905 } 906 fail("RoleManager." + methodName + "() should require " 907 + PERMISSION_MANAGE_ROLES_FROM_CONTROLLER); 908 } 909 910 @Test manageRolesFromControllerPermissionShouldBeDeclaredByPermissionController()911 public void manageRolesFromControllerPermissionShouldBeDeclaredByPermissionController() 912 throws PackageManager.NameNotFoundException { 913 PermissionInfo permissionInfo = sPackageManager.getPermissionInfo( 914 PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, 0); 915 916 assertThat(permissionInfo.packageName).isEqualTo( 917 sPackageManager.getPermissionControllerPackageName()); 918 assertThat(permissionInfo.getProtection()).isEqualTo(PermissionInfo.PROTECTION_SIGNATURE); 919 assertThat(permissionInfo.getProtectionFlags()).isEqualTo(0); 920 } 921 922 @Test smsRoleHasHolder()923 public void smsRoleHasHolder() throws Exception { 924 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 925 926 assertThat(getRoleHolders(RoleManager.ROLE_SMS)).isNotEmpty(); 927 } 928 929 @Test addSmsRoleHolderThenPermissionIsGranted()930 public void addSmsRoleHolderThenPermissionIsGranted() throws Exception { 931 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 932 933 addRoleHolder(RoleManager.ROLE_SMS, APP_PACKAGE_NAME); 934 935 assertThat(sPackageManager.checkPermission(android.Manifest.permission.SEND_SMS, 936 APP_PACKAGE_NAME)).isEqualTo(PackageManager.PERMISSION_GRANTED); 937 } 938 939 @Test removeSmsRoleHolderThenPermissionIsRevoked()940 public void removeSmsRoleHolderThenPermissionIsRevoked() throws Exception { 941 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 942 943 String smsRoleHolder = getRoleHolders(RoleManager.ROLE_SMS).get(0); 944 addRoleHolder(RoleManager.ROLE_SMS, APP_PACKAGE_NAME); 945 addRoleHolder(RoleManager.ROLE_SMS, smsRoleHolder); 946 947 assertThat(sPackageManager.checkPermission(android.Manifest.permission.SEND_SMS, 948 APP_PACKAGE_NAME)).isEqualTo(PackageManager.PERMISSION_DENIED); 949 } 950 951 @Test removeSmsRoleHolderThenDialerRolePermissionIsRetained()952 public void removeSmsRoleHolderThenDialerRolePermissionIsRetained() throws Exception { 953 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_DIALER) 954 && sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 955 956 addRoleHolder(RoleManager.ROLE_DIALER, APP_PACKAGE_NAME); 957 String smsRoleHolder = getRoleHolders(RoleManager.ROLE_SMS).get(0); 958 addRoleHolder(RoleManager.ROLE_SMS, APP_PACKAGE_NAME); 959 addRoleHolder(RoleManager.ROLE_SMS, smsRoleHolder); 960 961 assertThat(sPackageManager.checkPermission(android.Manifest.permission.SEND_SMS, 962 APP_PACKAGE_NAME)).isEqualTo(PackageManager.PERMISSION_GRANTED); 963 } 964 965 @Test packageManagerGetDefaultBrowserBackedByRole()966 public void packageManagerGetDefaultBrowserBackedByRole() throws Exception { 967 addRoleHolder(RoleManager.ROLE_BROWSER, APP_PACKAGE_NAME); 968 969 assertThat(sPackageManager.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId())) 970 .isEqualTo(APP_PACKAGE_NAME); 971 } 972 973 @Test packageManagerSetDefaultBrowserBackedByRole()974 public void packageManagerSetDefaultBrowserBackedByRole() throws Exception { 975 callWithShellPermissionIdentity(() -> sPackageManager.setDefaultBrowserPackageNameAsUser( 976 APP_PACKAGE_NAME, UserHandle.myUserId())); 977 978 assertIsRoleHolder(RoleManager.ROLE_BROWSER, APP_PACKAGE_NAME, true); 979 } 980 981 @Test telephonySmsGetDefaultSmsPackageBackedByRole()982 public void telephonySmsGetDefaultSmsPackageBackedByRole() throws Exception { 983 assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 984 985 addRoleHolder(RoleManager.ROLE_SMS, APP_PACKAGE_NAME); 986 987 assertThat(Telephony.Sms.getDefaultSmsPackage(sContext)).isEqualTo(APP_PACKAGE_NAME); 988 } 989 990 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S, codeName = "S") 991 @Test cannotBypassRoleQualificationWithoutPermission()992 public void cannotBypassRoleQualificationWithoutPermission() throws Exception { 993 assertThrows(SecurityException.class, () -> 994 sRoleManager.setBypassingRoleQualification(true)); 995 } 996 997 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S, codeName = "S") 998 @Test bypassRoleQualificationThenCanAddUnqualifiedRoleHolder()999 public void bypassRoleQualificationThenCanAddUnqualifiedRoleHolder() throws Exception { 1000 assertThat(sRoleManager.isRoleAvailable(RoleManager.ROLE_SYSTEM_ACTIVITY_RECOGNIZER)) 1001 .isTrue(); 1002 1003 runWithShellPermissionIdentity(() -> sRoleManager.setBypassingRoleQualification(true)); 1004 try { 1005 assertThat(callWithShellPermissionIdentity(() -> 1006 sRoleManager.isBypassingRoleQualification())).isTrue(); 1007 1008 // The System Activity Recognizer role requires a system app, so this won't succeed 1009 // without bypassing role qualification. 1010 addRoleHolder(RoleManager.ROLE_SYSTEM_ACTIVITY_RECOGNIZER, APP_PACKAGE_NAME); 1011 1012 assertThat(getRoleHolders(RoleManager.ROLE_SYSTEM_ACTIVITY_RECOGNIZER)) 1013 .contains(APP_PACKAGE_NAME); 1014 } finally { 1015 runWithShellPermissionIdentity(() -> sRoleManager.setBypassingRoleQualification(false)); 1016 } 1017 assertThat(callWithShellPermissionIdentity(() -> 1018 sRoleManager.isBypassingRoleQualification())).isFalse(); 1019 } 1020 1021 @NonNull getRoleHolders(@onNull String roleName)1022 private List<String> getRoleHolders(@NonNull String roleName) throws Exception { 1023 return callWithShellPermissionIdentity(() -> sRoleManager.getRoleHolders(roleName)); 1024 } 1025 assertIsRoleHolder(@onNull String roleName, @NonNull String packageName, boolean shouldBeRoleHolder)1026 private void assertIsRoleHolder(@NonNull String roleName, @NonNull String packageName, 1027 boolean shouldBeRoleHolder) throws Exception { 1028 List<String> packageNames = getRoleHolders(roleName); 1029 1030 if (shouldBeRoleHolder) { 1031 assertThat(packageNames).contains(packageName); 1032 } else { 1033 assertThat(packageNames).doesNotContain(packageName); 1034 } 1035 } 1036 addRoleHolder(@onNull String roleName, @NonNull String packageName, boolean expectSuccess)1037 private void addRoleHolder(@NonNull String roleName, @NonNull String packageName, 1038 boolean expectSuccess) throws Exception { 1039 CallbackFuture future = new CallbackFuture(); 1040 runWithShellPermissionIdentity(() -> sRoleManager.addRoleHolderAsUser(roleName, 1041 packageName, 0, Process.myUserHandle(), sContext.getMainExecutor(), future)); 1042 assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isEqualTo(expectSuccess); 1043 } 1044 addRoleHolder(@onNull String roleName, @NonNull String packageName)1045 private void addRoleHolder(@NonNull String roleName, @NonNull String packageName) 1046 throws Exception { 1047 addRoleHolder(roleName, packageName, true); 1048 } 1049 removeRoleHolder(@onNull String roleName, @NonNull String packageName, boolean expectSuccess)1050 private void removeRoleHolder(@NonNull String roleName, @NonNull String packageName, 1051 boolean expectSuccess) throws Exception { 1052 CallbackFuture future = new CallbackFuture(); 1053 runWithShellPermissionIdentity(() -> sRoleManager.removeRoleHolderAsUser(roleName, 1054 packageName, 0, Process.myUserHandle(), sContext.getMainExecutor(), future)); 1055 assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isEqualTo(expectSuccess); 1056 } 1057 removeRoleHolder(@onNull String roleName, @NonNull String packageName)1058 private void removeRoleHolder(@NonNull String roleName, @NonNull String packageName) 1059 throws Exception { 1060 removeRoleHolder(roleName, packageName, true); 1061 } 1062 clearRoleHolders(@onNull String roleName, boolean expectSuccess)1063 private void clearRoleHolders(@NonNull String roleName, boolean expectSuccess) 1064 throws Exception { 1065 CallbackFuture future = new CallbackFuture(); 1066 runWithShellPermissionIdentity(() -> sRoleManager.clearRoleHoldersAsUser(roleName, 0, 1067 Process.myUserHandle(), sContext.getMainExecutor(), future)); 1068 assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isEqualTo(expectSuccess); 1069 } 1070 clearRoleHolders(@onNull String roleName)1071 private void clearRoleHolders(@NonNull String roleName) throws Exception { 1072 clearRoleHolders(roleName, true); 1073 } 1074 1075 private static class ListenerFuture extends CompletableFuture<Pair<String, UserHandle>> 1076 implements OnRoleHoldersChangedListener { 1077 1078 @Override onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1079 public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { 1080 complete(new Pair<>(roleName, user)); 1081 } 1082 } 1083 1084 private static class CallbackFuture extends CompletableFuture<Boolean> 1085 implements Consumer<Boolean> { 1086 1087 @Override accept(Boolean successful)1088 public void accept(Boolean successful) { 1089 complete(successful); 1090 } 1091 } 1092 } 1093