blob: 197c94c2dc56617164d15586d07676172e73f328 [file] [log] [blame]
/*
* Copyright (C) 2016 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 com.android.internal.telephony.imsphone;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.ImsCallProfile;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.GsmCdmaCall;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.lang.reflect.Field;
import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyChar;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
public class ImsPhoneConnectionTest extends TelephonyTest {
private ImsPhoneConnection mConnectionUT;
private Bundle mBundle = new Bundle();
@Mock
private ImsPhoneCall mForeGroundCall;
@Mock
private ImsPhoneCall mBackGroundCall;
@Mock
private ImsPhoneCall mRingGroundCall;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
replaceInstance(Handler.class, "mLooper", mImsCT, Looper.getMainLooper());
replaceInstance(ImsPhoneCallTracker.class, "mForegroundCall", mImsCT, mForeGroundCall);
replaceInstance(ImsPhoneCallTracker.class, "mBackgroundCall", mImsCT, mBackGroundCall);
replaceInstance(ImsPhoneCallTracker.class, "mRingingCall", mImsCT, mRingGroundCall);
replaceInstance(ImsPhoneCallTracker.class, "mPhone", mImsCT, mImsPhone);
mImsCallProfile.mCallExtras = mBundle;
doReturn(ImsPhoneCall.State.IDLE).when(mForeGroundCall).getState();
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
@Test
@SmallTest
public void testImsConnectionSanity() {
logd("Testing initial state of MT ImsPhoneConnection");
mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
assertEquals(ImsPhoneCall.State.IDLE, mConnectionUT.getState());
assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getNumberPresentation());
assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getCnapNamePresentation());
assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
assertEquals(0, mConnectionUT.getDisconnectTime());
assertEquals(0, mConnectionUT.getHoldDurationMillis());
assertNull(mConnectionUT.getOrigDialString());
assertFalse(mConnectionUT.isMultiparty());
assertFalse(mConnectionUT.isConferenceHost());
verify(mForeGroundCall, times(1)).attach((Connection) any(),
eq(ImsPhoneCall.State.INCOMING));
logd("Testing initial state of MO ImsPhoneConnection");
mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false);
assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getNumberPresentation());
assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getCnapNamePresentation());
assertEquals("+1 (700).555-41NN,1234", mConnectionUT.getOrigDialString());
verify(mForeGroundCall, times(1)).attachFake((Connection) any(),
eq(ImsPhoneCall.State.DIALING));
}
@Test
@SmallTest
public void testImsUpdateStateForeGround() {
// MO Foreground Connection dailing -> active
mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
mForeGroundCall, false);
// initially in dialing state
doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
// for Ringing/Dialing upadte postDialState
assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
verify(mForeGroundCall, times(1)).update(eq(mConnectionUT), eq(mImsCall),
eq(Call.State.ACTIVE));
}
@Test
@SmallTest
public void testImsUpdateStateBackGround() {
// MT background Connection dialing -> active
mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mBackGroundCall, false);
doReturn(Call.State.HOLDING).when(mBackGroundCall).getState();
assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
verify(mBackGroundCall, times(1)).detach(eq(mConnectionUT));
verify(mForeGroundCall, times(1)).attach(eq(mConnectionUT));
verify(mForeGroundCall, times(1)).update(eq(mConnectionUT), eq(mImsCall),
eq(Call.State.ACTIVE));
assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
}
@Test
@SmallTest
public void testImsUpdateStatePendingHold() {
mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
mForeGroundCall, false);
doReturn(true).when(mImsCall).isPendingHold();
assertFalse(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
verify(mForeGroundCall, times(0)).update(eq(mConnectionUT), eq(mImsCall),
eq(Call.State.ACTIVE));
assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
}
@Test
@SmallTest
public void testUpdateAddressDisplay() {
mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getNumberPresentation());
assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getCnapNamePresentation());
doReturn(ImsCallProfile.OIR_PRESENTATION_PAYPHONE).when(mImsCallProfile)
.getCallExtraInt(eq(ImsCallProfile.EXTRA_CNAP));
doReturn(ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED).when(mImsCallProfile)
.getCallExtraInt(eq(ImsCallProfile.EXTRA_OIR));
mConnectionUT.updateAddressDisplay(mImsCall);
assertEquals(ImsCallProfile.OIRToPresentation(ImsCallProfile.OIR_PRESENTATION_PAYPHONE),
mConnectionUT.getCnapNamePresentation());
assertEquals(ImsCallProfile.OIRToPresentation(
ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED),
mConnectionUT.getNumberPresentation());
}
@Test
@SmallTest
public void testConnectionDisconnect() {
//Mock we have an active connection
testImsUpdateStateForeGround();
waitForMs(50);
mConnectionUT.onDisconnect(DisconnectCause.LOCAL);
assertEquals(DisconnectCause.LOCAL, mConnectionUT.getDisconnectCause());
assertEquals(GsmCdmaCall.State.DISCONNECTED, mConnectionUT.getState());
assertTrue(mConnectionUT.getDisconnectTime() <= System.currentTimeMillis());
assertTrue(mConnectionUT.getDurationMillis() >= 50);
}
@Test
@SmallTest
public void testPostDialWait() {
mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
PhoneNumberUtils.WAIT), mImsCT, mForeGroundCall, false);
doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Message msg = (Message) invocation.getArguments()[1];
AsyncResult.forMessage(msg);
msg.sendToTarget();
return null;
}
}).when(mImsCT).sendDtmf(anyChar(), (Message) any());
// process post dial string during update
assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
assertEquals(Connection.PostDialState.WAIT, mConnectionUT.getPostDialState());
mConnectionUT.proceedAfterWaitChar();
waitForMs(50);
assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
}
@Test
@MediumTest
public void testPostDialPause() {
mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false);
doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Message msg = (Message) invocation.getArguments()[1];
AsyncResult.forMessage(msg);
msg.sendToTarget();
return null;
}
}).when(mImsCT).sendDtmf(anyChar(), (Message) any());
// process post dial string during update
assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
assertEquals(Connection.PostDialState.STARTED, mConnectionUT.getPostDialState());
try {
Field field = ImsPhoneConnection.class.getDeclaredField("PAUSE_DELAY_MILLIS");
field.setAccessible(true);
waitForMs((Integer) field.get(null) + 50);
} catch (Exception ex) {
Assert.fail("unexpected exception thrown" + ex.getMessage());
}
assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
}
@Test
@SmallTest
public void testSetWifi() {
mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
assertFalse(mConnectionUT.isWifi());
// ImsCall.isWifiCall is tested elsewhere
doReturn(true).when(mImsCall).isWifiCall();
mBundle.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE,
ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN + "");
assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
assertTrue(mConnectionUT.isWifi());
}
@Test
@SmallTest
public void testSetWifi2() {
mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
assertFalse(mConnectionUT.isWifi());
// ImsCall.isWifiCall is tested elsewhere
doReturn(true).when(mImsCall).isWifiCall();
// Tests to make sure that the EXTRA_CALL_RAT_TYPE_ALT string is set correctly for newer
// devices.
mBundle.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE_ALT,
ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN + "");
assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
assertTrue(mConnectionUT.isWifi());
}
}