175ba09a17a669f4906268088a769836aa87d8241fionaxu/*
275ba09a17a669f4906268088a769836aa87d8241fionaxu * Copyright (C) 2016 The Android Open Source Project
375ba09a17a669f4906268088a769836aa87d8241fionaxu *
475ba09a17a669f4906268088a769836aa87d8241fionaxu * Licensed under the Apache License, Version 2.0 (the "License");
575ba09a17a669f4906268088a769836aa87d8241fionaxu * you may not use this file except in compliance with the License.
675ba09a17a669f4906268088a769836aa87d8241fionaxu * You may obtain a copy of the License at
775ba09a17a669f4906268088a769836aa87d8241fionaxu *
875ba09a17a669f4906268088a769836aa87d8241fionaxu *      http://www.apache.org/licenses/LICENSE-2.0
975ba09a17a669f4906268088a769836aa87d8241fionaxu *
1075ba09a17a669f4906268088a769836aa87d8241fionaxu * Unless required by applicable law or agreed to in writing, software
1175ba09a17a669f4906268088a769836aa87d8241fionaxu * distributed under the License is distributed on an "AS IS" BASIS,
1275ba09a17a669f4906268088a769836aa87d8241fionaxu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375ba09a17a669f4906268088a769836aa87d8241fionaxu * See the License for the specific language governing permissions and
1475ba09a17a669f4906268088a769836aa87d8241fionaxu * limitations under the License.
1575ba09a17a669f4906268088a769836aa87d8241fionaxu */
16ecac744a4e585e3c7af95ffa06fa3e711131200cAmit Mahajanpackage com.android.internal.telephony.imsphone;
1775ba09a17a669f4906268088a769836aa87d8241fionaxu
18ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
19ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yu
20ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.junit.Assert.assertEquals;
21ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.junit.Assert.assertFalse;
22ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.junit.Assert.assertTrue;
23ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.ArgumentMatchers.nullable;
24ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.any;
25ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.anyBoolean;
26ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.anyInt;
27ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.doAnswer;
28b03dbaac0051b2d6c9daee438781c26bf4123fdeBrad Ebingerimport static org.mockito.Mockito.doNothing;
29ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.doReturn;
30ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.doThrow;
31ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.eq;
32ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.isNull;
3302761d2406c0197cebd255b575f161f5145efbb3Tyler Gunnimport static org.mockito.Mockito.mock;
34ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.never;
35ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.spy;
36ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.times;
37ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport static org.mockito.Mockito.verify;
38ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yu
39ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebingerimport android.content.Context;
40d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunnimport android.content.SharedPreferences;
41ecac744a4e585e3c7af95ffa06fa3e711131200cAmit Mahajanimport android.os.Bundle;
42ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebingerimport android.os.Handler;
4375ba09a17a669f4906268088a769836aa87d8241fionaxuimport android.os.HandlerThread;
44e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxuimport android.os.Message;
4502761d2406c0197cebd255b575f161f5145efbb3Tyler Gunnimport android.os.PersistableBundle;
46516010d13181808ca8205316a419b615e5a9fe5eShuoqimport android.support.test.filters.FlakyTest;
47d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunnimport android.telecom.VideoProfile;
4802761d2406c0197cebd255b575f161f5145efbb3Tyler Gunnimport android.telephony.CarrierConfigManager;
49745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunnimport android.telephony.DisconnectCause;
50e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxuimport android.telephony.PhoneNumberUtils;
5102761d2406c0197cebd255b575f161f5145efbb3Tyler Gunnimport android.telephony.ServiceState;
5202761d2406c0197cebd255b575f161f5145efbb3Tyler Gunnimport android.telephony.TelephonyManager;
5309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebingerimport android.telephony.ims.ImsCallProfile;
5409f5b9723639968e85e2452f328b2517ffbc749cBrad Ebingerimport android.telephony.ims.ImsCallSession;
5509f5b9723639968e85e2452f328b2517ffbc749cBrad Ebingerimport android.telephony.ims.ImsReasonInfo;
5609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebingerimport android.telephony.ims.ImsStreamMediaProfile;
57fda28316b04100d2aadc81ae836f9f10c3226f0cBrad Ebingerimport android.telephony.ims.feature.ImsFeature;
581d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebingerimport android.telephony.ims.feature.MmTelFeature;
591d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebingerimport android.telephony.ims.stub.ImsRegistrationImplBase;
6075ba09a17a669f4906268088a769836aa87d8241fionaxuimport android.test.suitebuilder.annotation.SmallTest;
6175ba09a17a669f4906268088a769836aa87d8241fionaxu
6275ba09a17a669f4906268088a769836aa87d8241fionaxuimport com.android.ims.ImsCall;
6375ba09a17a669f4906268088a769836aa87d8241fionaxuimport com.android.ims.ImsConfig;
64ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebingerimport com.android.ims.ImsException;
651d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebingerimport com.android.ims.internal.IImsCallSession;
66ecac744a4e585e3c7af95ffa06fa3e711131200cAmit Mahajanimport com.android.internal.telephony.Call;
67d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunnimport com.android.internal.telephony.CallStateException;
68d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunnimport com.android.internal.telephony.CommandsInterface;
69ecac744a4e585e3c7af95ffa06fa3e711131200cAmit Mahajanimport com.android.internal.telephony.Connection;
70ecac744a4e585e3c7af95ffa06fa3e711131200cAmit Mahajanimport com.android.internal.telephony.PhoneConstants;
71ecac744a4e585e3c7af95ffa06fa3e711131200cAmit Mahajanimport com.android.internal.telephony.TelephonyTest;
72ecac744a4e585e3c7af95ffa06fa3e711131200cAmit Mahajan
7375ba09a17a669f4906268088a769836aa87d8241fionaxuimport org.junit.After;
7475ba09a17a669f4906268088a769836aa87d8241fionaxuimport org.junit.Assert;
7575ba09a17a669f4906268088a769836aa87d8241fionaxuimport org.junit.Before;
76ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yuimport org.junit.Ignore;
7775ba09a17a669f4906268088a769836aa87d8241fionaxuimport org.junit.Test;
78d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunnimport org.mockito.ArgumentCaptor;
7975ba09a17a669f4906268088a769836aa87d8241fionaxuimport org.mockito.Mock;
8075ba09a17a669f4906268088a769836aa87d8241fionaxuimport org.mockito.invocation.InvocationOnMock;
8175ba09a17a669f4906268088a769836aa87d8241fionaxuimport org.mockito.stubbing.Answer;
8275ba09a17a669f4906268088a769836aa87d8241fionaxu
8375ba09a17a669f4906268088a769836aa87d8241fionaxupublic class ImsPhoneCallTrackerTest extends TelephonyTest {
8475ba09a17a669f4906268088a769836aa87d8241fionaxu    private ImsPhoneCallTracker mCTUT;
857e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan    private ImsCTHandlerThread mImsCTHandlerThread;
861d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger    private MmTelFeature.Listener mMmTelListener;
8709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    private ImsRegistrationImplBase.Callback mRegistrationCallback;
881d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger    private ImsFeature.CapabilityCallback mCapabilityCallback;
8975ba09a17a669f4906268088a769836aa87d8241fionaxu    private ImsCall.Listener mImsCallListener;
9075ba09a17a669f4906268088a769836aa87d8241fionaxu    private ImsCall mImsCall;
9175ba09a17a669f4906268088a769836aa87d8241fionaxu    private ImsCall mSecondImsCall;
9275ba09a17a669f4906268088a769836aa87d8241fionaxu    private Bundle mBundle = new Bundle();
93e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    private int mServiceId;
9475ba09a17a669f4906268088a769836aa87d8241fionaxu    @Mock
9575ba09a17a669f4906268088a769836aa87d8241fionaxu    private ImsCallSession mImsCallSession;
96d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn    @Mock
97d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn    private SharedPreferences mSharedPreferences;
9802761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    @Mock
9902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    private ImsPhoneConnection.Listener mImsPhoneConnectionListener;
1001d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger    @Mock
1011d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger    private ImsConfig mImsConfig;
102ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    private Handler mCTHander;
10375ba09a17a669f4906268088a769836aa87d8241fionaxu
10475ba09a17a669f4906268088a769836aa87d8241fionaxu    private class ImsCTHandlerThread extends HandlerThread {
10575ba09a17a669f4906268088a769836aa87d8241fionaxu
10675ba09a17a669f4906268088a769836aa87d8241fionaxu        private ImsCTHandlerThread(String name) {
10775ba09a17a669f4906268088a769836aa87d8241fionaxu            super(name);
10875ba09a17a669f4906268088a769836aa87d8241fionaxu        }
10975ba09a17a669f4906268088a769836aa87d8241fionaxu        @Override
11075ba09a17a669f4906268088a769836aa87d8241fionaxu        public void onLooperPrepared() {
11175ba09a17a669f4906268088a769836aa87d8241fionaxu            mCTUT = new ImsPhoneCallTracker(mImsPhone);
1124558536154e496ea917b343e496ed64c94250873Tyler Gunn            mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST);
1134558536154e496ea917b343e496ed64c94250873Tyler Gunn            mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.",
1144558536154e496ea917b343e496ed64c94250873Tyler Gunn                    ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
1154558536154e496ea917b343e496ed64c94250873Tyler Gunn            mCTUT.addReasonCodeRemapping(510, "Call answered elsewhere.",
1164558536154e496ea917b343e496ed64c94250873Tyler Gunn                    ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
11702761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn            mCTUT.setDataEnabled(true);
118ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger            mCTHander = new Handler(mCTUT.getLooper());
11975ba09a17a669f4906268088a769836aa87d8241fionaxu            setReady(true);
12075ba09a17a669f4906268088a769836aa87d8241fionaxu        }
12175ba09a17a669f4906268088a769836aa87d8241fionaxu    }
12275ba09a17a669f4906268088a769836aa87d8241fionaxu
12375ba09a17a669f4906268088a769836aa87d8241fionaxu    private void imsCallMocking(final ImsCall mImsCall) throws Exception {
12475ba09a17a669f4906268088a769836aa87d8241fionaxu
12575ba09a17a669f4906268088a769836aa87d8241fionaxu        doAnswer(new Answer<Void>() {
12675ba09a17a669f4906268088a769836aa87d8241fionaxu            @Override
12775ba09a17a669f4906268088a769836aa87d8241fionaxu            public Void answer(InvocationOnMock invocation) throws Throwable {
12875ba09a17a669f4906268088a769836aa87d8241fionaxu                // trigger the listener on accept call
12975ba09a17a669f4906268088a769836aa87d8241fionaxu                if (mImsCallListener != null) {
13075ba09a17a669f4906268088a769836aa87d8241fionaxu                    mImsCallListener.onCallStarted(mImsCall);
13175ba09a17a669f4906268088a769836aa87d8241fionaxu                }
13275ba09a17a669f4906268088a769836aa87d8241fionaxu                return null;
13375ba09a17a669f4906268088a769836aa87d8241fionaxu            }
13475ba09a17a669f4906268088a769836aa87d8241fionaxu        }).when(mImsCall).accept(anyInt());
13575ba09a17a669f4906268088a769836aa87d8241fionaxu
13675ba09a17a669f4906268088a769836aa87d8241fionaxu        doAnswer(new Answer<Void>() {
13775ba09a17a669f4906268088a769836aa87d8241fionaxu            @Override
13875ba09a17a669f4906268088a769836aa87d8241fionaxu            public Void answer(InvocationOnMock invocation) throws Throwable {
13975ba09a17a669f4906268088a769836aa87d8241fionaxu                // trigger the listener on reject call
14075ba09a17a669f4906268088a769836aa87d8241fionaxu                int reasonCode = (int) invocation.getArguments()[0];
14175ba09a17a669f4906268088a769836aa87d8241fionaxu                if (mImsCallListener != null) {
14275ba09a17a669f4906268088a769836aa87d8241fionaxu                    mImsCallListener.onCallStartFailed(mImsCall, new ImsReasonInfo(reasonCode, -1));
14375ba09a17a669f4906268088a769836aa87d8241fionaxu                    mImsCallListener.onCallTerminated(mImsCall, new ImsReasonInfo(reasonCode, -1));
14475ba09a17a669f4906268088a769836aa87d8241fionaxu                }
14575ba09a17a669f4906268088a769836aa87d8241fionaxu                return null;
14675ba09a17a669f4906268088a769836aa87d8241fionaxu            }
14775ba09a17a669f4906268088a769836aa87d8241fionaxu        }).when(mImsCall).reject(anyInt());
14875ba09a17a669f4906268088a769836aa87d8241fionaxu
14975ba09a17a669f4906268088a769836aa87d8241fionaxu        doAnswer(new Answer<Void>() {
15075ba09a17a669f4906268088a769836aa87d8241fionaxu            @Override
15175ba09a17a669f4906268088a769836aa87d8241fionaxu            public Void answer(InvocationOnMock invocation) throws Throwable {
15275ba09a17a669f4906268088a769836aa87d8241fionaxu                // trigger the listener on reject call
15375ba09a17a669f4906268088a769836aa87d8241fionaxu                int reasonCode = (int) invocation.getArguments()[0];
15475ba09a17a669f4906268088a769836aa87d8241fionaxu                if (mImsCallListener != null) {
15575ba09a17a669f4906268088a769836aa87d8241fionaxu                    mImsCallListener.onCallTerminated(mImsCall, new ImsReasonInfo(reasonCode, -1));
15675ba09a17a669f4906268088a769836aa87d8241fionaxu                }
15775ba09a17a669f4906268088a769836aa87d8241fionaxu                return null;
15875ba09a17a669f4906268088a769836aa87d8241fionaxu            }
15975ba09a17a669f4906268088a769836aa87d8241fionaxu        }).when(mImsCall).terminate(anyInt());
16075ba09a17a669f4906268088a769836aa87d8241fionaxu
16175ba09a17a669f4906268088a769836aa87d8241fionaxu        doAnswer(new Answer<Void>() {
16275ba09a17a669f4906268088a769836aa87d8241fionaxu            @Override
16375ba09a17a669f4906268088a769836aa87d8241fionaxu            public Void answer(InvocationOnMock invocation) throws Throwable {
16475ba09a17a669f4906268088a769836aa87d8241fionaxu                if (mImsCallListener != null) {
16575ba09a17a669f4906268088a769836aa87d8241fionaxu                    mImsCallListener.onCallHeld(mImsCall);
16675ba09a17a669f4906268088a769836aa87d8241fionaxu                }
16775ba09a17a669f4906268088a769836aa87d8241fionaxu                return null;
16875ba09a17a669f4906268088a769836aa87d8241fionaxu            }
16975ba09a17a669f4906268088a769836aa87d8241fionaxu        }).when(mImsCall).hold();
17075ba09a17a669f4906268088a769836aa87d8241fionaxu
17102761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        mImsCall.attachSession(mImsCallSession);
17275ba09a17a669f4906268088a769836aa87d8241fionaxu    }
17375ba09a17a669f4906268088a769836aa87d8241fionaxu
17475ba09a17a669f4906268088a769836aa87d8241fionaxu    @Before
17575ba09a17a669f4906268088a769836aa87d8241fionaxu    public void setUp() throws Exception {
17675ba09a17a669f4906268088a769836aa87d8241fionaxu        super.setUp(this.getClass().getSimpleName());
177e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        mServiceId = 0;
17875ba09a17a669f4906268088a769836aa87d8241fionaxu        mImsCallProfile.mCallExtras = mBundle;
17975ba09a17a669f4906268088a769836aa87d8241fionaxu        mImsManagerInstances.put(mImsPhone.getPhoneId(), mImsManager);
18075ba09a17a669f4906268088a769836aa87d8241fionaxu        mImsCall = spy(new ImsCall(mContext, mImsCallProfile));
18175ba09a17a669f4906268088a769836aa87d8241fionaxu        mSecondImsCall = spy(new ImsCall(mContext, mImsCallProfile));
18202761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        mImsPhoneConnectionListener = mock(ImsPhoneConnection.Listener.class);
18375ba09a17a669f4906268088a769836aa87d8241fionaxu        imsCallMocking(mImsCall);
18475ba09a17a669f4906268088a769836aa87d8241fionaxu        imsCallMocking(mSecondImsCall);
1851d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState();
1861d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        doReturn(mImsCallProfile).when(mImsManager).createCallProfile(anyInt(), anyInt());
1871d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger
1881d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        doAnswer(invocation -> {
1891d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            mMmTelListener = (MmTelFeature.Listener) invocation.getArguments()[0];
1901d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            return null;
1911d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        }).when(mImsManager).open(any(MmTelFeature.Listener.class));
192e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
19375ba09a17a669f4906268088a769836aa87d8241fionaxu
19475ba09a17a669f4906268088a769836aa87d8241fionaxu        doAnswer(new Answer<ImsCall>() {
19575ba09a17a669f4906268088a769836aa87d8241fionaxu            @Override
19675ba09a17a669f4906268088a769836aa87d8241fionaxu            public ImsCall answer(InvocationOnMock invocation) throws Throwable {
19775ba09a17a669f4906268088a769836aa87d8241fionaxu                mImsCallListener =
19875ba09a17a669f4906268088a769836aa87d8241fionaxu                        (ImsCall.Listener) invocation.getArguments()[2];
19902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                mImsCall.setListener(mImsCallListener);
20075ba09a17a669f4906268088a769836aa87d8241fionaxu                return mImsCall;
20175ba09a17a669f4906268088a769836aa87d8241fionaxu            }
2021d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        }).when(mImsManager).takeCall(any(), any(), any());
203e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
204e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        doAnswer(new Answer<ImsCall>() {
205e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            @Override
206e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            public ImsCall answer(InvocationOnMock invocation) throws Throwable {
207e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu                mImsCallListener =
2081d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                        (ImsCall.Listener) invocation.getArguments()[2];
20902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                mSecondImsCall.setListener(mImsCallListener);
210e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu                return mSecondImsCall;
211e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            }
2121d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        }).when(mImsManager).makeCall(eq(mImsCallProfile), (String []) any(),
213e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu                (ImsCall.Listener) any());
21475ba09a17a669f4906268088a769836aa87d8241fionaxu
2151d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        doAnswer(invocation -> {
21609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger            mRegistrationCallback = invocation.getArgument(0);
21709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger            return mRegistrationCallback;
21809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        }).when(mImsManager).addRegistrationCallback(any(ImsRegistrationImplBase.Callback.class));
21909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
22009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        doAnswer(invocation -> {
2211d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            mCapabilityCallback = (ImsFeature.CapabilityCallback) invocation.getArguments()[0];
2221d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            return mCapabilityCallback;
2231d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger
2241d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        }).when(mImsManager).addCapabilitiesCallback(any(ImsFeature.CapabilityCallback.class));
2251d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger
2261d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        doReturn(mImsConfig).when(mImsManager).getConfigInterface();
2271d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger
228b03dbaac0051b2d6c9daee438781c26bf4123fdeBrad Ebinger        doNothing().when(mImsManager).addNotifyStatusChangedCallbackIfAvailable(any());
229b03dbaac0051b2d6c9daee438781c26bf4123fdeBrad Ebinger
2307e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan        mImsCTHandlerThread = new ImsCTHandlerThread(this.getClass().getSimpleName());
2317e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan        mImsCTHandlerThread.start();
23275ba09a17a669f4906268088a769836aa87d8241fionaxu
23375ba09a17a669f4906268088a769836aa87d8241fionaxu        waitUntilReady();
23475ba09a17a669f4906268088a769836aa87d8241fionaxu        logd("ImsPhoneCallTracker initiated");
235ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        /* Make sure getImsService is triggered on handler */
236ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        waitForHandlerAction(mCTHander, 100);
23775ba09a17a669f4906268088a769836aa87d8241fionaxu    }
23875ba09a17a669f4906268088a769836aa87d8241fionaxu
23975ba09a17a669f4906268088a769836aa87d8241fionaxu    @After
24075ba09a17a669f4906268088a769836aa87d8241fionaxu    public void tearDown() throws Exception {
24175ba09a17a669f4906268088a769836aa87d8241fionaxu        mCTUT = null;
242ae6e8f99bdb297f906d6dcdc0a385ba27eee47fdJack Yu        mImsCTHandlerThread.quit();
24375ba09a17a669f4906268088a769836aa87d8241fionaxu        super.tearDown();
24475ba09a17a669f4906268088a769836aa87d8241fionaxu    }
24575ba09a17a669f4906268088a769836aa87d8241fionaxu
24675ba09a17a669f4906268088a769836aa87d8241fionaxu    @Test
24775ba09a17a669f4906268088a769836aa87d8241fionaxu    @SmallTest
24809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    public void testImsRegistered() {
24909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // when IMS is registered
25009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        mRegistrationCallback.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
25109f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // then service state should be IN_SERVICE and ImsPhone state set to registered
25209f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        verify(mImsPhone).setServiceState(eq(ServiceState.STATE_IN_SERVICE));
25309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        verify(mImsPhone).setImsRegistered(eq(true));
25409f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    }
25509f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
25609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @Test
25709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @SmallTest
25809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    public void testImsRegistering() {
25909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // when IMS is registering
26009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        mRegistrationCallback.onRegistering(ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
26109f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered
26209f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE));
26309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        verify(mImsPhone).setImsRegistered(eq(false));
26409f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    }
26509f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
26609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @Test
26709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @SmallTest
26809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    public void testImsDeregistered() {
26909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // when IMS is deregistered
27009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        mRegistrationCallback.onDeregistered(new ImsReasonInfo());
27109f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered
27209f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE));
27309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        verify(mImsPhone).setImsRegistered(eq(false));
27409f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    }
27509f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
27609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @Test
27709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @SmallTest
27809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    public void testVowifiDisabledOnLte() {
27909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // LTE is registered.
28009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(
28109f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger                mImsManager).getRegistrationTech();
28209f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        assertFalse(mCTUT.isVowifiEnabled());
28309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
28409f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // enable Voice over LTE
28509f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        ImsFeature.Capabilities caps = new ImsFeature.Capabilities();
28609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
28709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        mCapabilityCallback.onCapabilitiesStatusChanged(caps);
28809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        waitForHandlerAction(mCTHander, 1000);
28909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
29009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // Voice over IWLAN is still disabled
29109f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        assertFalse(mCTUT.isVowifiEnabled());
29209f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    }
29309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
29409f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @Test
29509f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @SmallTest
29609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    public void testVowifiDisabledOnIwlan() {
29709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // LTE is registered.
29809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).when(
29909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger                mImsManager).getRegistrationTech();
30009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        assertFalse(mCTUT.isVowifiEnabled());
30109f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
30209f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // enable Voice over IWLAN
30309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        ImsFeature.Capabilities caps = new ImsFeature.Capabilities();
30409f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
30509f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        mCapabilityCallback.onCapabilitiesStatusChanged(caps);
30609f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        waitForHandlerAction(mCTHander, 1000);
30709f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
30809f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        // Voice over IWLAN is enabled
30909f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger        assertTrue(mCTUT.isVowifiEnabled());
31009f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    }
31109f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger
31209f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @Test
31309f5b9723639968e85e2452f328b2517ffbc749cBrad Ebinger    @SmallTest
31475ba09a17a669f4906268088a769836aa87d8241fionaxu    public void testImsFeatureCapabilityChange() {
3151d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(
3161d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                mImsManager).getRegistrationTech();
31775ba09a17a669f4906268088a769836aa87d8241fionaxu        assertFalse(mCTUT.isVolteEnabled());
31875ba09a17a669f4906268088a769836aa87d8241fionaxu        assertFalse(mCTUT.isVideoCallEnabled());
3191d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger
3201d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        // enable only Voice
3211d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        ImsFeature.Capabilities caps = new ImsFeature.Capabilities();
3221d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
3231d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        mCapabilityCallback.onCapabilitiesStatusChanged(caps);
32424396c2cbf5fdbb665075cea256dc7ac94291b4cTyler Gunn        waitForHandlerAction(mCTHander, 1000);
3251d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger
32675ba09a17a669f4906268088a769836aa87d8241fionaxu        assertTrue(mCTUT.isVolteEnabled());
32775ba09a17a669f4906268088a769836aa87d8241fionaxu        assertFalse(mCTUT.isVideoCallEnabled());
32875ba09a17a669f4906268088a769836aa87d8241fionaxu        // video call not enabled
32975ba09a17a669f4906268088a769836aa87d8241fionaxu        verify(mImsPhone, times(0)).notifyForVideoCapabilityChanged(anyBoolean());
33075ba09a17a669f4906268088a769836aa87d8241fionaxu        verify(mImsPhone, times(1)).onFeatureCapabilityChanged();
3311d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger
33275ba09a17a669f4906268088a769836aa87d8241fionaxu        // enable video call
3331d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        ImsFeature.Capabilities capsVideo = new ImsFeature.Capabilities();
3341d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        capsVideo.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
3351d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        capsVideo.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
3361d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        mCapabilityCallback.onCapabilitiesStatusChanged(capsVideo);
33724396c2cbf5fdbb665075cea256dc7ac94291b4cTyler Gunn        waitForHandlerAction(mCTHander, 1000);
33875ba09a17a669f4906268088a769836aa87d8241fionaxu        assertTrue(mCTUT.isVideoCallEnabled());
33975ba09a17a669f4906268088a769836aa87d8241fionaxu        verify(mImsPhone, times(1)).notifyForVideoCapabilityChanged(eq(true));
34075ba09a17a669f4906268088a769836aa87d8241fionaxu    }
34175ba09a17a669f4906268088a769836aa87d8241fionaxu
34275ba09a17a669f4906268088a769836aa87d8241fionaxu    @Test
34375ba09a17a669f4906268088a769836aa87d8241fionaxu    @SmallTest
34475ba09a17a669f4906268088a769836aa87d8241fionaxu    public void testImsMTCall() {
34575ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
34675ba09a17a669f4906268088a769836aa87d8241fionaxu        assertFalse(mCTUT.mRingingCall.isRinging());
34775ba09a17a669f4906268088a769836aa87d8241fionaxu        // mock a MT call
3481d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
34975ba09a17a669f4906268088a769836aa87d8241fionaxu        verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any());
35075ba09a17a669f4906268088a769836aa87d8241fionaxu        verify(mImsPhone, times(1)).notifyIncomingRing();
35175ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());
35275ba09a17a669f4906268088a769836aa87d8241fionaxu        assertTrue(mCTUT.mRingingCall.isRinging());
35375ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(1, mCTUT.mRingingCall.getConnections().size());
35402761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        ImsPhoneConnection connection =
35502761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                (ImsPhoneConnection) mCTUT.mRingingCall.getConnections().get(0);
35602761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        connection.addListener(mImsPhoneConnectionListener);
35775ba09a17a669f4906268088a769836aa87d8241fionaxu    }
35875ba09a17a669f4906268088a769836aa87d8241fionaxu
35975ba09a17a669f4906268088a769836aa87d8241fionaxu    @Test
36075ba09a17a669f4906268088a769836aa87d8241fionaxu    @SmallTest
36175ba09a17a669f4906268088a769836aa87d8241fionaxu    public void testImsMTCallAccept() {
36275ba09a17a669f4906268088a769836aa87d8241fionaxu        testImsMTCall();
36375ba09a17a669f4906268088a769836aa87d8241fionaxu        assertTrue(mCTUT.mRingingCall.isRinging());
36475ba09a17a669f4906268088a769836aa87d8241fionaxu        try {
36575ba09a17a669f4906268088a769836aa87d8241fionaxu            mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
366e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            verify(mImsCall, times(1)).accept(eq(ImsCallProfile
367e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu                    .getCallTypeFromVideoState(ImsCallProfile.CALL_TYPE_VOICE)));
36875ba09a17a669f4906268088a769836aa87d8241fionaxu        } catch (Exception ex) {
36975ba09a17a669f4906268088a769836aa87d8241fionaxu            ex.printStackTrace();
37075ba09a17a669f4906268088a769836aa87d8241fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
37175ba09a17a669f4906268088a769836aa87d8241fionaxu        }
37275ba09a17a669f4906268088a769836aa87d8241fionaxu        assertFalse(mCTUT.mRingingCall.isRinging());
37375ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
37475ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
37575ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(1, mCTUT.mForegroundCall.getConnections().size());
37675ba09a17a669f4906268088a769836aa87d8241fionaxu    }
37775ba09a17a669f4906268088a769836aa87d8241fionaxu
37875ba09a17a669f4906268088a769836aa87d8241fionaxu    @Test
37975ba09a17a669f4906268088a769836aa87d8241fionaxu    @SmallTest
38075ba09a17a669f4906268088a769836aa87d8241fionaxu    public void testImsMTCallReject() {
38175ba09a17a669f4906268088a769836aa87d8241fionaxu        testImsMTCall();
38275ba09a17a669f4906268088a769836aa87d8241fionaxu        assertTrue(mCTUT.mRingingCall.isRinging());
38375ba09a17a669f4906268088a769836aa87d8241fionaxu        try {
38475ba09a17a669f4906268088a769836aa87d8241fionaxu            mCTUT.rejectCall();
38575ba09a17a669f4906268088a769836aa87d8241fionaxu            verify(mImsCall, times(1)).reject(eq(ImsReasonInfo.CODE_USER_DECLINE));
38675ba09a17a669f4906268088a769836aa87d8241fionaxu        } catch (Exception ex) {
38775ba09a17a669f4906268088a769836aa87d8241fionaxu            ex.printStackTrace();
38875ba09a17a669f4906268088a769836aa87d8241fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
38975ba09a17a669f4906268088a769836aa87d8241fionaxu        }
39075ba09a17a669f4906268088a769836aa87d8241fionaxu        assertFalse(mCTUT.mRingingCall.isRinging());
39175ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(0, mCTUT.mRingingCall.getConnections().size());
39275ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
39375ba09a17a669f4906268088a769836aa87d8241fionaxu    }
39475ba09a17a669f4906268088a769836aa87d8241fionaxu
39575ba09a17a669f4906268088a769836aa87d8241fionaxu    @Test
39675ba09a17a669f4906268088a769836aa87d8241fionaxu    @SmallTest
39775ba09a17a669f4906268088a769836aa87d8241fionaxu    public void testImsMTCallAcceptHangUp() {
39875ba09a17a669f4906268088a769836aa87d8241fionaxu        testImsMTCallAccept();
39975ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
40075ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
40175ba09a17a669f4906268088a769836aa87d8241fionaxu        try {
40275ba09a17a669f4906268088a769836aa87d8241fionaxu            mCTUT.hangup(mCTUT.mForegroundCall);
40375ba09a17a669f4906268088a769836aa87d8241fionaxu        } catch (Exception ex) {
40475ba09a17a669f4906268088a769836aa87d8241fionaxu            ex.printStackTrace();
40575ba09a17a669f4906268088a769836aa87d8241fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
40675ba09a17a669f4906268088a769836aa87d8241fionaxu        }
40775ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
40875ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
40975ba09a17a669f4906268088a769836aa87d8241fionaxu    }
41075ba09a17a669f4906268088a769836aa87d8241fionaxu
41175ba09a17a669f4906268088a769836aa87d8241fionaxu    @Test
41275ba09a17a669f4906268088a769836aa87d8241fionaxu    @SmallTest
41375ba09a17a669f4906268088a769836aa87d8241fionaxu    public void testImsMTCallAcceptHold() {
41475ba09a17a669f4906268088a769836aa87d8241fionaxu        testImsMTCallAccept();
41575ba09a17a669f4906268088a769836aa87d8241fionaxu
41675ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
41775ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
41875ba09a17a669f4906268088a769836aa87d8241fionaxu        // mock a new MT
41975ba09a17a669f4906268088a769836aa87d8241fionaxu        try {
4201d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class),
4211d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                    any(Bundle.class), any(ImsCall.Listener.class));
42275ba09a17a669f4906268088a769836aa87d8241fionaxu        } catch (Exception ex) {
42375ba09a17a669f4906268088a769836aa87d8241fionaxu            ex.printStackTrace();
42475ba09a17a669f4906268088a769836aa87d8241fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
42575ba09a17a669f4906268088a769836aa87d8241fionaxu        }
4261d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
42775ba09a17a669f4906268088a769836aa87d8241fionaxu
42875ba09a17a669f4906268088a769836aa87d8241fionaxu        verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any());
42975ba09a17a669f4906268088a769836aa87d8241fionaxu        verify(mImsPhone, times(2)).notifyIncomingRing();
43075ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
43175ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(ImsPhoneCall.State.WAITING, mCTUT.mRingingCall.getState());
43275ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());
43375ba09a17a669f4906268088a769836aa87d8241fionaxu
43475ba09a17a669f4906268088a769836aa87d8241fionaxu        //hold the foreground active call, accept the new ringing call
43575ba09a17a669f4906268088a769836aa87d8241fionaxu        try {
43675ba09a17a669f4906268088a769836aa87d8241fionaxu            mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
43775ba09a17a669f4906268088a769836aa87d8241fionaxu            verify(mImsCall, times(1)).hold();
43875ba09a17a669f4906268088a769836aa87d8241fionaxu        } catch (Exception ex) {
43975ba09a17a669f4906268088a769836aa87d8241fionaxu            ex.printStackTrace();
44075ba09a17a669f4906268088a769836aa87d8241fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
44175ba09a17a669f4906268088a769836aa87d8241fionaxu        }
44275ba09a17a669f4906268088a769836aa87d8241fionaxu
44375ba09a17a669f4906268088a769836aa87d8241fionaxu        waitForMs(100);
44475ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
44575ba09a17a669f4906268088a769836aa87d8241fionaxu        assertFalse(mCTUT.mRingingCall.isRinging());
44675ba09a17a669f4906268088a769836aa87d8241fionaxu        assertEquals(Call.State.HOLDING, mCTUT.mBackgroundCall.getState());
44775ba09a17a669f4906268088a769836aa87d8241fionaxu    }
448e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
449d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn    /**
450d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn     * Ensures that the dial method will perform a shared preferences lookup using the correct
451d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn     * shared preference key to determine the CLIR mode.
452d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn     */
453d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn    @Test
454d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn    @SmallTest
455d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn    public void testDialClirMode() {
456d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        mCTUT.setSharedPreferenceProxy((Context context) -> {
457d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn            return mSharedPreferences;
458d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        });
459d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        ArgumentCaptor<String> mStringCaptor = ArgumentCaptor.forClass(String.class);
460d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        doReturn(CommandsInterface.CLIR_INVOCATION).when(mSharedPreferences).getInt(
461d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn                mStringCaptor.capture(), anyInt());
462d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn
463d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        try {
464d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn            mCTUT.dial("+17005554141", VideoProfile.STATE_AUDIO_ONLY, null);
465d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        } catch (CallStateException cse) {
466d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn            cse.printStackTrace();
467d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn            Assert.fail("unexpected exception thrown" + cse.getMessage());
468d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        }
469d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn
470d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        // Ensure that the correct key was queried from the shared prefs.
471d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn        assertEquals("clir_key0", mStringCaptor.getValue());
472d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn    }
473d04bdfe07ddf5523ca4d1c07780c3f131c4254beTyler Gunn
474e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn    /**
475e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn     * Ensures for an emergency call that the dial method will default the CLIR to
476e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn     * {@link CommandsInterface#CLIR_SUPPRESSION}, ensuring the caller's ID is shown.
477e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn     */
478e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn    @Test
479e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn    @SmallTest
480e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn    public void testEmergencyDialSuppressClir() {
481e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        mCTUT.setSharedPreferenceProxy((Context context) -> {
482e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            return mSharedPreferences;
483e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        });
484e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        // Mock implementation of phone number utils treats everything as an emergency.
485e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        mCTUT.setPhoneNumberUtilsProxy((String string) -> {
486e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            return true;
487e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        });
488e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        // Set preference to hide caller ID.
489e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
490e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        doReturn(CommandsInterface.CLIR_INVOCATION).when(mSharedPreferences).getInt(
491e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn                stringCaptor.capture(), anyInt());
492e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn
493e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        try {
494e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            mCTUT.dial("+17005554141", VideoProfile.STATE_AUDIO_ONLY, null);
495e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn
496e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            ArgumentCaptor<ImsCallProfile> profileCaptor = ArgumentCaptor.forClass(
497e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn                    ImsCallProfile.class);
4981d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            verify(mImsManager, times(1)).makeCall(eq(mImsCallProfile),
4991d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                    eq(new String[]{"+17005554141"}), any());
500e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn
501e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            // Because this is an emergency call, we expect caller id to be visible now.
5020b49b9969d3e8923cc9b6a1add06ced2a8d245b4Brad Ebinger            assertEquals(mImsCallProfile.getCallExtraInt(ImsCallProfile.EXTRA_OIR),
503e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn                    CommandsInterface.CLIR_SUPPRESSION);
504e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        } catch (CallStateException cse) {
505e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            cse.printStackTrace();
506e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            Assert.fail("unexpected exception thrown" + cse.getMessage());
507e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        } catch (ImsException ie) {
508e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            ie.printStackTrace();
509e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn            Assert.fail("unexpected exception thrown" + ie.getMessage());
510e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn        }
511e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn    }
512e2b25c138d61072f3532c69110c3713006dabf20Tyler Gunn
513516010d13181808ca8205316a419b615e5a9fe5eShuoq    @FlakyTest
514cc940f429180765b6072a071becae8117e665954Amit Mahajan    @Ignore
515e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @Test
516e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @SmallTest
517e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    public void testImsMOCallDial() {
518e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
519e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
520e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        try {
521e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            mCTUT.dial("+17005554141", ImsCallProfile.CALL_TYPE_VOICE, null);
5221d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            verify(mImsManager, times(1)).makeCall(eq(mImsCallProfile),
523e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu                    eq(new String[]{"+17005554141"}), (ImsCall.Listener) any());
524e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        } catch (Exception ex) {
525e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            ex.printStackTrace();
526e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
527e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        }
528e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
529e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.DIALING, mCTUT.mForegroundCall.getState());
530e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        //call established
531e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        mImsCallListener.onCallProgressing(mSecondImsCall);
532e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.ALERTING, mCTUT.mForegroundCall.getState());
533e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    }
534e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
535ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yu    @FlakyTest
536ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yu    @Ignore
537e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @Test
538e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @SmallTest
539e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    public void testImsMTActiveMODial() {
540e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
541e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.IDLE, mCTUT.mBackgroundCall.getState());
542e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
543e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        testImsMTCallAccept();
544e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
545e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
546e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.IDLE, mCTUT.mBackgroundCall.getState());
547e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        try {
548e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            mCTUT.dial("+17005554141", ImsCallProfile.CALL_TYPE_VOICE, null);
5491d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            verify(mImsManager, times(1)).makeCall(eq(mImsCallProfile),
550e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu                    eq(new String[]{"+17005554141"}), (ImsCall.Listener) any());
551e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        } catch (Exception ex) {
552e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            ex.printStackTrace();
553e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
554e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        }
555e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        waitForMs(100);
556e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.DIALING, mCTUT.mForegroundCall.getState());
557e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.HOLDING, mCTUT.mBackgroundCall.getState());
558e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    }
559e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
560e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @Test
561e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @SmallTest
562e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    public void testImsMOCallHangup() {
563e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        testImsMOCallDial();
564e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        //hangup before call go to active
565e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        try {
566e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            mCTUT.hangup(mCTUT.mForegroundCall);
567e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        } catch (Exception ex) {
568e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            ex.printStackTrace();
569e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
570e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        }
571e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
572e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
573e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    }
574e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
575e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @Test
576e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    @SmallTest
577e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    public void testImsSendDtmf() {
578e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        //establish a MT call
579e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        testImsMTCallAccept();
580e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        mCTUT.sendDtmf(PhoneNumberUtils.PAUSE, null);
581e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        //verify trigger sendDtmf to mImsCall
582e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        verify(mImsCall, times(1)).sendDtmf(eq(PhoneNumberUtils.PAUSE), (Message) isNull());
583e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        // mock a new MT
584e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        try {
5851d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class),
5861d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                    any(Bundle.class), any(ImsCall.Listener.class));
5871d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger            mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
588e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
589e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        } catch (Exception ex) {
590e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            ex.printStackTrace();
591e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu            Assert.fail("unexpected exception thrown" + ex.getMessage());
592e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        }
593e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
594e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        waitForMs(100);
595e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu
596e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        mCTUT.sendDtmf(PhoneNumberUtils.WAIT, null);
597e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        //verify trigger sendDtmf to mImsSecondCall
598e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu        verify(mSecondImsCall, times(1)).sendDtmf(eq(PhoneNumberUtils.WAIT), (Message) isNull());
599e415b7b5ae3afec0b7a24d85b930e8cca47499a6fionaxu    }
6004558536154e496ea917b343e496ed64c94250873Tyler Gunn
6014558536154e496ea917b343e496ed64c94250873Tyler Gunn    @Test
6024558536154e496ea917b343e496ed64c94250873Tyler Gunn    @SmallTest
6034558536154e496ea917b343e496ed64c94250873Tyler Gunn    public void testReasonCodeRemap() {
6044558536154e496ea917b343e496ed64c94250873Tyler Gunn        assertEquals(ImsReasonInfo.CODE_WIFI_LOST, mCTUT.maybeRemapReasonCode(
6054558536154e496ea917b343e496ed64c94250873Tyler Gunn                new ImsReasonInfo(1, 1, "Wifi signal lost.")));
6064558536154e496ea917b343e496ed64c94250873Tyler Gunn        assertEquals(ImsReasonInfo.CODE_WIFI_LOST, mCTUT.maybeRemapReasonCode(
6074558536154e496ea917b343e496ed64c94250873Tyler Gunn                new ImsReasonInfo(200, 1, "Wifi signal lost.")));
6084558536154e496ea917b343e496ed64c94250873Tyler Gunn        assertEquals(ImsReasonInfo.CODE_ANSWERED_ELSEWHERE,
6094558536154e496ea917b343e496ed64c94250873Tyler Gunn                mCTUT.maybeRemapReasonCode(new ImsReasonInfo(501, 1, "Call answered elsewhere.")));
6104558536154e496ea917b343e496ed64c94250873Tyler Gunn        assertEquals(ImsReasonInfo.CODE_ANSWERED_ELSEWHERE,
6114558536154e496ea917b343e496ed64c94250873Tyler Gunn                mCTUT.maybeRemapReasonCode(new ImsReasonInfo(510, 1, "Call answered elsewhere.")));
6124558536154e496ea917b343e496ed64c94250873Tyler Gunn        assertEquals(90210, mCTUT.maybeRemapReasonCode(new ImsReasonInfo(90210, 1,
6134558536154e496ea917b343e496ed64c94250873Tyler Gunn                "Call answered elsewhere.")));
6144558536154e496ea917b343e496ed64c94250873Tyler Gunn    }
615ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger
616ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger
617ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    @Test
618ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    @SmallTest
619ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    public void testDialImsServiceUnavailable() throws ImsException {
620ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        doThrow(new ImsException("Test Exception", ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN)).when(
6211d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                mImsManager).createCallProfile(anyInt(), anyInt());
622b03dbaac0051b2d6c9daee438781c26bf4123fdeBrad Ebinger        mCTUT.setRetryTimeout(() -> 0);
623ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
624ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
625ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger
626ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        try {
627ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger            mCTUT.dial("+17005554141", ImsCallProfile.CALL_TYPE_VOICE, null);
628ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        } catch (Exception e) {
629ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger            Assert.fail();
630ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        }
631ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger
632ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        // wait for handler to process ImsService connection retry
633ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        waitForHandlerAction(mCTHander, 1000); // 1 second timeout
6341d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        verify(mImsManager, never()).makeCall(nullable(ImsCallProfile.class),
635ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger                eq(new String[]{"+17005554141"}), nullable(ImsCall.Listener.class));
636ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        // Make sure that open is called in ImsPhoneCallTracker when it was first connected and
637ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        // again after retry.
6381d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        verify(mImsManager, times(2)).open(
6391d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                nullable(MmTelFeature.Listener.class));
640ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    }
641ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger
642ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yu    @FlakyTest
643ee5c35e032973df2a96ff1d37c3714d3a12f3dd0Jack Yu    @Ignore
644ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    @Test
645ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    @SmallTest
646ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    public void testTTYImsServiceUnavailable() throws ImsException {
647ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        doThrow(new ImsException("Test Exception", ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN)).when(
648ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger                mImsManager).setUiTTYMode(nullable(Context.class), anyInt(),
649ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger                nullable(Message.class));
650ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        // Remove retry timeout delay
651b03dbaac0051b2d6c9daee438781c26bf4123fdeBrad Ebinger        mCTUT.setRetryTimeout(() -> 0); //ms
652ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger
653ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        mCTUT.setUiTTYMode(0, new Message());
654ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger
655ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        // wait for handler to process ImsService connection retry
656ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        waitForHandlerAction(mCTHander, 100);
657ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        // Make sure that open is called in ImsPhoneCallTracker to re-establish connection to
658ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger        // ImsService
6591d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger        verify(mImsManager, times(2)).open(
6601d0af327f9d60dcdb010314bbdc4ab2492df11dfBrad Ebinger                nullable(MmTelFeature.Listener.class));
661ec581c0b21b5da662b9fe60a8212a66196a9f05cBrad Ebinger    }
662745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn
66302761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    /**
66402761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn     * Test notification of handover from LTE to WIFI and WIFI to LTE and ensure that the expected
66502761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn     * connection events are sent.
66602761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn     */
66702761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    @Test
66802761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    @SmallTest
66902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    public void testNotifyHandovers() {
67002761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        setupCarrierConfig();
67102761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn
67202761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        //establish a MT call
67302761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        testImsMTCallAccept();
67402761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        ImsPhoneConnection connection =
67502761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                (ImsPhoneConnection) mCTUT.mForegroundCall.getConnections().get(0);
67602761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        ImsCall call = connection.getImsCall();
67702761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        // Needs to be a video call to see this signalling.
6780b49b9969d3e8923cc9b6a1add06ced2a8d245b4Brad Ebinger        mImsCallProfile.mCallType = ImsCallProfile.CALL_TYPE_VT;
67902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn
68002761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        // First handover from LTE to WIFI; this takes us into a mid-call state.
68102761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        call.getImsCallSessionListenerProxy().callSessionHandover(call.getCallSession(),
68202761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
68302761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                new ImsReasonInfo());
68402761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        // Handover back to LTE.
68502761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        call.getImsCallSessionListenerProxy().callSessionHandover(call.getCallSession(),
68602761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, ServiceState.RIL_RADIO_TECHNOLOGY_LTE,
68702761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                new ImsReasonInfo());
68802761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        verify(mImsPhoneConnectionListener).onConnectionEvent(eq(
68902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE), isNull());
69002761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn
69102761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        // Finally hand back to WIFI
69202761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        call.getImsCallSessionListenerProxy().callSessionHandover(call.getCallSession(),
69302761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
69402761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                new ImsReasonInfo());
69502761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        verify(mImsPhoneConnectionListener).onConnectionEvent(eq(
69602761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_LTE_TO_WIFI), isNull());
69702761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    }
69802761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn
69902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    /**
70002761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn     * Configure carrier config options relevant to the unit test.
70102761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn     */
70202761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    public void setupCarrierConfig() {
70302761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        PersistableBundle bundle = new PersistableBundle();
70402761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        bundle.putBoolean(CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_LTE_TO_WIFI_BOOL,
70502761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                true);
70602761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        bundle.putBoolean(CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL,
70702761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn                true);
70802761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        bundle.putBoolean(CarrierConfigManager.KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, true);
70902761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn        mCTUT.updateCarrierConfigCache(bundle);
71002761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn    }
71102761d2406c0197cebd255b575f161f5145efbb3Tyler Gunn
712745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    @Test
713745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    @SmallTest
714745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    public void testLowBatteryDisconnectMidCall() {
715745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn        assertEquals(DisconnectCause.LOW_BATTERY, mCTUT.getDisconnectCauseFromReasonInfo(
716745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn                new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_LOW_BATTERY, 0), Call.State.ACTIVE));
717745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn        assertEquals(DisconnectCause.LOW_BATTERY, mCTUT.getDisconnectCauseFromReasonInfo(
718745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn                new ImsReasonInfo(ImsReasonInfo.CODE_LOW_BATTERY, 0), Call.State.ACTIVE));
719745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    }
720745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn
721745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    @Test
722745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    @SmallTest
723da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn    public void testImsAlternateEmergencyDisconnect() {
724da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn        assertEquals(DisconnectCause.IMS_SIP_ALTERNATE_EMERGENCY_CALL,
725da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn                mCTUT.getDisconnectCauseFromReasonInfo(
726da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn                        new ImsReasonInfo(ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0),
727da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn                        Call.State.ACTIVE));
728da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn    }
729da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn
730da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn    @Test
731da70560d7b8cebfd3c5d3b58a343c6b2159a6d49Tyler Gunn    @SmallTest
732745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    public void testLowBatteryDisconnectDialing() {
733745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn        assertEquals(DisconnectCause.DIAL_LOW_BATTERY, mCTUT.getDisconnectCauseFromReasonInfo(
734745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn                new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_LOW_BATTERY, 0), Call.State.DIALING));
735745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn        assertEquals(DisconnectCause.DIAL_LOW_BATTERY, mCTUT.getDisconnectCauseFromReasonInfo(
736745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn                new ImsReasonInfo(ImsReasonInfo.CODE_LOW_BATTERY, 0), Call.State.DIALING));
737745dce04d7334df0f6b52696b672d86f3bf86027Tyler Gunn    }
738fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
739fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    /**
740fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn     * Tests that no hold tone is played if the call is remotely held and the media direction is
741fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn     * send/receive (i.e. there is an audio stream present).
742fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn     */
743fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    @Test
744fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    @SmallTest
745fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    public void testNoRemoteHoldtone() {
746fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        //establish a MT call
747fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        testImsMTCallAccept();
748fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection();
749fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsCall call = connection.getImsCall();
750fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
751fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        // Set the media direction to send/receive.
752fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsCallProfile callProfile = new ImsCallProfile();
753fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
754fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        call.setCallProfile(callProfile);
755fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
756fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        try {
757fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            mCTUT.onCallHoldReceived(call);
758fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        } catch (Exception ex) {
759fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            ex.printStackTrace();
760fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            Assert.fail("unexpected exception thrown" + ex.getMessage());
761fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        }
762fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        verify(mImsPhone, never()).startOnHoldTone(nullable(Connection.class));
763fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    }
764fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
765fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    /**
766fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn     * Verifies that a remote hold tone is played when the call is remotely held and the media
767fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn     * direction is inactive (i.e. the audio stream is not playing, so we should play the tone).
768fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn     */
769fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    @Test
770fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    @SmallTest
771fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    public void testRemoteToneInactive() {
772fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        //establish a MT call
773fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        testImsMTCallAccept();
774fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection();
775fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsCall call = connection.getImsCall();
776fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
777fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        // Set the media direction to inactive to trigger a hold tone.
778fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsCallProfile callProfile = new ImsCallProfile();
779fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_INACTIVE;
780fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        call.setCallProfile(callProfile);
781fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
782fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        try {
783fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            mCTUT.onCallHoldReceived(call);
784fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        } catch (Exception ex) {
785fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            ex.printStackTrace();
786fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            Assert.fail("unexpected exception thrown" + ex.getMessage());
787fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        }
788fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        verify(mImsPhone, times(1)).startOnHoldTone(nullable(Connection.class));
789fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    }
790fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
791fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    @Test
792fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    @SmallTest
793fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    public void testRemoteHoldtone() {
794fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        // Set carrier config to always play remote hold tone.
795fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        mCTUT.setAlwaysPlayRemoteHoldTone(true);
796fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        //establish a MT call
797fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        testImsMTCallAccept();
798fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection();
799fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsCall call = connection.getImsCall();
800fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
801fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        // Set the media direction to send/receive; normally we don't play a hold tone but the
802fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        // carrier config option is set to ensure we will do it in this case.
803fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        ImsCallProfile callProfile = new ImsCallProfile();
804fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
805fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        call.setCallProfile(callProfile);
806fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn
807fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        try {
808fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            mCTUT.onCallHoldReceived(call);
809fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        } catch (Exception ex) {
810fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            ex.printStackTrace();
811fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn            Assert.fail("unexpected exception thrown" + ex.getMessage());
812fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        }
813fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn        verify(mImsPhone, times(1)).startOnHoldTone(nullable(Connection.class));
814fb4330692d332ee8ee4614a9500ae39efbe138d8Tyler Gunn    }
81575ba09a17a669f4906268088a769836aa87d8241fionaxu}
816