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