blob: 67587d4021cec88c30d797bf89b201ad630158ab [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;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyChar;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.os.Handler;
import android.os.Message;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import java.lang.reflect.Field;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class CallManagerTest extends TelephonyTest {
@Mock
GsmCdmaCall mFgCall;
@Mock
GsmCdmaCall mBgCall;
@Mock
GsmCdmaCall mRingingCall;
@Mock
Phone mSecondPhone;
@Before
public void setUp() throws Exception {
super.setUp(this.getClass().getSimpleName());
restoreInstance(CallManager.class, "INSTANCE", null);
/* Mock Phone and Call, initially all calls are idle */
doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
doReturn(mBgCall).when(mPhone).getBackgroundCall();
doReturn(mFgCall).when(mPhone).getForegroundCall();
doReturn(mRingingCall).when(mPhone).getRingingCall();
doReturn(mPhone).when(mBgCall).getPhone();
doReturn(mPhone).when(mFgCall).getPhone();
doReturn(mPhone).when(mRingingCall).getPhone();
doReturn(Call.State.IDLE).when(mBgCall).getState();
doReturn(Call.State.IDLE).when(mFgCall).getState();
doReturn(Call.State.IDLE).when(mRingingCall).getState();
doReturn(true).when(mBgCall).isIdle();
doReturn(true).when(mFgCall).isIdle();
doReturn(true).when(mRingingCall).isIdle();
/* CallManager is a static object with private constructor; no need to call constructor */
CallManager.getInstance().registerPhone(mPhone);
processAllMessages();
}
@After
public void tearDown() throws Exception {
CallManager.getInstance().unregisterPhone(mPhone);
super.tearDown();
}
@SmallTest @Test
public void testSanity() {
assertEquals(mPhone, CallManager.getInstance().getDefaultPhone());
assertFalse(CallManager.getInstance().hasActiveBgCall());
assertFalse(CallManager.getInstance().hasActiveRingingCall());
assertFalse(CallManager.getInstance().hasActiveFgCall());
/* return the default phone if there is no any active call */
assertEquals(mPhone, CallManager.getInstance().getRingingPhone());
assertEquals(mPhone, CallManager.getInstance().getBgPhone());
assertEquals(mPhone, CallManager.getInstance().getFgPhone());
}
@SmallTest @Test
public void testBasicDial() throws Exception {
//verify can dial and dial function of the phone is being triggered
CallManager.getInstance().dial(mPhone,
PhoneNumberUtils.stripSeparators("+17005554141"), 0);
ArgumentCaptor<String> mCaptorString = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<PhoneInternalInterface.DialArgs> dialArgsCaptor =
ArgumentCaptor.forClass(PhoneInternalInterface.DialArgs.class);
verify(mPhone, times(1)).dial(mCaptorString.capture(), dialArgsCaptor.capture());
assertEquals(PhoneNumberUtils.stripSeparators("+17005554141"),
mCaptorString.getValue());
assertEquals(0, dialArgsCaptor.getValue().videoState);
}
@SmallTest @Test
public void testBasicRejectCall() throws Exception {
//verify can dial and dial function of the phone is being triggered
CallManager.getInstance().rejectCall(mRingingCall);
verify(mPhone, times(1)).rejectCall();
}
@SmallTest @Test
public void testSendDtmf() throws Exception {
CallManager.getInstance().sendDtmf('a');
verify(mPhone, times(0)).sendDtmf(eq('a'));
//has active fg Call
doReturn(false).when(mFgCall).isIdle();
assertEquals(mFgCall, CallManager.getInstance().getActiveFgCall());
CallManager.getInstance().sendDtmf('a');
verify(mPhone, times(1)).sendDtmf(eq('a'));
}
@SmallTest @Test
public void testStartDtmf() throws Exception {
doReturn(true).when(mFgCall).isIdle();
assertFalse(CallManager.getInstance().startDtmf('a'));
verify(mPhone, times(0)).startDtmf(anyChar());
//has active fg Call
doReturn(false).when(mFgCall).isIdle();
assertEquals(mFgCall, CallManager.getInstance().getActiveFgCall());
assertTrue(CallManager.getInstance().startDtmf('a'));
verify(mPhone, times(1)).startDtmf('a');
}
@SmallTest @Test
public void testStopDtmf() throws Exception {
doReturn(true).when(mFgCall).isIdle();
CallManager.getInstance().stopDtmf();
verify(mPhone, times(0)).stopDtmf();
//has active fg Call
doReturn(false).when(mFgCall).isIdle();
assertEquals(mPhone, CallManager.getInstance().getFgPhone());
CallManager.getInstance().stopDtmf();
verify(mPhone, times(1)).stopDtmf();
}
@SmallTest @Test
public void testSendBurstDtmf() throws Exception {
doReturn(true).when(mFgCall).isIdle();
assertFalse(CallManager.getInstance().sendBurstDtmf("12*#", 0, 0, null));
verify(mPhone, times(0)).sendBurstDtmf(anyString(), anyInt(), anyInt(), (Message) any());
//has active fg Call
doReturn(false).when(mFgCall).isIdle();
assertTrue(CallManager.getInstance().sendBurstDtmf("12*#", 0, 0, null));
verify(mPhone, times(1)).sendBurstDtmf("12*#", 0, 0, null);
}
@SmallTest @Test
public void testSetGetMute() throws Exception {
CallManager.getInstance().setMute(false);
verify(mPhone, times(0)).setMute(anyBoolean());
//has active fg Call
doReturn(false).when(mFgCall).isIdle();
CallManager.getInstance().setMute(false);
verify(mPhone, times(1)).setMute(false);
CallManager.getInstance().setMute(true);
verify(mPhone, times(1)).setMute(true);
}
@SmallTest @Test
public void testFgCallActiveDial() throws Exception {
/* set Fg/Bg Call state to active, verify CallManager Logical */
doReturn(false).when(mFgCall).isIdle();
doReturn(false).when(mBgCall).isIdle();
assertTrue(CallManager.getInstance().hasActiveFgCall());
assertTrue(CallManager.getInstance().hasActiveBgCall());
assertTrue(CallManager.getInstance().hasActiveFgCall(mPhone.getSubId()));
assertFalse(CallManager.getInstance().hasDisconnectedFgCall());
/* try dial with non-idle foreground call and background call */
CallManager.getInstance().dial(mPhone,
PhoneNumberUtils.stripSeparators("+17005554141"), 0);
ArgumentCaptor<String> mCaptorString = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<PhoneInternalInterface.DialArgs> dialArgsCaptor =
ArgumentCaptor.forClass(PhoneInternalInterface.DialArgs.class);
verify(mPhone, times(1)).dial(mCaptorString.capture(), dialArgsCaptor.capture());
assertEquals(PhoneNumberUtils.stripSeparators("+17005554141"),
mCaptorString.getValue());
assertEquals(0, dialArgsCaptor.getValue().videoState);
}
@Test @SmallTest
public void testRegisterEvent() throws Exception {
Field field = CallManager.class.getDeclaredField("EVENT_CALL_WAITING");
field.setAccessible(true);
int mEvent = (Integer) field.get(CallManager.getInstance());
verify(mPhone, times(1)).registerForCallWaiting(isA(Handler.class),
eq(mEvent), isNull());
field = CallManager.class.getDeclaredField("EVENT_PRECISE_CALL_STATE_CHANGED");
field.setAccessible(true);
mEvent = (Integer) field.get(CallManager.getInstance());
verify(mPhone, times(1)).registerForPreciseCallStateChanged(isA(Handler.class),
eq(mEvent), isA(Object.class));
field = CallManager.class.getDeclaredField("EVENT_RINGBACK_TONE");
field.setAccessible(true);
mEvent = (Integer) field.get(CallManager.getInstance());
verify(mPhone, times(1)).registerForRingbackTone(isA(Handler.class),
eq(mEvent), isA(Object.class));
}
@Test @SmallTest
public void testGetServiceState() throws Exception {
// register for another phone
ServiceState mSecondServiceState = mock(ServiceState.class);
doReturn(mSecondServiceState).when(mSecondPhone).getServiceState();
logd("Phone registered with CallManager");
CallManager.getInstance().registerPhone(mSecondPhone);
processAllMessages();
// mPhone: STATE_IN_SERVICE > mPhoneSecond: state STATE_OUT_OF_SERVICE
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSecondServiceState).getState();
assertEquals(ServiceState.STATE_IN_SERVICE, CallManager.getInstance().getServiceState());
// mPhone: STATE_IN_SERVICE > mPhoneSecond: state STATE_EMERGENCY_ONLY
doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mSecondServiceState).getState();
assertEquals(ServiceState.STATE_IN_SERVICE, CallManager.getInstance().getServiceState());
// mPhone: STATE_IN_SERVICE > mPhoneSecond: state STATE_POWER_OFF
doReturn(ServiceState.STATE_POWER_OFF).when(mSecondServiceState).getState();
assertEquals(ServiceState.STATE_IN_SERVICE, CallManager.getInstance().getServiceState());
// mPhone: STATE_EMERGENCY_ONLY < mPhoneSecond: state STATE_OUT_OF_SERVICE
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSecondServiceState).getState();
doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getState();
assertEquals(ServiceState.STATE_OUT_OF_SERVICE,
CallManager.getInstance().getServiceState());
// mPhone: STATE_POWER_OFF < mPhoneSecond: state STATE_OUT_OF_SERVICE
doReturn(ServiceState.STATE_POWER_OFF).when(mServiceState).getState();
assertEquals(ServiceState.STATE_OUT_OF_SERVICE,
CallManager.getInstance().getServiceState());
/* mPhone: STATE_POWER_OFF < mPhoneSecond: state STATE_EMERGENCY_ONLY
but OUT_OF_SERVICE will replaces EMERGENCY_ONLY and POWER_OFF */
doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mSecondServiceState).getState();
assertEquals(ServiceState.STATE_OUT_OF_SERVICE,
CallManager.getInstance().getServiceState());
CallManager.getInstance().unregisterPhone(mSecondPhone);
}
}