| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.telephony.ims.cts; |
| |
| import static junit.framework.Assert.assertNotNull; |
| import static junit.framework.Assert.assertTrue; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.fail; |
| |
| import android.annotation.NonNull; |
| import android.app.UiAutomation; |
| import android.content.Context; |
| import android.media.AudioManager; |
| import android.net.Uri; |
| import android.os.Bundle; |
| import android.telecom.Call; |
| import android.telecom.PhoneAccount; |
| import android.telecom.TelecomManager; |
| import android.telephony.AccessNetworkConstants; |
| import android.telephony.SubscriptionManager; |
| import android.telephony.TelephonyCallback; |
| import android.telephony.TelephonyManager; |
| import android.telephony.cts.InCallServiceStateValidator; |
| import android.telephony.ims.ImsCallSessionListener; |
| import android.telephony.ims.MediaQualityStatus; |
| import android.telephony.ims.feature.MmTelFeature; |
| import android.util.Log; |
| |
| import androidx.test.ext.junit.runners.AndroidJUnit4; |
| import androidx.test.platform.app.InstrumentationRegistry; |
| |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Objects; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.LinkedBlockingQueue; |
| import java.util.concurrent.TimeUnit; |
| |
| /** |
| * CTS tests for ImsCall . |
| */ |
| @RunWith(AndroidJUnit4.class) |
| public class ImsCallingTest extends ImsCallingBase { |
| |
| protected static final String LOG_TAG = "CtsImsCallingTest"; |
| |
| private Call mCall1 = null; |
| private Call mCall2 = null; |
| private Call mCall3 = null; |
| private Call mConferenceCall = null; |
| private TestImsCallSessionImpl mCallSession1 = null; |
| private TestImsCallSessionImpl mCallSession2 = null; |
| private TestImsCallSessionImpl mCallSession3 = null; |
| private TestImsCallSessionImpl mConfCallSession = null; |
| |
| // the timeout to wait result in milliseconds |
| private static final int WAIT_UPDATE_TIMEOUT_MS = 2000; |
| |
| static { |
| initializeLatches(); |
| } |
| |
| @BeforeClass |
| public static void beforeAllTests() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| TelephonyManager tm = (TelephonyManager) getContext() |
| .getSystemService(Context.TELEPHONY_SERVICE); |
| sTestSub = ImsUtils.getPreferredActiveSubId(); |
| sTestSlot = SubscriptionManager.getSlotIndex(sTestSub); |
| if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) { |
| return; |
| } |
| |
| beforeAllTestsBase(); |
| } |
| |
| @AfterClass |
| public static void afterAllTests() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| afterAllTestsBase(); |
| } |
| |
| @Before |
| public void beforeTest() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| TelephonyManager tm = (TelephonyManager) InstrumentationRegistry.getInstrumentation() |
| .getContext().getSystemService(Context.TELEPHONY_SERVICE); |
| if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) { |
| fail("This test requires that there is a SIM in the device!"); |
| } |
| // Correctness check: ensure that the subscription hasn't changed between tests. |
| int subId = SubscriptionManager.getSubscriptionId(sTestSlot); |
| if (subId != sTestSub) { |
| fail("The found subId " + subId + " does not match the test sub id " + sTestSub); |
| } |
| } |
| |
| @After |
| public void afterTest() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| resetCallSessionObjects(); |
| |
| if (!mCalls.isEmpty() && (mCurrentCallId != null)) { |
| Call call = mCalls.get(mCurrentCallId); |
| call.disconnect(); |
| } |
| |
| //Set the untracked CountDownLatches which are reseted in ServiceCallBack |
| for (int i = 0; i < LATCH_MAX; i++) { |
| sLatches[i] = new CountDownLatch(1); |
| } |
| |
| if (sServiceConnector != null && sIsBound) { |
| TestImsService imsService = sServiceConnector.getCarrierService(); |
| sServiceConnector.disconnectCarrierImsService(); |
| sIsBound = false; |
| imsService.waitForExecutorFinish(); |
| } |
| } |
| |
| @Test |
| public void testOutGoingCall() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingCallStartFailed() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return true; |
| } |
| |
| @Override |
| public Object actual() { |
| TestMmTelFeature mmtelfeatue = sServiceConnector.getCarrierService() |
| .getMmTelFeature(); |
| return (mmtelfeatue.isCallSessionCreated()) ? true : false; |
| } |
| }, WAIT_FOR_CONDITION, "CallSession Created"); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| assertNotNull("Unable to get callSession, its null", callSession); |
| callSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_MO_FAILED); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testIncomingCall() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| Bundle extras = new Bundle(); |
| sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| if (call.getDetails().getState() == Call.STATE_RINGING) { |
| call.answer(0); |
| } |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| callSession.terminateIncomingCall(); |
| |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testIncomingCallReturnListener() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| Bundle extras = new Bundle(); |
| ImsCallSessionListener isl = sServiceConnector.getCarrierService().getMmTelFeature() |
| .onIncomingCallReceivedReturnListener(extras); |
| assertTrue("failed to get ImsCallSessionListener..", Objects.nonNull(isl)); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| if (call.getDetails().getState() == Call.STATE_RINGING) { |
| call.answer(0); |
| } |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| callSession.terminateIncomingCall(); |
| |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testIncomingCallReject() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| Bundle extras = new Bundle(); |
| sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| if (call.getDetails().getState() == Call.STATE_RINGING) { |
| call.reject(504); |
| } |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingCallForExecutor() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| sServiceConnector.setExecutorTestType(true); |
| bindImsService(); |
| |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingCallHoldResume() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| |
| // Put on hold |
| call.hold(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| // Put on resume |
| call.unhold(); |
| isCallActive(call, callSession); |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingCallHoldFailure() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| callSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_HOLD_FAILED); |
| |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| call.hold(); |
| assertTrue("call is not in Active State", (call.getDetails().getState() |
| == call.STATE_ACTIVE)); |
| |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| |
| @Test |
| public void testOutGoingCallResumeFailure() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| |
| // Put on hold |
| call.hold(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| |
| callSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_RESUME_FAILED); |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| call.unhold(); |
| assertTrue("Call is not in Hold State", (call.getDetails().getState() |
| == call.STATE_HOLDING)); |
| |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingCallReceivedHoldResume() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| isCallActive(call, callSession); |
| |
| // received hold and checking it is still active and received the connection event |
| // EVENT_CALL_REMOTELY_HELD |
| callSession.sendHoldReceived(); |
| assertTrue("Call is not in Active State", (call.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOTELY_HELD, WAIT_FOR_CALL_STATE)); |
| |
| // received resume and checking it is still active and received the connection event |
| // EVENT_CALL_REMOTELY_UNHELD |
| callSession.sendResumeReceived(); |
| assertTrue("Call is not in Active State", (call.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| assertTrue( |
| callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOTELY_UNHELD, WAIT_FOR_CALL_STATE)); |
| |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingIncomingMultiCall() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call moCall = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl moCallSession = sServiceConnector.getCarrierService() |
| .getMmTelFeature().getImsCallsession(); |
| isCallActive(moCall, moCallSession); |
| assertTrue("Call is not in Active State", (moCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| extras.putBoolean("android.telephony.ims.feature.extra.IS_USSD", false); |
| extras.putBoolean("android.telephony.ims.feature.extra.IS_UNKNOWN_CALL", false); |
| extras.putString("android:imsCallID", String.valueOf(++sCounter)); |
| extras.putLong("android:phone_id", 123456); |
| sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call mtCall = null; |
| if (mCurrentCallId != null) { |
| mtCall = getCall(mCurrentCallId); |
| if (mtCall.getDetails().getState() == Call.STATE_RINGING) { |
| mtCall.answer(0); |
| } |
| } |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| TestImsCallSessionImpl mtCallSession = sServiceConnector.getCarrierService() |
| .getMmTelFeature().getImsCallsession(); |
| isCallActive(mtCall, mtCallSession); |
| assertTrue("Call is not in Active State", (mtCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| mtCall.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mtCall, mtCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| isCallActive(moCall, moCallSession); |
| assertTrue("Call is not in Active State", (moCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| moCall.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(moCall, moCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingIncomingMultiCallAcceptTerminate() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call moCall = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl moCallSession = sServiceConnector.getCarrierService() |
| .getMmTelFeature().getImsCallsession(); |
| isCallActive(moCall, moCallSession); |
| assertTrue("Call is not in Active State", (moCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| extras.putBoolean("android.telephony.ims.feature.extra.IS_USSD", false); |
| extras.putBoolean("android.telephony.ims.feature.extra.IS_UNKNOWN_CALL", false); |
| extras.putString("android:imsCallID", String.valueOf(++sCounter)); |
| extras.putLong("android:phone_id", 123456); |
| sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| TestImsCallSessionImpl mtCallSession = sServiceConnector.getCarrierService() |
| .getMmTelFeature().getImsCallsession(); |
| // do not generate an auto hold response here, need to simulate a timing issue. |
| moCallSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_HOLD_NO_RESPONSE); |
| |
| Call mtCall = null; |
| if (mCurrentCallId != null) { |
| mtCall = getCall(mCurrentCallId); |
| if (mtCall.getDetails().getState() == Call.STATE_RINGING) { |
| mtCall.answer(0); |
| } |
| } |
| |
| // simulate user hanging up the MT call at the same time as accept. |
| mtCallSession.terminateIncomingCall(); |
| isCallDisconnected(mtCall, mtCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| // then send hold response, which should be reversed, since MT call was disconnected. |
| moCallSession.sendHoldResponse(); |
| |
| // MO call should move back to active. |
| isCallActive(moCall, moCallSession); |
| assertTrue("Call is not in Active State", (moCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| moCall.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(moCall, moCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingIncomingMultiCallHoldFailedTerminateByRemote() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call moCall = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl moCallSession = sServiceConnector.getCarrierService() |
| .getMmTelFeature().getImsCallsession(); |
| isCallActive(moCall, moCallSession); |
| assertTrue("Call is not in Active State", (moCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| TestImsCallSessionImpl mtCallSession = sServiceConnector.getCarrierService() |
| .getMmTelFeature().getImsCallsession(); |
| moCallSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_HOLD_NO_RESPONSE); |
| |
| Call mtCall = null; |
| if (mCurrentCallId != null) { |
| mtCall = getCall(mCurrentCallId); |
| if (mtCall.getDetails().getState() == Call.STATE_RINGING) { |
| mtCall.answer(0); |
| } |
| } |
| |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| // received holdFailed because the other party of the outgoing call terminated the call |
| moCallSession.sendHoldFailRemoteTerminated(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(moCall, moCallSession); |
| |
| // incoming call accept again |
| mtCall.answer(0); |
| isCallActive(mtCall, mtCallSession); |
| assertTrue("Call is not in Active State", (mtCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| mtCall.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mtCall, mtCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingCallSwap() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| addOutgoingCalls(); |
| |
| // Swap the call |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| mCall1.unhold(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| assertTrue("Call is not in Hold State", (mCall2.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| isCallActive(mCall1, mCallSession1); |
| |
| // After successful call swap disconnect the call |
| mCall1.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall1, mCallSession1); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| //Wait till second call is in active state |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return true; |
| } |
| |
| @Override |
| public Object actual() { |
| return (mCall2.getDetails().getState() == Call.STATE_ACTIVE) |
| ? true : false; |
| } |
| }, WAIT_FOR_CALL_STATE_ACTIVE, "Call in Active State"); |
| |
| isCallActive(mCall2, mCallSession2); |
| mCall2.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall2, mCallSession2); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testOutGoingCallSwapFail() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| addOutgoingCalls(); |
| |
| mCallSession1.addTestType(TestImsCallSessionImpl.TEST_TYPE_RESUME_FAILED); |
| // Swap the call |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| mCall1.unhold(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| assertTrue("Call is not in Hold State", (mCall1.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| |
| // Wait till second call is in active state |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return true; |
| } |
| |
| @Override |
| public Object actual() { |
| return (mCall2.getDetails().getState() == Call.STATE_ACTIVE) |
| ? true : false; |
| } |
| }, WAIT_FOR_CALL_STATE_ACTIVE, "Call in Active State"); |
| |
| isCallActive(mCall2, mCallSession2); |
| mCallSession1.removeTestType(TestImsCallSessionImpl.TEST_TYPE_RESUME_FAILED); |
| mCall2.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall2, mCallSession2); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| // Wait till second call is in active state |
| isCallActive(mCall1, mCallSession1); |
| mCall1.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall1, mCallSession1); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testConferenceCall() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| Log.i(LOG_TAG, "testConference "); |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| makeConferenceCall(); |
| |
| //Disconnect the conference call. |
| mConferenceCall.disconnect(); |
| |
| //Verify conference participant connections are disconnected. |
| assertParticiapantAddedToConference(0); |
| isCallDisconnected(mConferenceCall, mConfCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testConferenceCallFailure() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| Log.i(LOG_TAG, "testConferenceCallFailure "); |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| addOutgoingCalls(); |
| mCallSession2.addTestType(TestImsCallSessionImpl.TEST_TYPE_CONFERENCE_FAILED); |
| addConferenceCall(mCall1, mCall2); |
| |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| //Verify foreground call is in Active state after merge failed. |
| assertTrue("Call is not in Active State", (mCall2.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| //Verify background call is in Hold state after merge failed. |
| assertTrue("Call is not in Holding State", (mCall1.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| |
| mCall2.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall2, mCallSession2); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| //Wait till background call is in active state |
| isCallActive(mCall1, mCallSession1); |
| mCall1.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall1, mCallSession1); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testConferenceCallFailureByRemoteTerminated() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| addOutgoingCalls(); |
| mCallSession2.addTestType( |
| TestImsCallSessionImpl.TEST_TYPE_CONFERENCE_FAILED_REMOTE_TERMINATED); |
| addConferenceCall(mCall1, mCall2); |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| |
| // first call is terminated by remote |
| mCallSession1.sendTerminatedByRemote(); |
| // received mergeFailed due to terminated first call |
| mCallSession2.sendMergedFailed(); |
| |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| // verify foreground call is in Active state after merge failed. |
| assertTrue("Call is not in Active State", (mCall2.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| // verify background call is in Disconnected state. |
| isCallDisconnected(mCall1, mCallSession1); |
| assertTrue("Call is not in Disconnected State", (mCall1.getDetails().getState() |
| == Call.STATE_DISCONNECTED)); |
| |
| mCall2.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall2, mCallSession2); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testCallJoinExistingConferenceCall() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| makeConferenceCall(); |
| // add third outgoing call, third call : active , conference call : hold |
| addThirdOutgoingCall(); |
| mCallSession3.addTestType(TestImsCallSessionImpl.TEST_TYPE_JOIN_EXIST_CONFERENCE); |
| |
| mCall3.conference(mConferenceCall); |
| isCallActive(mConferenceCall, mConfCallSession); |
| |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| // verify third call disconnected after conference Merge success |
| assertParticiapantDisconnected(mCall3); |
| |
| // verify conference participant connections are connected. |
| assertParticiapantAddedToConference(3); |
| |
| mConferenceCall.disconnect(); |
| |
| assertParticiapantAddedToConference(0); |
| isCallDisconnected(mConferenceCall, mConfCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testCallJoinExistingConferenceCallAfterCallSwap() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| makeConferenceCall(); |
| // add third outgoing call, third call : active , conference call : hold |
| addThirdOutgoingCall(); |
| |
| // swap the call |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| mConferenceCall.unhold(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| assertTrue("Call is not in Hold State", (mCall3.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| isCallActive(mConferenceCall, mConfCallSession); |
| |
| mConfCallSession.addTestType( |
| TestImsCallSessionImpl.TEST_TYPE_JOIN_EXIST_CONFERENCE_AFTER_SWAP); |
| |
| // merge call |
| mConferenceCall.conference(mCall3); |
| isCallActive(mConferenceCall, mConfCallSession); |
| |
| // verify third call disconnected after conference Merge success |
| assertParticiapantDisconnected(mCall3); |
| |
| // verify conference participant connections are connected. |
| assertParticiapantAddedToConference(3); |
| |
| // disconnect the conference call. |
| mConferenceCall.disconnect(); |
| |
| // verify conference participant connections are disconnected. |
| assertParticiapantAddedToConference(0); |
| isCallDisconnected(mConferenceCall, mConfCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testCallJoinExistingConferenceCallAfterCallSwapFail() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| makeConferenceCall(); |
| // add third outgoing call, third call : active , conference call : hold |
| addThirdOutgoingCall(); |
| |
| // swap the call |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| mConferenceCall.unhold(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| assertTrue("Call is not in Hold State", (mCall3.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| isCallActive(mConferenceCall, mConfCallSession); |
| |
| // fail to merge |
| mConfCallSession.addTestType( |
| TestImsCallSessionImpl.TEST_TYPE_JOIN_EXIST_CONFERENCE_FAILED_AFTER_SWAP); |
| |
| mConferenceCall.conference(mCall3); |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| |
| // verify foreground call is in Active state after merge failed. |
| assertTrue("Call is not in Active State", (mConferenceCall.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| // verify background call is in Hold state after merge failed. |
| assertTrue("Call is not in Holding State", (mCall3.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| |
| // disconnect the conference call. |
| mConferenceCall.disconnect(); |
| |
| // verify conference participant connections are disconnected. |
| assertParticiapantAddedToConference(0); |
| isCallDisconnected(mConferenceCall, mConfCallSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| |
| // verify third call is active |
| isCallActive(mCall3, mCallSession3); |
| mCall3.disconnect(); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(mCall3, mCallSession3); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testSetCallAudioHandler() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| AudioManager mAudioManager = (AudioManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.AUDIO_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| |
| sServiceConnector.getCarrierService().getMmTelFeature() |
| .setCallAudioHandler(MmTelFeature.AUDIO_HANDLER_ANDROID); |
| sServiceConnector.getCarrierService().getMmTelFeature() |
| .getTerminalBasedCallWaitingLatch().await(WAIT_UPDATE_TIMEOUT_MS, |
| TimeUnit.MILLISECONDS); |
| assertEquals(AudioManager.MODE_IN_COMMUNICATION, mAudioManager.getMode()); |
| |
| sServiceConnector.getCarrierService().getMmTelFeature() |
| .setCallAudioHandler(MmTelFeature.AUDIO_HANDLER_BASEBAND); |
| sServiceConnector.getCarrierService().getMmTelFeature() |
| .getTerminalBasedCallWaitingLatch().await(WAIT_UPDATE_TIMEOUT_MS, |
| TimeUnit.MILLISECONDS); |
| assertEquals(AudioManager.MODE_IN_CALL, mAudioManager.getMode()); |
| |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| @Test |
| public void testNotifyMediaCallStatusChanged() throws Exception { |
| if (!ImsUtils.shouldTestImsService()) { |
| return; |
| } |
| |
| bindImsService(); |
| mServiceCallBack = new ServiceCallBack(); |
| InCallServiceStateValidator.setCallbacks(mServiceCallBack); |
| |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null); |
| Bundle extras = new Bundle(); |
| |
| // Place outgoing call |
| telecomManager.placeCall(imsUri, extras); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| Call call = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| |
| TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getImsCallsession(); |
| |
| isCallActive(call, callSession); |
| String callSessionId = callSession.getCallId(); |
| |
| LinkedBlockingQueue<MediaQualityStatus> queue = new LinkedBlockingQueue<>(); |
| ImsCallingTest.TestTelephonyCallback testCb = |
| new ImsCallingTest.TestTelephonyCallback(queue); |
| TelephonyManager telephonyManager = getContext().getSystemService(TelephonyManager.class); |
| |
| //test registration without permission |
| try { |
| telephonyManager.registerTelephonyCallback(getContext().getMainExecutor(), testCb); |
| fail("registerTelephonyCallback requires READ_PRECISE_PHONE_STATE permission."); |
| } catch (SecurityException e) { |
| //expected |
| } |
| |
| final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation(); |
| try { |
| automan.adoptShellPermissionIdentity(); |
| telephonyManager.registerTelephonyCallback(getContext().getMainExecutor(), testCb); |
| } finally { |
| automan.dropShellPermissionIdentity(); |
| } |
| |
| //Expect to receive cached media quality status retrieved by #queryMediaQualityStatus. |
| MediaQualityStatus status = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); |
| assertNotNull(status); |
| assertEquals(callSessionId, status.getCallSessionId()); |
| assertEquals(MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO, status.getMediaSessionType()); |
| assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, status.getTransportType()); |
| assertEquals(0, status.getRtpPacketLossRate()); |
| assertEquals(0, status.getRtpJitterMillis()); |
| assertEquals(0, status.getRtpInactivityMillis()); |
| |
| //Notify a new media quality status. |
| sServiceConnector.getCarrierService().getMmTelFeature() |
| .notifyMediaQualityStatusChanged(new MediaQualityStatus |
| .Builder(callSessionId, |
| MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO, |
| AccessNetworkConstants.TRANSPORT_TYPE_WWAN) |
| .setRtpPacketLossRate(TEST_RTP_THRESHOLD_PACKET_LOSS_RATE) |
| .setRtpJitterMillis(TEST_RTP_THRESHOLD_JITTER_MILLIS) |
| .setRtpInactivityMillis(TEST_RTP_THRESHOLD_INACTIVITY_TIME_MILLIS).build()); |
| |
| status = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); |
| assertNotNull(status); |
| assertEquals(callSessionId, status.getCallSessionId()); |
| assertEquals(MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO, status.getMediaSessionType()); |
| assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, status.getTransportType()); |
| assertEquals(TEST_RTP_THRESHOLD_PACKET_LOSS_RATE, status.getRtpPacketLossRate()); |
| assertEquals(TEST_RTP_THRESHOLD_JITTER_MILLIS, status.getRtpJitterMillis()); |
| assertEquals(TEST_RTP_THRESHOLD_INACTIVITY_TIME_MILLIS, status.getRtpInactivityMillis()); |
| |
| call.disconnect(); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE)); |
| isCallDisconnected(call, callSession); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE)); |
| waitForUnboundService(); |
| } |
| |
| private class TestTelephonyCallback extends TelephonyCallback |
| implements TelephonyCallback.MediaQualityStatusChangedListener { |
| LinkedBlockingQueue<MediaQualityStatus> mTestMediaQualityStatusQueue; |
| TestTelephonyCallback(LinkedBlockingQueue<MediaQualityStatus> queue) { |
| mTestMediaQualityStatusQueue = queue; |
| } |
| @Override |
| public void onMediaQualityStatusChanged(@NonNull MediaQualityStatus status) { |
| mTestMediaQualityStatusQueue.offer(status); |
| } |
| } |
| |
| void addConferenceCall(Call call1, Call call2) { |
| InCallServiceStateValidator inCallService = mServiceCallBack.getService(); |
| |
| // Verify that the calls have each other on their conferenceable list before proceeding |
| List<Call> callConfList = new ArrayList<>(); |
| callConfList.add(call2); |
| assertCallConferenceableList(call1, callConfList); |
| |
| callConfList.clear(); |
| callConfList.add(call1); |
| assertCallConferenceableList(call2, callConfList); |
| |
| call2.conference(call1); |
| } |
| |
| void assertCallConferenceableList(final Call call, final List<Call> conferenceableList) { |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return conferenceableList; |
| } |
| |
| @Override |
| public Object actual() { |
| return call.getConferenceableCalls(); |
| } |
| }, WAIT_FOR_CONDITION, |
| "Call: " + call + " does not have the correct conferenceable call list." |
| ); |
| } |
| |
| private void assertParticiapantDisconnected(Call call) { |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return true; |
| } |
| |
| @Override |
| public Object actual() { |
| return ((call.getState() == Call.STATE_DISCONNECTED)) ? true : false; |
| } |
| }, WAIT_FOR_CONDITION, "Call Disconnected"); |
| } |
| |
| private void assertParticiapantAddedToConference(int count) { |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return true; |
| } |
| |
| @Override |
| public Object actual() { |
| return (mParticipantCount == count) ? true : false; |
| } |
| }, WAIT_FOR_CONDITION, "Call Added"); |
| } |
| |
| private void addOutgoingCalls() throws Exception { |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| |
| // Place first outgoing call |
| final Uri imsUri1 = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), |
| null); |
| Bundle extras1 = new Bundle(); |
| |
| telecomManager.placeCall(imsUri1, extras1); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| mCall1 = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| mCallSession1 = sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession(); |
| isCallActive(mCall1, mCallSession1); |
| assertTrue("Call is not in Active State", (mCall1.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| |
| // Place second outgoing call |
| final Uri imsUri2 = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), |
| null); |
| Bundle extras2 = new Bundle(); |
| |
| telecomManager.placeCall(imsUri2, extras2); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| |
| mCall2 = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| assertTrue("Call is not in Hold State", (mCall1.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| |
| //Wait till the object of TestImsCallSessionImpl for second call created. |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return true; |
| } |
| |
| @Override |
| public Object actual() { |
| TestMmTelFeature mmtelfeatue = sServiceConnector.getCarrierService() |
| .getMmTelFeature(); |
| return (mmtelfeatue.getImsCallsession() != mCallSession1) ? true : false; |
| } |
| }, WAIT_FOR_CONDITION, "CallSession Created"); |
| |
| mCallSession2 = sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession(); |
| isCallActive(mCall2, mCallSession2); |
| assertTrue("Call is not in Active State", (mCall2.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| } |
| |
| private void addThirdOutgoingCall() { |
| // add a third outgoing call when a conference call already exists. |
| TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry |
| .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE); |
| final Uri imsUri3 = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), |
| null); |
| Bundle extras3 = new Bundle(); |
| |
| telecomManager.placeCall(imsUri3, extras3); |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE); |
| |
| mCall3 = getCall(mCurrentCallId); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE)); |
| assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE)); |
| assertTrue("Call is not in Hold State", (mConferenceCall.getDetails().getState() |
| == Call.STATE_HOLDING)); |
| |
| waitNewCallCreated(mCallSession2); |
| mCallSession3 = |
| sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession(); |
| |
| isCallActive(mCall3, mCallSession3); |
| assertTrue("Call is not in Active State", (mCall3.getDetails().getState() |
| == Call.STATE_ACTIVE)); |
| } |
| |
| private void waitNewCallCreated(TestImsCallSessionImpl previousCallSession) { |
| waitUntilConditionIsTrueOrTimeout( |
| new Condition() { |
| @Override |
| public Object expected() { |
| return true; |
| } |
| |
| @Override |
| public Object actual() { |
| TestMmTelFeature mmtelfeatue = sServiceConnector.getCarrierService() |
| .getMmTelFeature(); |
| return (mmtelfeatue.getImsCallsession() != previousCallSession) ? true |
| : false; |
| } |
| }, WAIT_FOR_CONDITION, "CallSession Created"); |
| } |
| |
| private void makeConferenceCall() throws Exception { |
| addOutgoingCalls(); |
| addConferenceCall(mCall1, mCall2); |
| |
| assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE)); |
| // Wait to add participants in conference |
| ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE); |
| assertTrue("Conference call is not added", mServiceCallBack.getService() |
| .getConferenceCallCount() > 0); |
| |
| mConferenceCall = mServiceCallBack.getService().getLastConferenceCall(); |
| assertNotNull("Unable to add conference call, its null", mConferenceCall); |
| |
| ConferenceHelper confHelper = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getConferenceHelper(); |
| |
| mConfCallSession = confHelper.getConferenceSession(); |
| isCallActive(mConferenceCall, mConfCallSession); |
| assertTrue("Conference call is not Active", mConfCallSession.isInCall()); |
| |
| //Verify mCall1 and mCall2 disconnected after conference Merge success |
| assertParticiapantDisconnected(mCall1); |
| assertParticiapantDisconnected(mCall2); |
| |
| //Verify conference participant connections are connected. |
| assertParticiapantAddedToConference(2); |
| |
| // Since the conference call has been made, remove session1&2 from the confHelper session. |
| confHelper.removeSession(mCallSession1); |
| confHelper.removeSession(mCallSession2); |
| } |
| |
| private void resetCallSessionObjects() { |
| mCall1 = mCall2 = mCall3 = mConferenceCall = null; |
| mCallSession1 = mCallSession2 = mCallSession3 = mConfCallSession = null; |
| ConferenceHelper confHelper = sServiceConnector.getCarrierService().getMmTelFeature() |
| .getConferenceHelper(); |
| if (confHelper != null) { |
| confHelper.clearSessions(); |
| } |
| } |
| } |