| package android.telecom.cts; |
| |
| import static android.telecom.cts.TestUtils.TEST_PHONE_ACCOUNT_HANDLE; |
| import static android.telecom.cts.TestUtils.waitOnAllHandlers; |
| |
| import android.content.ServiceConnection; |
| import android.media.AudioManager; |
| import android.os.Bundle; |
| import android.provider.CallLog; |
| import android.telecom.Call; |
| import android.telecom.Call.Details; |
| import android.telecom.CallScreeningService.CallResponse; |
| import android.telecom.Connection; |
| import android.telecom.DisconnectCause; |
| import android.telecom.TelecomManager; |
| import android.telecom.VideoProfile; |
| import android.telecom.cts.MockCallScreeningService.CallScreeningServiceCallbacks; |
| import android.telecom.cts.api29incallservice.ICtsApi29InCallServiceControl; |
| import android.text.TextUtils; |
| import android.util.Pair; |
| |
| import androidx.test.InstrumentationRegistry; |
| |
| import java.util.concurrent.TimeUnit; |
| |
| public class BackgroundCallAudioTest extends BaseTelecomTestWithMockServices { |
| private static final String LOG_TAG = BackgroundCallAudioTest.class.getSimpleName(); |
| |
| private ServiceConnection mApiCompatControlServiceConnection; |
| |
| // copied from AudioSystem.java -- defined here because that change isn't in AOSP yet. |
| private static final int MODE_CALL_SCREENING = 4; |
| |
| // true if there's platform support for call screening in the audio stack. |
| private boolean doesAudioManagerSupportCallScreening = false; |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| if (mShouldTestTelecom) { |
| mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation()); |
| TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE); |
| setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE); |
| // Some of the tests expect changes in audio mode when the ringer starts, so we're |
| // going to turn up the ring stream volume. |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| audioManager.adjustStreamVolume(AudioManager.STREAM_RING, |
| AudioManager.ADJUST_UNMUTE, 0); |
| // TODO: uncomment when call screening APIs in AudioManager come to AOSP |
| /* |
| doesAudioManagerSupportCallScreening = |
| audioManager.isCallScreeningModeSupported(); |
| */ |
| } |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| if (mShouldTestTelecom && !TextUtils.isEmpty(mPreviousDefaultDialer)) { |
| TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer); |
| mTelecomManager.unregisterPhoneAccount(TEST_PHONE_ACCOUNT_HANDLE); |
| CtsConnectionService.tearDown(); |
| MockCallScreeningService.disableService(mContext); |
| } |
| super.tearDown(); |
| } |
| |
| public void testAudioProcessingFromCallScreeningAllow() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| verifySimulateRingAndUserPickup(call, connection); |
| } |
| |
| public void testAudioProcessingFromCallScreeningDisallow() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| call.disconnect(); |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| assertEquals(DisconnectCause.REJECTED, call.getDetails().getDisconnectCause().getCode()); |
| } |
| |
| public void testAudioProcessingFromCallScreeningMissed() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| verifySimulateRingAndUserMissed(call, connection); |
| } |
| |
| public void testAudioProcessingFromCallScreeningRemoteHangupDuringRing() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| call.exitBackgroundAudioProcessing(true); |
| assertCallState(call, Call.STATE_SIMULATED_RINGING); |
| |
| waitOnAllHandlers(getInstrumentation()); |
| // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE)); |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| assertEquals(DisconnectCause.MISSED, call.getDetails().getDisconnectCause().getCode()); |
| connection.destroy(); |
| } |
| |
| public void testAudioProcessingFromCallScreeningAllowPlaceEmergencyCall() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| call.exitBackgroundAudioProcessing(true); |
| assertCallState(call, Call.STATE_SIMULATED_RINGING); |
| waitOnAllHandlers(getInstrumentation()); |
| // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| placeAndVerifyEmergencyCall(false /*supportsHold*/); |
| waitOnAllHandlers(getInstrumentation()); |
| Call eCall = getInCallService().getLastCall(); |
| assertCallState(eCall, Call.STATE_DIALING); |
| // Even though the connection was technically active, it is "simulated ringing", so |
| // disconnect as you would a normal ringing call in favor of an emergency call. |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| assertConnectionState(connection, Connection.STATE_DISCONNECTED); |
| // Notify as missed instead of rejected, since the user did not explicitly reject. |
| verifyCallLogging(connection.getAddress(), CallLog.Calls.MISSED_TYPE); |
| } |
| |
| public void testAudioProcessingFromIncomingActivePlaceEmergencyCall() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| verifySimulateRingAndUserPickup(call, connection); |
| // Go back into audio processing for hold case |
| call.enterBackgroundAudioProcessing(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| waitOnAllHandlers(getInstrumentation()); |
| |
| placeAndVerifyEmergencyCall(false /*supportsHold*/); |
| waitOnAllHandlers(getInstrumentation()); |
| Call eCall = getInCallService().getLastCall(); |
| assertCallState(eCall, Call.STATE_DIALING); |
| // Even though the connection was technically active, it is "simulated ringing", so |
| // disconnect as you would a normal ringing call in favor of an emergency call. |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| assertConnectionState(connection, Connection.STATE_DISCONNECTED); |
| // Notify as incoming, since the user has already answered the call. |
| verifyCallLogging(connection.getAddress(), CallLog.Calls.INCOMING_TYPE); |
| } |
| |
| public void testAudioProcessActiveCall() { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| Connection connection = placeActiveOutgoingCall(); |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| |
| call.enterBackgroundAudioProcessing(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| |
| waitOnAllHandlers(getInstrumentation()); |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| verifySimulateRingAndUserPickup(call, connection); |
| } |
| |
| public void testAudioProcessActiveCallMissed() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| Connection connection = placeActiveOutgoingCall(); |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| |
| call.enterBackgroundAudioProcessing(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| waitOnAllHandlers(getInstrumentation()); |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| verifySimulateRingAndUserMissed(call, connection); |
| } |
| |
| public void testAudioProcessActiveCallRemoteHangup() { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| Connection connection = placeActiveOutgoingCall(); |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| |
| call.enterBackgroundAudioProcessing(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| waitOnAllHandlers(getInstrumentation()); |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE)); |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| assertEquals(DisconnectCause.REMOTE, call.getDetails().getDisconnectCause().getCode()); |
| connection.destroy(); |
| } |
| |
| public void testAudioProcessOutgoingActiveEmergencyCallPlaced() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| setupForEmergencyCalling(TEST_EMERGENCY_NUMBER); |
| |
| Connection connection = placeActiveOutgoingCall(); |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| |
| call.enterBackgroundAudioProcessing(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| waitOnAllHandlers(getInstrumentation()); |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| placeAndVerifyEmergencyCall(false /*supportsHold*/); |
| waitOnAllHandlers(getInstrumentation()); |
| Call eCall = getInCallService().getLastCall(); |
| // emergency call should be dialing |
| assertCallState(eCall, Call.STATE_DIALING); |
| // audio processing call should be disconnected |
| assertConnectionState(connection, Connection.STATE_DISCONNECTED); |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| // If we went to AUDIO_PROCESSING from an active outgoing call, Make sure the call is |
| // marked outgoing, not missed. |
| verifyCallLogging(connection.getAddress(), CallLog.Calls.OUTGOING_TYPE); |
| } |
| |
| public void testManualAudioCallScreenAccept() { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| addAndVerifyNewIncomingCall(createTestNumber(), null); |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_RINGING); |
| |
| call.enterBackgroundAudioProcessing(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| waitOnAllHandlers(getInstrumentation()); |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| call.exitBackgroundAudioProcessing(false); |
| assertCallState(call, Call.STATE_ACTIVE); |
| waitOnAllHandlers(getInstrumentation()); |
| assertAudioMode(audioManager, AudioManager.MODE_IN_CALL); |
| } |
| |
| public void testManualAudioCallScreenReject() { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| addAndVerifyNewIncomingCall(createTestNumber(), null); |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_RINGING); |
| |
| call.enterBackgroundAudioProcessing(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| waitOnAllHandlers(getInstrumentation()); |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| |
| call.disconnect(); |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| assertEquals(DisconnectCause.REJECTED, call.getDetails().getDisconnectCause().getCode()); |
| } |
| |
| public void testEnterAudioProcessingWithoutPermission() { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| if (true) { |
| // TODO: enable test |
| return; |
| } |
| |
| placeAndVerifyCall(); |
| final MockConnection connection = verifyConnectionForOutgoingCall(); |
| |
| final MockInCallService inCallService = mInCallCallbacks.getService(); |
| |
| connection.setActive(); |
| final Call call = inCallService.getLastCall(); |
| assertCallState(call, Call.STATE_ACTIVE); |
| |
| try { |
| call.enterBackgroundAudioProcessing(); |
| fail("Expected SecurityException"); |
| } catch (SecurityException e) { |
| // expected |
| } |
| } |
| |
| public void testLowerApiLevelCompatibility1() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| |
| InstrumentationRegistry.getInstrumentation().getUiAutomation() |
| .adoptShellPermissionIdentity("android.permission.CONTROL_INCALL_EXPERIENCE"); |
| try { |
| ICtsApi29InCallServiceControl controlInterface = setUpControl(); |
| |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| // Make sure that the dummy app never got any calls |
| assertEquals(0, controlInterface.getHistoricalCallCount()); |
| |
| call.exitBackgroundAudioProcessing(true); |
| assertCallState(call, Call.STATE_SIMULATED_RINGING); |
| waitOnAllHandlers(getInstrumentation()); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| // Make sure that the dummy app sees a ringing call. |
| assertEquals(Call.STATE_RINGING, |
| controlInterface.getCallState(call.getDetails().getTelecomCallId())); |
| |
| call.answer(VideoProfile.STATE_AUDIO_ONLY); |
| assertCallState(call, Call.STATE_ACTIVE); |
| waitOnAllHandlers(getInstrumentation()); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| // Make sure that the dummy app sees an active call. |
| assertEquals(Call.STATE_ACTIVE, |
| controlInterface.getCallState(call.getDetails().getTelecomCallId())); |
| |
| tearDownControl(); |
| } finally { |
| InstrumentationRegistry.getInstrumentation().getUiAutomation() |
| .dropShellPermissionIdentity(); |
| } |
| } |
| |
| public void testLowerApiLevelCompatibility2() throws Exception { |
| if (!mShouldTestTelecom) { |
| return; |
| } |
| InstrumentationRegistry.getInstrumentation().getUiAutomation() |
| .adoptShellPermissionIdentity("android.permission.CONTROL_INCALL_EXPERIENCE"); |
| try { |
| ICtsApi29InCallServiceControl controlInterface = setUpControl(); |
| |
| setupIncomingCallWithCallScreening(); |
| |
| final MockConnection connection = verifyConnectionForIncomingCall(); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_AUDIO_PROCESSING); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| // Make sure that the dummy app never got any calls |
| assertEquals(0, controlInterface.getHistoricalCallCount()); |
| |
| call.disconnect(); |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| waitOnAllHandlers(getInstrumentation()); |
| assertConnectionState(connection, Connection.STATE_DISCONNECTED); |
| // Make sure that the dummy app never saw the call |
| assertEquals(0, controlInterface.getHistoricalCallCount()); |
| |
| tearDownControl(); |
| } finally { |
| InstrumentationRegistry.getInstrumentation().getUiAutomation() |
| .dropShellPermissionIdentity(); |
| } |
| } |
| |
| private Connection placeActiveOutgoingCall() { |
| placeAndVerifyCall(); |
| |
| Call call = mInCallCallbacks.getService().getLastCall(); |
| assertCallState(call, Call.STATE_DIALING); |
| |
| final MockConnection connection = verifyConnectionForOutgoingCall(); |
| connection.setActive(); |
| assertCallState(call, Call.STATE_ACTIVE); |
| return connection; |
| } |
| |
| private void verifySimulateRingAndUserPickup(Call call, Connection connection) { |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| |
| call.exitBackgroundAudioProcessing(true); |
| assertCallState(call, Call.STATE_SIMULATED_RINGING); |
| waitOnAllHandlers(getInstrumentation()); |
| // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| |
| call.answer(VideoProfile.STATE_AUDIO_ONLY); |
| assertCallState(call, Call.STATE_ACTIVE); |
| waitOnAllHandlers(getInstrumentation()); |
| assertAudioMode(audioManager, AudioManager.MODE_IN_CALL); |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| } |
| |
| private void verifySimulateRingAndUserMissed(Call call, Connection connection) { |
| AudioManager audioManager = mContext.getSystemService(AudioManager.class); |
| |
| call.exitBackgroundAudioProcessing(true); |
| assertCallState(call, Call.STATE_SIMULATED_RINGING); |
| waitOnAllHandlers(getInstrumentation()); |
| // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing. |
| if (doesAudioManagerSupportCallScreening) { |
| assertAudioMode(audioManager, MODE_CALL_SCREENING); |
| } |
| assertConnectionState(connection, Connection.STATE_ACTIVE); |
| assertTrue(mTelecomManager.isRinging()); |
| |
| call.disconnect(); |
| assertCallState(call, Call.STATE_DISCONNECTED); |
| assertConnectionState(connection, Connection.STATE_DISCONNECTED); |
| assertEquals(DisconnectCause.MISSED, call.getDetails().getDisconnectCause().getCode()); |
| } |
| |
| private void setupIncomingCallWithCallScreening() throws Exception { |
| CallScreeningServiceCallbacks callback = new CallScreeningServiceCallbacks() { |
| @Override |
| public void onScreenCall(Details callDetails) { |
| getService().respondToCall(callDetails, new CallResponse.Builder() |
| .setDisallowCall(false) |
| .setShouldScreenCallViaAudioProcessing(true) |
| .build()); |
| lock.release(); |
| } |
| }; |
| MockCallScreeningService.enableService(mContext); |
| MockCallScreeningService.setCallbacks(callback); |
| Bundle extras = new Bundle(); |
| extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, createTestNumber()); |
| mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras); |
| |
| if (!callback.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("Call screening service never got the call"); |
| } |
| |
| } |
| |
| private ICtsApi29InCallServiceControl setUpControl() throws Exception { |
| Pair<ServiceConnection, ICtsApi29InCallServiceControl> setupResult = |
| Api29InCallUtils.setupControl(mContext); |
| mApiCompatControlServiceConnection = setupResult.first; |
| return setupResult.second; |
| } |
| |
| private void tearDownControl() throws Exception { |
| Api29InCallUtils.tearDownControl(mContext, |
| mApiCompatControlServiceConnection); |
| } |
| } |