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.telecom.cts; 18 19 import static android.telecom.cts.TestUtils.shouldTestTelecom; 20 import static android.telecom.cts.TestUtils.waitOnAllHandlers; 21 22 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 23 24 import android.Manifest; 25 import android.app.role.RoleManager; 26 import android.content.ComponentName; 27 import android.content.ContentResolver; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.ServiceConnection; 31 import android.content.pm.PackageManager; 32 import android.database.Cursor; 33 import android.net.Uri; 34 import android.os.Bundle; 35 import android.os.IBinder; 36 import android.os.Process; 37 import android.os.UserHandle; 38 39 import android.provider.CallLog; 40 import android.telecom.Call; 41 import android.telecom.CallScreeningService; 42 import android.telecom.TelecomManager; 43 import android.telecom.cts.screeningtestapp.CallScreeningServiceControl; 44 import android.telecom.cts.screeningtestapp.CtsCallScreeningService; 45 import android.telecom.cts.screeningtestapp.ICallScreeningControl; 46 import android.text.TextUtils; 47 48 import java.util.List; 49 import java.util.concurrent.CountDownLatch; 50 import java.util.concurrent.Executor; 51 import java.util.concurrent.LinkedBlockingQueue; 52 import java.util.concurrent.TimeUnit; 53 54 public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockServices { 55 public static final String EXTRA_NETWORK_IDENTIFIED_EMERGENCY_CALL = "identifiedEmergencyCall"; 56 private static final String TAG = ThirdPartyCallScreeningServiceTest.class.getSimpleName(); 57 private static final String TEST_APP_NAME = "CTSCSTest"; 58 private static final String TEST_APP_PACKAGE = "android.telecom.cts.screeningtestapp"; 59 private static final String TEST_APP_COMPONENT = 60 "android.telecom.cts.screeningtestapp/" 61 + "android.telecom.cts.screeningtestapp.CtsCallScreeningService"; 62 private static final int ASYNC_TIMEOUT = 10000; 63 private static final String ROLE_CALL_SCREENING = RoleManager.ROLE_CALL_SCREENING; 64 private static final Uri TEST_OUTGOING_NUMBER = Uri.fromParts("tel", "6505551212", null); 65 66 private ICallScreeningControl mCallScreeningControl; 67 private RoleManager mRoleManager; 68 private String mPreviousCallScreeningPackage; 69 private PackageManager mPackageManager; 70 private Uri mContactUri; 71 private ContentResolver mContentResolver; 72 73 @Override setUp()74 protected void setUp() throws Exception { 75 super.setUp(); 76 if (!mShouldTestTelecom) { 77 return; 78 } 79 mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 80 mPackageManager = mContext.getPackageManager(); 81 revokeReadContactPermission(); 82 setupControlBinder(); 83 setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE); 84 rememberPreviousCallScreeningApp(); 85 // Ensure CTS app holds the call screening role. 86 addRoleHolder(ROLE_CALL_SCREENING, 87 CtsCallScreeningService.class.getPackage().getName()); 88 mContentResolver = getInstrumentation().getTargetContext().getContentResolver(); 89 } 90 91 @Override tearDown()92 protected void tearDown() throws Exception { 93 super.tearDown(); 94 if (!mShouldTestTelecom) { 95 return; 96 } 97 98 if (mCallScreeningControl != null) { 99 mCallScreeningControl.reset(); 100 } 101 102 // Remove the test app from the screening role. 103 removeRoleHolder(ROLE_CALL_SCREENING, CtsCallScreeningService.class.getPackage().getName()); 104 105 if (!TextUtils.isEmpty(mPreviousCallScreeningPackage)) { 106 addRoleHolder(ROLE_CALL_SCREENING, mPreviousCallScreeningPackage); 107 } 108 } 109 110 /** 111 * Verifies that a {@link android.telecom.CallScreeningService} can reject an incoming call. 112 * Ensures that the system logs the blocked call to the call log. 113 * 114 * @throws Exception 115 */ testRejectCall()116 public void testRejectCall() throws Exception { 117 if (!shouldTestTelecom(mContext)) { 118 return; 119 } 120 121 // Tell the test app to block the call. 122 mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, 123 true /* shouldRejectCall */, false /* shouldSilenceCall */, 124 false /* shouldSkipCallLog */, true /* shouldSkipNotification */); 125 126 addIncomingAndVerifyBlocked(false /* addContact */); 127 } 128 129 /** 130 * Similar to {@link #testRejectCall()}, except the {@link android.telecom.CallScreeningService} 131 * tries to skip logging the call to the call log. We verify that Telecom still logs the call 132 * to the call log, retaining the API behavior documented in 133 * {@link android.telecom.CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)} 134 * @throws Exception 135 */ testRejectCallAndTryToSkipCallLog()136 public void testRejectCallAndTryToSkipCallLog() throws Exception { 137 if (!shouldTestTelecom(mContext)) { 138 return; 139 } 140 141 // Tell the test app to block the call; also try to skip logging the call. 142 mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, 143 true /* shouldRejectCall */, false /* shouldSilenceCall */, 144 true /* shouldSkipCallLog */, true /* shouldSkipNotification */); 145 146 addIncomingAndVerifyBlocked(false /* addContact */); 147 } 148 149 /** 150 * Verifies that a {@link android.telecom.CallScreeningService} set the extra to silence a call. 151 * @throws Exception 152 */ testIncomingCallHasSilenceExtra()153 public void testIncomingCallHasSilenceExtra() throws Exception { 154 if (!shouldTestTelecom(mContext)) { 155 return; 156 } 157 158 // Tell the test app to silence the call. 159 mCallScreeningControl.setCallResponse(false /* shouldDisallowCall */, 160 false /* shouldRejectCall */, true /* shouldSilenceCall */, 161 false /* shouldSkipCallLog */, false /* shouldSkipNotification */); 162 163 addIncomingAndVerifyCallExtraForSilence(true); 164 } 165 166 /** 167 * Verifies that a {@link android.telecom.CallScreeningService} did not set the extra to silence an incoming call. 168 * @throws Exception 169 */ testIncomingCallDoesNotHaveHaveSilenceExtra()170 public void testIncomingCallDoesNotHaveHaveSilenceExtra() throws Exception { 171 if (!shouldTestTelecom(mContext)) { 172 return; 173 } 174 175 // Tell the test app to not silence the call. 176 mCallScreeningControl.setCallResponse(false /* shouldDisallowCall */, 177 false /* shouldRejectCall */, false /* shouldSilenceCall */, 178 false /* shouldSkipCallLog */, false /* shouldSkipNotification */); 179 180 addIncomingAndVerifyCallExtraForSilence(false); 181 } 182 testHasPermissionAndNoContactIncoming()183 public void testHasPermissionAndNoContactIncoming() throws Exception { 184 if (!shouldTestTelecom(mContext)) { 185 return; 186 } 187 188 grantReadContactPermission(); 189 verifyPermission(true); 190 // Tell the test app to block the call. 191 mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, 192 true /* shouldRejectCall */, false /* shouldSilenceCall */, 193 false /* shouldSkipCallLog */, true /* shouldSkipNotification */); 194 addIncomingAndVerifyBlocked(false /* addContact */); 195 } 196 testNoPermissionAndNoContactIncoming()197 public void testNoPermissionAndNoContactIncoming() throws Exception { 198 if (!shouldTestTelecom(mContext)) { 199 return; 200 } 201 202 verifyPermission(false); 203 // Tell the test app to block the call. 204 mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, 205 true /* shouldRejectCall */, false /* shouldSilenceCall */, 206 false /* shouldSkipCallLog */, true /* shouldSkipNotification */); 207 addIncomingAndVerifyBlocked(false /* addContact */); 208 } 209 testHasPermissionAndHasContactIncoming()210 public void testHasPermissionAndHasContactIncoming() throws Exception { 211 if (!shouldTestTelecom(mContext)) { 212 return; 213 } 214 215 grantReadContactPermission(); 216 verifyPermission(true); 217 mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, 218 true /* shouldRejectCall */, false /* shouldSilenceCall */, 219 false /* shouldSkipCallLog */, true /* shouldSkipNotification */); 220 addIncomingAndVerifyBlocked(true /* addContact */); 221 } 222 testNoPermissionAndHasContactIncoming()223 public void testNoPermissionAndHasContactIncoming() throws Exception { 224 if (!shouldTestTelecom(mContext)) { 225 return; 226 } 227 228 verifyPermission(false); 229 mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, 230 true /* shouldRejectCall */, false /* shouldSilenceCall */, 231 false /* shouldSkipCallLog */, true /* shouldSkipNotification */); 232 addIncomingAndVerifyAllowed(true /* addContact */); 233 } 234 testHasPermissionAndNoContactOutgoing()235 public void testHasPermissionAndNoContactOutgoing() throws Exception { 236 if (!shouldTestTelecom(mContext)) { 237 return; 238 } 239 240 grantReadContactPermission(); 241 verifyPermission(true); 242 placeOutgoingCall(false /* addContact */); 243 assertTrue(mCallScreeningControl.waitForBind()); 244 } 245 testNoPermissionAndNoContactOutgoing()246 public void testNoPermissionAndNoContactOutgoing() throws Exception { 247 if (!shouldTestTelecom(mContext)) { 248 return; 249 } 250 251 verifyPermission(false); 252 placeOutgoingCall(false /* addContact */); 253 assertTrue(mCallScreeningControl.waitForBind()); 254 } 255 testHasPermissionAndHasContactOutgoing()256 public void testHasPermissionAndHasContactOutgoing() throws Exception { 257 if (!shouldTestTelecom(mContext)) { 258 return; 259 } 260 261 grantReadContactPermission(); 262 verifyPermission(true); 263 placeOutgoingCall(true /* addCountact */); 264 assertTrue(mCallScreeningControl.waitForBind()); 265 } 266 testNoPermissionAndHasContactOutgoing()267 public void testNoPermissionAndHasContactOutgoing() throws Exception { 268 if (!shouldTestTelecom(mContext)) { 269 return; 270 } 271 272 verifyPermission(false); 273 placeOutgoingCall(true /* addCountact */); 274 assertFalse(mCallScreeningControl.waitForBind()); 275 } 276 testNoPostCallActivityWithoutRole()277 public void testNoPostCallActivityWithoutRole() throws Exception { 278 if (!shouldTestTelecom(mContext)) { 279 return; 280 } 281 282 removeRoleHolder(ROLE_CALL_SCREENING, CtsCallScreeningService.class.getPackage().getName()); 283 addIncomingAndVerifyAllowed(false); 284 assertFalse(mCallScreeningControl.waitForActivity()); 285 } 286 testAllowCall()287 public void testAllowCall() throws Exception { 288 if (!mShouldTestTelecom) { 289 return; 290 } 291 292 mCallScreeningControl.setCallResponse(false /* shouldDisallowCall */, 293 false /* shouldRejectCall */, false /* shouldSilenceCall */, 294 false /* shouldSkipCallLog */, false /* shouldSkipNotification */); 295 addIncomingAndVerifyAllowed(false /* addContact */); 296 assertTrue(mCallScreeningControl.waitForActivity()); 297 } 298 testNoPostCallActivityWhenBlocked()299 public void testNoPostCallActivityWhenBlocked() throws Exception { 300 if (!mShouldTestTelecom) { 301 return; 302 } 303 304 mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, 305 true /* shouldRejectCall */, false /* shouldSilenceCall */, 306 false /* shouldSkipCallLog */, true /* shouldSkipNotification */); 307 addIncomingAndVerifyBlocked(false /* addContact */); 308 assertFalse(mCallScreeningControl.waitForActivity()); 309 } 310 testNoPostCallActivityWhenAudioProcessing()311 public void testNoPostCallActivityWhenAudioProcessing() throws Exception { 312 if (!shouldTestTelecom(mContext)) { 313 return; 314 } 315 316 mCallScreeningControl.setCallResponse(false /* shouldDisallowCall */, 317 false /* shouldRejectCall */, false /* shouldSilenceCall */, 318 false /* shouldSkipCallLog */, false /* shouldSkipNotification */); 319 Uri testNumber = createRandomTestNumber(); 320 Bundle extras = new Bundle(); 321 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, testNumber); 322 mTelecomManager.addNewIncomingCall(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, extras); 323 324 // Wait until the new incoming call is processed. 325 waitOnAllHandlers(getInstrumentation()); 326 327 assertEquals(1, mInCallCallbacks.getService().getCallCount()); 328 Call call = mInCallCallbacks.getService().getLastCall(); 329 call.enterBackgroundAudioProcessing(); 330 331 waitOnAllHandlers(getInstrumentation()); 332 mInCallCallbacks.getService().disconnectAllCalls(); 333 assertFalse(mCallScreeningControl.waitForActivity()); 334 } 335 testNoPostCallActivityForOutgoingEmergencyCall()336 public void testNoPostCallActivityForOutgoingEmergencyCall() throws Exception { 337 if (!shouldTestTelecom(mContext)) { 338 return; 339 } 340 341 setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); 342 Bundle extras = new Bundle(); 343 extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, TEST_EMERGENCY_URI); 344 placeAndVerifyCall(extras); 345 346 // Wait until the new incoming call is processed. 347 waitOnAllHandlers(getInstrumentation()); 348 mInCallCallbacks.getService().disconnectAllCalls(); 349 assertFalse(mCallScreeningControl.waitForActivity()); 350 } 351 testNoPostCallActivityForIncomingEmergencyCall()352 public void testNoPostCallActivityForIncomingEmergencyCall() throws Exception { 353 if (!shouldTestTelecom(mContext)) { 354 return; 355 } 356 setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); 357 mCallScreeningControl.setCallResponse(false /* shouldDisallowCall */, 358 false /* shouldRejectCall */, false /* shouldSilenceCall */, 359 false /* shouldSkipCallLog */, false /* shouldSkipNotification */); 360 Bundle extras = new Bundle(); 361 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, TEST_EMERGENCY_URI); 362 extras.putBoolean(EXTRA_NETWORK_IDENTIFIED_EMERGENCY_CALL, true); 363 mTelecomManager.addNewIncomingCall(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, extras); 364 365 // Wait until the new incoming call is processed. 366 waitOnAllHandlers(getInstrumentation()); 367 mInCallCallbacks.getService().disconnectAllCalls(); 368 369 assertFalse(mCallScreeningControl.waitForActivity()); 370 } 371 placeOutgoingCall(boolean addContact)372 private void placeOutgoingCall(boolean addContact) throws Exception { 373 // Setup content observer to notify us when we call log entry is added. 374 CountDownLatch callLogEntryLatch = getCallLogEntryLatch(); 375 376 Uri contactUri = null; 377 if (addContact) { 378 contactUri = TestUtils.insertContact(mContentResolver, 379 TEST_OUTGOING_NUMBER.getSchemeSpecificPart()); 380 } 381 Bundle extras = new Bundle(); 382 extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, TEST_OUTGOING_NUMBER); 383 // Create a new outgoing call. 384 placeAndVerifyCall(extras); 385 386 if (addContact) { 387 assertEquals(1, TestUtils.deleteContact(mContentResolver, contactUri)); 388 } 389 390 mInCallCallbacks.getService().disconnectAllCalls(); 391 assertNumCalls(mInCallCallbacks.getService(), 0); 392 393 // Wait for it to log. 394 callLogEntryLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 395 } 396 addIncoming(boolean disconnectImmediately, boolean addContact)397 private Uri addIncoming(boolean disconnectImmediately, boolean addContact) throws Exception { 398 // Add call through TelecomManager; we can't use the test methods since they assume a call 399 // makes it through to the InCallService; this is blocked so it shouldn't. 400 Uri testNumber = createRandomTestNumber(); 401 if (addContact) { 402 mContactUri = TestUtils.insertContact(mContentResolver, 403 testNumber.getSchemeSpecificPart()); 404 } 405 406 // Setup content observer to notify us when we call log entry is added. 407 CountDownLatch callLogEntryLatch = getCallLogEntryLatch(); 408 409 Bundle extras = new Bundle(); 410 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, testNumber); 411 mTelecomManager.addNewIncomingCall(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, extras); 412 413 // Wait until the new incoming call is processed. 414 waitOnAllHandlers(getInstrumentation()); 415 416 if (disconnectImmediately) { 417 // Disconnect the call 418 mInCallCallbacks.getService().disconnectAllCalls(); 419 assertNumCalls(mInCallCallbacks.getService(), 0); 420 } 421 422 // Wait for the content observer to report that we have gotten a new call log entry. 423 callLogEntryLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 424 return testNumber; 425 } 426 addIncomingAndVerifyAllowed(boolean addContact)427 private void addIncomingAndVerifyAllowed(boolean addContact) throws Exception { 428 Uri testNumber = addIncoming(true, addContact); 429 430 // Query the latest entry into the call log. 431 Cursor callsCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, null, 432 null, null, CallLog.Calls._ID + " DESC limit 1;"); 433 int numberIndex = callsCursor.getColumnIndex(CallLog.Calls.NUMBER); 434 int callTypeIndex = callsCursor.getColumnIndex(CallLog.Calls.TYPE); 435 int blockReasonIndex = callsCursor.getColumnIndex(CallLog.Calls.BLOCK_REASON); 436 if (callsCursor.moveToNext()) { 437 String number = callsCursor.getString(numberIndex); 438 int callType = callsCursor.getInt(callTypeIndex); 439 int blockReason = callsCursor.getInt(blockReasonIndex); 440 assertEquals(testNumber.getSchemeSpecificPart(), number); 441 assertEquals(CallLog.Calls.INCOMING_TYPE, callType); 442 assertEquals(CallLog.Calls.BLOCK_REASON_NOT_BLOCKED, blockReason); 443 } else { 444 fail("Call not logged"); 445 } 446 447 if (addContact && mContactUri != null) { 448 assertEquals(1, TestUtils.deleteContact(mContentResolver, mContactUri)); 449 } 450 } 451 addIncomingAndVerifyBlocked(boolean addContact)452 private void addIncomingAndVerifyBlocked(boolean addContact) throws Exception { 453 Uri testNumber = addIncoming(false, addContact); 454 455 // Query the latest entry into the call log. 456 Cursor callsCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, null, 457 null, null, CallLog.Calls._ID + " DESC limit 1;"); 458 int numberIndex = callsCursor.getColumnIndex(CallLog.Calls.NUMBER); 459 int callTypeIndex = callsCursor.getColumnIndex(CallLog.Calls.TYPE); 460 int blockReasonIndex = callsCursor.getColumnIndex(CallLog.Calls.BLOCK_REASON); 461 int callScreeningAppNameIndex = callsCursor.getColumnIndex( 462 CallLog.Calls.CALL_SCREENING_APP_NAME); 463 int callScreeningCmpNameIndex = callsCursor.getColumnIndex( 464 CallLog.Calls.CALL_SCREENING_COMPONENT_NAME); 465 if (callsCursor.moveToNext()) { 466 String number = callsCursor.getString(numberIndex); 467 int callType = callsCursor.getInt(callTypeIndex); 468 int blockReason = callsCursor.getInt(blockReasonIndex); 469 String screeningAppName = callsCursor.getString(callScreeningAppNameIndex); 470 String screeningComponentName = callsCursor.getString(callScreeningCmpNameIndex); 471 assertEquals(testNumber.getSchemeSpecificPart(), number); 472 assertEquals(CallLog.Calls.BLOCKED_TYPE, callType); 473 assertEquals(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, blockReason); 474 assertEquals(TEST_APP_NAME, screeningAppName); 475 assertEquals(TEST_APP_COMPONENT, screeningComponentName); 476 } else { 477 fail("Blocked call was not logged."); 478 } 479 480 if (addContact && mContactUri != null) { 481 assertEquals(1, TestUtils.deleteContact(mContentResolver, mContactUri)); 482 } 483 } 484 addIncomingAndVerifyCallExtraForSilence(boolean expectedIsSilentRingingExtraSet)485 private void addIncomingAndVerifyCallExtraForSilence(boolean expectedIsSilentRingingExtraSet) 486 throws Exception { 487 Uri testNumber = addIncoming(false, false); 488 489 waitUntilConditionIsTrueOrTimeout( 490 new Condition() { 491 @Override 492 public Object expected() { 493 return true; 494 } 495 496 @Override 497 public Object actual() { 498 // Verify that the call extra matches expectation 499 Call call = mInCallCallbacks.getService().getLastCall(); 500 return expectedIsSilentRingingExtraSet == 501 call.getDetails().getExtras().getBoolean( 502 Call.EXTRA_SILENT_RINGING_REQUESTED); 503 } 504 }, 505 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, 506 "Call extra - verification failed, expected the extra " + 507 "EXTRA_SILENT_RINGING_REQUESTED to be set:" + 508 expectedIsSilentRingingExtraSet); 509 } 510 511 /** 512 * Sets up a binder used to control the CallScreeningServiceCtsTestApp. 513 * This app is a standalone APK so that it can reside in a package name outside of the one the 514 * CTS test itself runs in (since that APK is where the CTS InCallService resides). 515 * @throws InterruptedException 516 */ setupControlBinder()517 private void setupControlBinder() throws InterruptedException { 518 Intent bindIntent = new Intent(CallScreeningServiceControl.CONTROL_INTERFACE_ACTION); 519 bindIntent.setComponent(CallScreeningServiceControl.CONTROL_INTERFACE_COMPONENT); 520 final CountDownLatch bindLatch = new CountDownLatch(1); 521 522 boolean success = mContext.bindService(bindIntent, new ServiceConnection() { 523 @Override 524 public void onServiceConnected(ComponentName name, IBinder service) { 525 mCallScreeningControl = ICallScreeningControl.Stub.asInterface(service); 526 bindLatch.countDown(); 527 } 528 529 @Override 530 public void onServiceDisconnected(ComponentName name) { 531 mCallScreeningControl = null; 532 } 533 }, Context.BIND_AUTO_CREATE); 534 if (!success) { 535 fail("Failed to get control interface -- bind error"); 536 } 537 bindLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 538 } 539 540 /** 541 * Use RoleManager to query the previous call screening app so we can restore it later. 542 */ rememberPreviousCallScreeningApp()543 private void rememberPreviousCallScreeningApp() { 544 runWithShellPermissionIdentity(() -> { 545 List<String> callScreeningApps = mRoleManager.getRoleHolders(ROLE_CALL_SCREENING); 546 if (!callScreeningApps.isEmpty()) { 547 mPreviousCallScreeningPackage = callScreeningApps.get(0); 548 } else { 549 mPreviousCallScreeningPackage = null; 550 } 551 }); 552 } 553 addRoleHolder(String roleName, String packageName)554 private void addRoleHolder(String roleName, String packageName) 555 throws Exception { 556 UserHandle user = Process.myUserHandle(); 557 Executor executor = mContext.getMainExecutor(); 558 LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1); 559 560 runWithShellPermissionIdentity(() -> mRoleManager.addRoleHolderAsUser(roleName, 561 packageName, RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, executor, 562 successful -> { 563 try { 564 queue.put(successful); 565 } catch (InterruptedException e) { 566 e.printStackTrace(); 567 } 568 })); 569 boolean result = queue.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 570 assertTrue(result); 571 } 572 removeRoleHolder(String roleName, String packageName)573 private void removeRoleHolder(String roleName, String packageName) 574 throws Exception { 575 UserHandle user = Process.myUserHandle(); 576 Executor executor = mContext.getMainExecutor(); 577 LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1); 578 579 runWithShellPermissionIdentity(() -> mRoleManager.removeRoleHolderAsUser(roleName, 580 packageName, RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, executor, 581 successful -> { 582 try { 583 queue.put(successful); 584 } catch (InterruptedException e) { 585 e.printStackTrace(); 586 } 587 })); 588 boolean result = queue.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 589 assertTrue(result); 590 } 591 grantReadContactPermission()592 private void grantReadContactPermission() { 593 runWithShellPermissionIdentity(() -> { 594 if (mPackageManager != null) { 595 mPackageManager.grantRuntimePermission(TEST_APP_PACKAGE, 596 Manifest.permission.READ_CONTACTS, mContext.getUser()); 597 }}); 598 } 599 revokeReadContactPermission()600 private void revokeReadContactPermission() { 601 runWithShellPermissionIdentity(() -> { 602 if (mPackageManager != null) { 603 mPackageManager.revokeRuntimePermission(TEST_APP_PACKAGE, 604 Manifest.permission.READ_CONTACTS, mContext.getUser()); 605 }}); 606 } 607 verifyPermission(boolean hasPermission)608 private void verifyPermission(boolean hasPermission) { 609 assertEquals(hasPermission, 610 mPackageManager.checkPermission 611 (Manifest.permission.READ_CONTACTS, TEST_APP_PACKAGE) 612 == PackageManager.PERMISSION_GRANTED); 613 } 614 } 615