1 package android.telecom.cts; 2 3 import static android.app.role.RoleManager.ROLE_CALL_SCREENING; 4 import static android.telecom.cts.TestUtils.TEST_PHONE_ACCOUNT_HANDLE; 5 import static android.telecom.cts.TestUtils.waitOnAllHandlers; 6 7 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 8 9 import android.app.role.RoleManager; 10 import android.content.Context; 11 import android.content.ServiceConnection; 12 import android.media.AudioManager; 13 import android.os.Bundle; 14 import android.os.Process; 15 import android.os.UserHandle; 16 import android.provider.CallLog; 17 import android.telecom.Call; 18 import android.telecom.Call.Details; 19 import android.telecom.CallScreeningService.CallResponse; 20 import android.telecom.Connection; 21 import android.telecom.DisconnectCause; 22 import android.telecom.TelecomManager; 23 import android.telecom.VideoProfile; 24 import android.telecom.cts.MockCallScreeningService.CallScreeningServiceCallbacks; 25 import android.telecom.cts.api29incallservice.ICtsApi29InCallServiceControl; 26 import android.text.TextUtils; 27 import android.util.Pair; 28 29 import androidx.test.InstrumentationRegistry; 30 31 import java.util.concurrent.Executor; 32 import java.util.concurrent.LinkedBlockingQueue; 33 import java.util.concurrent.TimeUnit; 34 35 public class BackgroundCallAudioTest extends BaseTelecomTestWithMockServices { 36 private static final String LOG_TAG = BackgroundCallAudioTest.class.getSimpleName(); 37 38 private static final int ASYNC_TIMEOUT = 10000; 39 private RoleManager mRoleManager; 40 private ServiceConnection mApiCompatControlServiceConnection; 41 42 // copied from AudioSystem.java -- defined here because that change isn't in AOSP yet. 43 private static final int MODE_CALL_SCREENING = 4; 44 45 // true if there's platform support for call screening in the audio stack. 46 private boolean doesAudioManagerSupportCallScreening = false; 47 48 private String mPreviousDefaultDialer = null; 49 50 @Override setUp()51 protected void setUp() throws Exception { 52 super.setUp(); 53 if (mShouldTestTelecom) { 54 mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 55 clearRoleHoldersAsUser(ROLE_CALL_SCREENING); 56 mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation()); 57 TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE); 58 setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE); 59 // Some of the tests expect changes in audio mode when the ringer starts, so we're 60 // going to turn up the ring stream volume. 61 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 62 audioManager.adjustStreamVolume(AudioManager.STREAM_RING, 63 AudioManager.ADJUST_UNMUTE, 0); 64 doesAudioManagerSupportCallScreening = 65 audioManager.isCallScreeningModeSupported(); 66 } 67 } 68 69 @Override tearDown()70 protected void tearDown() throws Exception { 71 if (mShouldTestTelecom && !TextUtils.isEmpty(mPreviousDefaultDialer)) { 72 TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer); 73 MockCallScreeningService.disableService(mContext); 74 } 75 super.tearDown(); 76 } 77 testAudioProcessingFromCallScreeningAllow()78 public void testAudioProcessingFromCallScreeningAllow() throws Exception { 79 if (!mShouldTestTelecom) { 80 return; 81 } 82 83 setupIncomingCallWithCallScreening(); 84 85 final MockConnection connection = verifyConnectionForIncomingCall(); 86 87 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 88 TimeUnit.SECONDS)) { 89 fail("No call added to InCallService."); 90 } 91 92 Call call = mInCallCallbacks.getService().getLastCall(); 93 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 94 assertConnectionState(connection, Connection.STATE_ACTIVE); 95 96 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 97 if (doesAudioManagerSupportCallScreening) { 98 assertAudioMode(audioManager, MODE_CALL_SCREENING); 99 } 100 101 verifySimulateRingAndUserPickup(call, connection); 102 } 103 testHoldAfterAudioProcessingFromCallScreening()104 public void testHoldAfterAudioProcessingFromCallScreening() throws Exception { 105 if (!mShouldTestTelecom) { 106 return; 107 } 108 109 setupIncomingCallWithCallScreening(); 110 111 final MockConnection connection = verifyConnectionForIncomingCall(); 112 113 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 114 TimeUnit.SECONDS)) { 115 fail("No call added to InCallService."); 116 } 117 118 Call call = mInCallCallbacks.getService().getLastCall(); 119 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 120 assertConnectionState(connection, Connection.STATE_ACTIVE); 121 122 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 123 if (doesAudioManagerSupportCallScreening) { 124 assertAudioMode(audioManager, MODE_CALL_SCREENING); 125 } 126 127 verifySimulateRingAndUserPickup(call, connection); 128 129 call.hold(); 130 assertCallState(call, Call.STATE_HOLDING); 131 call.unhold(); 132 assertCallState(call, Call.STATE_ACTIVE); 133 } 134 testAudioProcessingFromCallScreeningDisallow()135 public void testAudioProcessingFromCallScreeningDisallow() throws Exception { 136 if (!mShouldTestTelecom) { 137 return; 138 } 139 140 setupIncomingCallWithCallScreening(); 141 142 final MockConnection connection = verifyConnectionForIncomingCall(); 143 144 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 145 TimeUnit.SECONDS)) { 146 fail("No call added to InCallService."); 147 } 148 149 Call call = mInCallCallbacks.getService().getLastCall(); 150 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 151 assertConnectionState(connection, Connection.STATE_ACTIVE); 152 153 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 154 if (doesAudioManagerSupportCallScreening) { 155 assertAudioMode(audioManager, MODE_CALL_SCREENING); 156 } 157 158 call.disconnect(); 159 assertCallState(call, Call.STATE_DISCONNECTED); 160 assertEquals(DisconnectCause.REJECTED, call.getDetails().getDisconnectCause().getCode()); 161 } 162 testAudioProcessingFromCallScreeningMissed()163 public void testAudioProcessingFromCallScreeningMissed() throws Exception { 164 if (!mShouldTestTelecom) { 165 return; 166 } 167 168 setupIncomingCallWithCallScreening(); 169 170 final MockConnection connection = verifyConnectionForIncomingCall(); 171 172 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 173 TimeUnit.SECONDS)) { 174 fail("No call added to InCallService."); 175 } 176 177 Call call = mInCallCallbacks.getService().getLastCall(); 178 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 179 assertConnectionState(connection, Connection.STATE_ACTIVE); 180 181 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 182 if (doesAudioManagerSupportCallScreening) { 183 assertAudioMode(audioManager, MODE_CALL_SCREENING); 184 } 185 186 verifySimulateRingAndUserMissed(call, connection); 187 } 188 testAudioProcessingFromCallScreeningRemoteHangupDuringRing()189 public void testAudioProcessingFromCallScreeningRemoteHangupDuringRing() throws Exception { 190 if (!mShouldTestTelecom) { 191 return; 192 } 193 194 setupIncomingCallWithCallScreening(); 195 196 final MockConnection connection = verifyConnectionForIncomingCall(); 197 198 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 199 TimeUnit.SECONDS)) { 200 fail("No call added to InCallService."); 201 } 202 203 Call call = mInCallCallbacks.getService().getLastCall(); 204 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 205 assertConnectionState(connection, Connection.STATE_ACTIVE); 206 207 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 208 if (doesAudioManagerSupportCallScreening) { 209 assertAudioMode(audioManager, MODE_CALL_SCREENING); 210 } 211 212 call.exitBackgroundAudioProcessing(true); 213 assertCallState(call, Call.STATE_SIMULATED_RINGING); 214 215 waitOnAllHandlers(getInstrumentation()); 216 // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. 217 if (doesAudioManagerSupportCallScreening) { 218 assertAudioMode(audioManager, MODE_CALL_SCREENING); 219 } 220 assertConnectionState(connection, Connection.STATE_ACTIVE); 221 222 connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE)); 223 assertCallState(call, Call.STATE_DISCONNECTED); 224 assertEquals(DisconnectCause.MISSED, call.getDetails().getDisconnectCause().getCode()); 225 connection.destroy(); 226 } 227 testAudioProcessingFromCallScreeningAllowPlaceEmergencyCall()228 public void testAudioProcessingFromCallScreeningAllowPlaceEmergencyCall() throws Exception { 229 if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) { 230 return; 231 } 232 setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); 233 setupIncomingCallWithCallScreening(); 234 235 final MockConnection connection = verifyConnectionForIncomingCall(); 236 237 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 238 TimeUnit.SECONDS)) { 239 fail("No call added to InCallService."); 240 } 241 242 Call call = mInCallCallbacks.getService().getLastCall(); 243 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 244 assertConnectionState(connection, Connection.STATE_ACTIVE); 245 246 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 247 if (doesAudioManagerSupportCallScreening) { 248 assertAudioMode(audioManager, MODE_CALL_SCREENING); 249 } 250 251 call.exitBackgroundAudioProcessing(true); 252 assertCallState(call, Call.STATE_SIMULATED_RINGING); 253 waitOnAllHandlers(getInstrumentation()); 254 // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. 255 if (doesAudioManagerSupportCallScreening) { 256 assertAudioMode(audioManager, MODE_CALL_SCREENING); 257 } 258 assertConnectionState(connection, Connection.STATE_ACTIVE); 259 260 placeAndVerifyEmergencyCall(false /*supportsHold*/); 261 waitOnAllHandlers(getInstrumentation()); 262 Call eCall = getInCallService().getLastCall(); 263 assertCallState(eCall, Call.STATE_DIALING); 264 // Even though the connection was technically active, it is "simulated ringing", so 265 // disconnect as you would a normal ringing call in favor of an emergency call. 266 assertCallState(call, Call.STATE_DISCONNECTED); 267 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 268 // Notify as missed instead of rejected, since the user did not explicitly reject. 269 verifyCallLogging(connection.getAddress(), CallLog.Calls.MISSED_TYPE, 270 TestUtils.TEST_PHONE_ACCOUNT_HANDLE); 271 } 272 testAudioProcessingFromIncomingActivePlaceEmergencyCall()273 public void testAudioProcessingFromIncomingActivePlaceEmergencyCall() throws Exception { 274 if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) { 275 return; 276 } 277 setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); 278 setupIncomingCallWithCallScreening(); 279 280 final MockConnection connection = verifyConnectionForIncomingCall(); 281 282 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 283 TimeUnit.SECONDS)) { 284 fail("No call added to InCallService."); 285 } 286 287 Call call = mInCallCallbacks.getService().getLastCall(); 288 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 289 assertConnectionState(connection, Connection.STATE_ACTIVE); 290 291 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 292 if (doesAudioManagerSupportCallScreening) { 293 assertAudioMode(audioManager, MODE_CALL_SCREENING); 294 } 295 296 verifySimulateRingAndUserPickup(call, connection); 297 // Go back into audio processing for hold case 298 call.enterBackgroundAudioProcessing(); 299 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 300 waitOnAllHandlers(getInstrumentation()); 301 302 placeAndVerifyEmergencyCall(false /*supportsHold*/); 303 waitOnAllHandlers(getInstrumentation()); 304 Call eCall = getInCallService().getLastCall(); 305 assertCallState(eCall, Call.STATE_DIALING); 306 // Even though the connection was technically active, it is "simulated ringing", so 307 // disconnect as you would a normal ringing call in favor of an emergency call. 308 assertCallState(call, Call.STATE_DISCONNECTED); 309 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 310 // Notify as incoming, since the user has already answered the call. 311 verifyCallLogging(connection.getAddress(), CallLog.Calls.INCOMING_TYPE, 312 TestUtils.TEST_PHONE_ACCOUNT_HANDLE); 313 } 314 testAudioProcessActiveCall()315 public void testAudioProcessActiveCall() { 316 if (!mShouldTestTelecom) { 317 return; 318 } 319 320 Connection connection = placeActiveOutgoingCall(); 321 Call call = mInCallCallbacks.getService().getLastCall(); 322 323 call.enterBackgroundAudioProcessing(); 324 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 325 326 waitOnAllHandlers(getInstrumentation()); 327 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 328 if (doesAudioManagerSupportCallScreening) { 329 assertAudioMode(audioManager, MODE_CALL_SCREENING); 330 } 331 assertConnectionState(connection, Connection.STATE_ACTIVE); 332 333 verifySimulateRingAndUserPickup(call, connection); 334 } 335 testAudioProcessActiveCallMissed()336 public void testAudioProcessActiveCallMissed() throws Exception { 337 if (!mShouldTestTelecom) { 338 return; 339 } 340 341 Connection connection = placeActiveOutgoingCall(); 342 Call call = mInCallCallbacks.getService().getLastCall(); 343 344 call.enterBackgroundAudioProcessing(); 345 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 346 assertConnectionState(connection, Connection.STATE_ACTIVE); 347 348 waitOnAllHandlers(getInstrumentation()); 349 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 350 if (doesAudioManagerSupportCallScreening) { 351 assertAudioMode(audioManager, MODE_CALL_SCREENING); 352 } 353 354 verifySimulateRingAndUserMissed(call, connection); 355 } 356 testAudioProcessActiveCallRemoteHangup()357 public void testAudioProcessActiveCallRemoteHangup() { 358 if (!mShouldTestTelecom) { 359 return; 360 } 361 362 Connection connection = placeActiveOutgoingCall(); 363 Call call = mInCallCallbacks.getService().getLastCall(); 364 365 call.enterBackgroundAudioProcessing(); 366 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 367 assertConnectionState(connection, Connection.STATE_ACTIVE); 368 369 waitOnAllHandlers(getInstrumentation()); 370 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 371 if (doesAudioManagerSupportCallScreening) { 372 assertAudioMode(audioManager, MODE_CALL_SCREENING); 373 } 374 375 connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE)); 376 assertCallState(call, Call.STATE_DISCONNECTED); 377 assertEquals(DisconnectCause.REMOTE, call.getDetails().getDisconnectCause().getCode()); 378 connection.destroy(); 379 } 380 testAudioProcessOutgoingActiveEmergencyCallPlaced()381 public void testAudioProcessOutgoingActiveEmergencyCallPlaced() throws Exception { 382 if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) { 383 return; 384 } 385 setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); 386 387 Connection connection = placeActiveOutgoingCall(); 388 Call call = mInCallCallbacks.getService().getLastCall(); 389 390 call.enterBackgroundAudioProcessing(); 391 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 392 assertConnectionState(connection, Connection.STATE_ACTIVE); 393 394 waitOnAllHandlers(getInstrumentation()); 395 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 396 if (doesAudioManagerSupportCallScreening) { 397 assertAudioMode(audioManager, MODE_CALL_SCREENING); 398 } 399 400 placeAndVerifyEmergencyCall(false /*supportsHold*/); 401 waitOnAllHandlers(getInstrumentation()); 402 Call eCall = getInCallService().getLastCall(); 403 // emergency call should be dialing 404 assertCallState(eCall, Call.STATE_DIALING); 405 // audio processing call should be disconnected 406 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 407 assertCallState(call, Call.STATE_DISCONNECTED); 408 // If we went to AUDIO_PROCESSING from an active outgoing call, Make sure the call is 409 // marked outgoing, not missed. 410 verifyCallLogging(connection.getAddress(), CallLog.Calls.OUTGOING_TYPE, 411 TestUtils.TEST_PHONE_ACCOUNT_HANDLE); 412 } 413 testManualAudioCallScreenAccept()414 public void testManualAudioCallScreenAccept() { 415 if (!mShouldTestTelecom) { 416 return; 417 } 418 419 addAndVerifyNewIncomingCall(createTestNumber(), null); 420 final MockConnection connection = verifyConnectionForIncomingCall(); 421 422 Call call = mInCallCallbacks.getService().getLastCall(); 423 assertCallState(call, Call.STATE_RINGING); 424 425 call.enterBackgroundAudioProcessing(); 426 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 427 assertConnectionState(connection, Connection.STATE_ACTIVE); 428 429 waitOnAllHandlers(getInstrumentation()); 430 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 431 if (doesAudioManagerSupportCallScreening) { 432 assertAudioMode(audioManager, MODE_CALL_SCREENING); 433 } 434 435 call.exitBackgroundAudioProcessing(false); 436 assertCallState(call, Call.STATE_ACTIVE); 437 waitOnAllHandlers(getInstrumentation()); 438 assertAudioMode(audioManager, AudioManager.MODE_IN_CALL); 439 } 440 testManualAudioCallScreenReject()441 public void testManualAudioCallScreenReject() { 442 if (!mShouldTestTelecom) { 443 return; 444 } 445 446 addAndVerifyNewIncomingCall(createTestNumber(), null); 447 final MockConnection connection = verifyConnectionForIncomingCall(); 448 449 Call call = mInCallCallbacks.getService().getLastCall(); 450 assertCallState(call, Call.STATE_RINGING); 451 452 call.enterBackgroundAudioProcessing(); 453 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 454 assertConnectionState(connection, Connection.STATE_ACTIVE); 455 456 waitOnAllHandlers(getInstrumentation()); 457 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 458 if (doesAudioManagerSupportCallScreening) { 459 assertAudioMode(audioManager, MODE_CALL_SCREENING); 460 } 461 462 call.disconnect(); 463 assertCallState(call, Call.STATE_DISCONNECTED); 464 assertEquals(DisconnectCause.REJECTED, call.getDetails().getDisconnectCause().getCode()); 465 } 466 testEnterAudioProcessingWithoutPermission()467 public void testEnterAudioProcessingWithoutPermission() { 468 if (!mShouldTestTelecom) { 469 return; 470 } 471 472 if (true) { 473 // TODO: enable test 474 return; 475 } 476 477 placeAndVerifyCall(); 478 final MockConnection connection = verifyConnectionForOutgoingCall(); 479 480 final MockInCallService inCallService = mInCallCallbacks.getService(); 481 482 connection.setActive(); 483 final Call call = inCallService.getLastCall(); 484 assertCallState(call, Call.STATE_ACTIVE); 485 486 try { 487 call.enterBackgroundAudioProcessing(); 488 fail("Expected SecurityException"); 489 } catch (SecurityException e) { 490 // expected 491 } 492 } 493 testLowerApiLevelCompatibility1()494 public void testLowerApiLevelCompatibility1() throws Exception { 495 if (!mShouldTestTelecom) { 496 return; 497 } 498 499 InstrumentationRegistry.getInstrumentation().getUiAutomation() 500 .adoptShellPermissionIdentity("android.permission.CONTROL_INCALL_EXPERIENCE"); 501 try { 502 ICtsApi29InCallServiceControl controlInterface = setUpControl(); 503 504 setupIncomingCallWithCallScreening(); 505 506 final MockConnection connection = verifyConnectionForIncomingCall(); 507 508 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 509 TimeUnit.SECONDS)) { 510 fail("No call added to InCallService."); 511 } 512 513 Call call = mInCallCallbacks.getService().getLastCall(); 514 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 515 assertConnectionState(connection, Connection.STATE_ACTIVE); 516 // Make sure that the test app never got any calls 517 assertEquals(0, controlInterface.getHistoricalCallCount()); 518 519 call.exitBackgroundAudioProcessing(true); 520 assertCallState(call, Call.STATE_SIMULATED_RINGING); 521 waitOnAllHandlers(getInstrumentation()); 522 assertConnectionState(connection, Connection.STATE_ACTIVE); 523 // Make sure that the test app sees a ringing call. 524 assertEquals(Call.STATE_RINGING, 525 controlInterface.getCallState(call.getDetails().getTelecomCallId())); 526 527 call.answer(VideoProfile.STATE_AUDIO_ONLY); 528 assertCallState(call, Call.STATE_ACTIVE); 529 waitOnAllHandlers(getInstrumentation()); 530 assertConnectionState(connection, Connection.STATE_ACTIVE); 531 // Make sure that the test app sees an active call. 532 assertEquals(Call.STATE_ACTIVE, 533 controlInterface.getCallState(call.getDetails().getTelecomCallId())); 534 535 tearDownControl(); 536 } finally { 537 InstrumentationRegistry.getInstrumentation().getUiAutomation() 538 .dropShellPermissionIdentity(); 539 } 540 } 541 testLowerApiLevelCompatibility2()542 public void testLowerApiLevelCompatibility2() throws Exception { 543 if (!mShouldTestTelecom) { 544 return; 545 } 546 InstrumentationRegistry.getInstrumentation().getUiAutomation() 547 .adoptShellPermissionIdentity("android.permission.CONTROL_INCALL_EXPERIENCE"); 548 try { 549 ICtsApi29InCallServiceControl controlInterface = setUpControl(); 550 551 setupIncomingCallWithCallScreening(); 552 553 final MockConnection connection = verifyConnectionForIncomingCall(); 554 555 if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 556 TimeUnit.SECONDS)) { 557 fail("No call added to InCallService."); 558 } 559 560 Call call = mInCallCallbacks.getService().getLastCall(); 561 assertCallState(call, Call.STATE_AUDIO_PROCESSING); 562 assertConnectionState(connection, Connection.STATE_ACTIVE); 563 // Make sure that the test app never got any calls 564 assertEquals(0, controlInterface.getHistoricalCallCount()); 565 566 call.disconnect(); 567 assertCallState(call, Call.STATE_DISCONNECTED); 568 waitOnAllHandlers(getInstrumentation()); 569 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 570 // Under some rare circumstances, the test app might get a flash of the disconnection 571 // call, so we won't do the call count check again. 572 573 tearDownControl(); 574 } finally { 575 InstrumentationRegistry.getInstrumentation().getUiAutomation() 576 .dropShellPermissionIdentity(); 577 } 578 } 579 placeActiveOutgoingCall()580 private Connection placeActiveOutgoingCall() { 581 placeAndVerifyCall(); 582 583 Call call = mInCallCallbacks.getService().getLastCall(); 584 assertCallState(call, Call.STATE_DIALING); 585 586 final MockConnection connection = verifyConnectionForOutgoingCall(); 587 connection.setActive(); 588 assertCallState(call, Call.STATE_ACTIVE); 589 return connection; 590 } 591 verifySimulateRingAndUserPickup(Call call, Connection connection)592 private void verifySimulateRingAndUserPickup(Call call, Connection connection) { 593 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 594 595 call.exitBackgroundAudioProcessing(true); 596 assertCallState(call, Call.STATE_SIMULATED_RINGING); 597 waitOnAllHandlers(getInstrumentation()); 598 // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. 599 if (doesAudioManagerSupportCallScreening) { 600 assertAudioMode(audioManager, MODE_CALL_SCREENING); 601 } 602 assertConnectionState(connection, Connection.STATE_ACTIVE); 603 604 call.answer(VideoProfile.STATE_AUDIO_ONLY); 605 assertCallState(call, Call.STATE_ACTIVE); 606 waitOnAllHandlers(getInstrumentation()); 607 assertAudioMode(audioManager, AudioManager.MODE_IN_CALL); 608 assertConnectionState(connection, Connection.STATE_ACTIVE); 609 } 610 verifySimulateRingAndUserMissed(Call call, Connection connection)611 private void verifySimulateRingAndUserMissed(Call call, Connection connection) { 612 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 613 614 call.exitBackgroundAudioProcessing(true); 615 assertCallState(call, Call.STATE_SIMULATED_RINGING); 616 waitOnAllHandlers(getInstrumentation()); 617 // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. 618 if (doesAudioManagerSupportCallScreening) { 619 assertAudioMode(audioManager, MODE_CALL_SCREENING); 620 } 621 assertConnectionState(connection, Connection.STATE_ACTIVE); 622 assertTrue(mTelecomManager.isRinging()); 623 624 call.disconnect(); 625 assertCallState(call, Call.STATE_DISCONNECTED); 626 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 627 assertEquals(DisconnectCause.MISSED, call.getDetails().getDisconnectCause().getCode()); 628 } 629 setupIncomingCallWithCallScreening()630 private void setupIncomingCallWithCallScreening() throws Exception { 631 CallScreeningServiceCallbacks callback = new CallScreeningServiceCallbacks() { 632 @Override 633 public void onScreenCall(Details callDetails) { 634 getService().respondToCall(callDetails, new CallResponse.Builder() 635 .setDisallowCall(false) 636 .setShouldScreenCallViaAudioProcessing(true) 637 .build()); 638 lock.release(); 639 } 640 }; 641 MockCallScreeningService.enableService(mContext); 642 MockCallScreeningService.setCallbacks(callback); 643 Bundle extras = new Bundle(); 644 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, createTestNumber()); 645 mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras); 646 647 if (!callback.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, 648 TimeUnit.SECONDS)) { 649 fail("Call screening service never got the call"); 650 } 651 652 } 653 setUpControl()654 private ICtsApi29InCallServiceControl setUpControl() throws Exception { 655 Pair<ServiceConnection, ICtsApi29InCallServiceControl> setupResult = 656 Api29InCallUtils.setupControl(mContext); 657 mApiCompatControlServiceConnection = setupResult.first; 658 return setupResult.second; 659 } 660 tearDownControl()661 private void tearDownControl() throws Exception { 662 Api29InCallUtils.tearDownControl(mContext, 663 mApiCompatControlServiceConnection); 664 } 665 clearRoleHoldersAsUser(String roleName)666 private void clearRoleHoldersAsUser(String roleName) 667 throws Exception { 668 UserHandle user = Process.myUserHandle(); 669 Executor executor = mContext.getMainExecutor(); 670 LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1); 671 672 runWithShellPermissionIdentity(() -> mRoleManager.clearRoleHoldersAsUser(roleName, 673 RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, executor, 674 successful -> { 675 try { 676 queue.put(successful); 677 } catch (InterruptedException e) { 678 e.printStackTrace(); 679 } 680 })); 681 boolean result = queue.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 682 assertTrue(result); 683 } 684 } 685