blob: 562a60808cadc55bd9548c1118c1900c30970b13 [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 com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
import static com.android.internal.telephony.Phone.EVENT_ICC_CHANGED;
import static com.android.internal.telephony.Phone.EVENT_SRVCC_STATE_CHANGED;
import static com.android.internal.telephony.Phone.EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED;
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.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.os.WorkSource;
import android.preference.PreferenceManager;
import android.telecom.VideoProfile;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.CellIdentity;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.test.filters.FlakyTest;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.IccVmNotSupportedException;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import java.util.List;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class GsmCdmaPhoneTest extends TelephonyTest {
@Mock
private Handler mTestHandler;
@Mock
private UiccSlot mUiccSlot;
@Mock
private CommandsInterface mMockCi;
//mPhoneUnderTest
private GsmCdmaPhone mPhoneUT;
private static final int EVENT_EMERGENCY_CALLBACK_MODE_EXIT = 1;
private static final int EVENT_EMERGENCY_CALL_TOGGLE = 2;
private static final int EVENT_SET_ICC_LOCK_ENABLED = 3;
private void switchToGsm() {
mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_GSM);
mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_VOICE_RADIO_TECH_CHANGED,
new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null)));
processAllMessages();
assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType());
}
private void switchToCdma() {
mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_IS95A);
mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_VOICE_RADIO_TECH_CHANGED,
new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_IS95A}, null)));
processAllMessages();
assertEquals(PhoneConstants.PHONE_TYPE_CDMA, mPhoneUT.getPhoneType());
}
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
doReturn(false).when(mSST).isDeviceShuttingDown();
mPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0,
PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory);
mPhoneUT.setVoiceCallSessionStats(mVoiceCallSessionStats);
ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mUiccController).registerForIccChanged(eq(mPhoneUT), integerArgumentCaptor.capture(),
nullable(Object.class));
Message msg = Message.obtain();
msg.what = integerArgumentCaptor.getValue();
mPhoneUT.sendMessage(msg);
processAllMessages();
}
@After
public void tearDown() throws Exception {
mPhoneUT.removeCallbacksAndMessages(null);
mPhoneUT = null;
super.tearDown();
}
@Test
@SmallTest
public void testPhoneTypeSwitch() {
assertTrue(mPhoneUT.isPhoneTypeGsm());
switchToCdma();
assertTrue(mPhoneUT.isPhoneTypeCdmaLte());
}
@Test
@SmallTest
public void testGetServiceState() {
ServiceState serviceState = new ServiceState();
mSST.mSS = serviceState;
assertEquals(serviceState, mPhoneUT.getServiceState());
}
@Test
@SmallTest
public void testGetMergedServiceState() throws Exception {
ServiceState imsServiceState = new ServiceState();
NetworkRegistrationInfo imsPsWwanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
NetworkRegistrationInfo imsPsWlanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
// Only PS states are tracked for IMS.
imsServiceState.addNetworkRegistrationInfo(imsPsWwanRegInfo);
imsServiceState.addNetworkRegistrationInfo(imsPsWlanRegInfo);
// Voice reg state in this case is whether or not IMS is registered.
imsServiceState.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
imsServiceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
imsServiceState.setIwlanPreferred(true);
doReturn(imsServiceState).when(mImsPhone).getServiceState();
replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
ServiceState serviceState = new ServiceState();
NetworkRegistrationInfo csWwanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
.build();
NetworkRegistrationInfo psWwanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
.build();
NetworkRegistrationInfo psWlanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
serviceState.addNetworkRegistrationInfo(csWwanRegInfo);
serviceState.addNetworkRegistrationInfo(psWwanRegInfo);
serviceState.addNetworkRegistrationInfo(psWlanRegInfo);
serviceState.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
serviceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
serviceState.setIwlanPreferred(true);
mSST.mSS = serviceState;
mPhoneUT.mSST = mSST;
ServiceState mergedServiceState = mPhoneUT.getServiceState();
assertEquals(ServiceState.STATE_IN_SERVICE, mergedServiceState.getState());
assertEquals(ServiceState.STATE_IN_SERVICE, mergedServiceState.getDataRegistrationState());
assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, mergedServiceState.getDataNetworkType());
}
/**
* Some vendors do not provide a voice registration for LTE when attached to LTE only (no CSFB
* available). In this case, we should still get IN_SERVICE for voice service state, since
* IMS is registered.
*/
@Test
@SmallTest
public void testGetMergedServiceStateNoCsfb() throws Exception {
ServiceState imsServiceState = new ServiceState();
NetworkRegistrationInfo imsPsWwanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
NetworkRegistrationInfo imsPsWlanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
.build();
// Only PS states are tracked for IMS.
imsServiceState.addNetworkRegistrationInfo(imsPsWwanRegInfo);
imsServiceState.addNetworkRegistrationInfo(imsPsWlanRegInfo);
// Voice reg state in this case is whether or not IMS is registered.
imsServiceState.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
imsServiceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
imsServiceState.setIwlanPreferred(true);
doReturn(imsServiceState).when(mImsPhone).getServiceState();
replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
ServiceState serviceState = new ServiceState();
NetworkRegistrationInfo csWwanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UNKNOWN)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
.build();
NetworkRegistrationInfo psWwanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
NetworkRegistrationInfo psWlanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
.setRegistrationState(
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
.build();
serviceState.addNetworkRegistrationInfo(csWwanRegInfo);
serviceState.addNetworkRegistrationInfo(psWwanRegInfo);
serviceState.addNetworkRegistrationInfo(psWlanRegInfo);
// No CSFB, voice is OOS for LTE only attach
serviceState.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
serviceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
serviceState.setIwlanPreferred(true);
mSST.mSS = serviceState;
mPhoneUT.mSST = mSST;
ServiceState mergedServiceState = mPhoneUT.getServiceState();
assertEquals(ServiceState.STATE_IN_SERVICE, mergedServiceState.getState());
assertEquals(ServiceState.STATE_IN_SERVICE, mergedServiceState.getDataRegistrationState());
assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mergedServiceState.getDataNetworkType());
}
@Test
@SmallTest
public void testGetSubscriberIdForGsmPhone() {
final String subscriberId = "123456789";
IccRecords iccRecords = Mockito.mock(IccRecords.class);
doReturn(subscriberId).when(iccRecords).getIMSI();
doReturn(iccRecords).when(mUiccController)
.getIccRecords(anyInt() /* phoneId */, eq(UiccController.APP_FAM_3GPP));
// Ensure the phone type is GSM
GsmCdmaPhone spyPhone = spy(mPhoneUT);
doReturn(false).when(spyPhone).isPhoneTypeCdma();
doReturn(false).when(spyPhone).isPhoneTypeCdmaLte();
doReturn(true).when(spyPhone).isPhoneTypeGsm();
assertEquals(subscriberId, spyPhone.getSubscriberId());
}
@Test
@SmallTest
public void testGetSubscriberIdForCdmaLtePhone() {
final String subscriberId = "abcdefghijk";
IccRecords iccRecords = Mockito.mock(IccRecords.class);
doReturn(subscriberId).when(iccRecords).getIMSI();
doReturn(iccRecords).when(mUiccController)
.getIccRecords(anyInt() /* phoneId */, eq(UiccController.APP_FAM_3GPP));
// Ensure the phone type is CdmaLte
GsmCdmaPhone spyPhone = spy(mPhoneUT);
doReturn(false).when(spyPhone).isPhoneTypeCdma();
doReturn(true).when(spyPhone).isPhoneTypeCdmaLte();
doReturn(false).when(spyPhone).isPhoneTypeGsm();
assertEquals(subscriberId, spyPhone.getSubscriberId());
}
@Test
@SmallTest
public void testGetSubscriberIdForCdmaPhone() {
final String subscriberId = "987654321";
doReturn(subscriberId).when(mSST).getImsi();
// Ensure the phone type is GSM
GsmCdmaPhone spyPhone = spy(mPhoneUT);
doReturn(true).when(spyPhone).isPhoneTypeCdma();
doReturn(false).when(spyPhone).isPhoneTypeCdmaLte();
doReturn(false).when(spyPhone).isPhoneTypeGsm();
assertEquals(subscriberId, spyPhone.getSubscriberId());
}
@Test
@SmallTest
public void testGetCellLocation() {
// GSM
CellIdentity cellLocation = new CellIdentityGsm();
WorkSource workSource = new WorkSource(Process.myUid(),
mContext.getPackageName());
doReturn(cellLocation).when(mSST).getCellIdentity();
assertEquals(cellLocation, mPhoneUT.getCellIdentity());
// Switch to CDMA
switchToCdma();
CellIdentityCdma cdmaCellLocation = new CellIdentityCdma();
doReturn(cdmaCellLocation).when(mSST).getCellIdentity();
CellIdentityCdma actualCellLocation =
(CellIdentityCdma) mPhoneUT.getCellIdentity();
assertEquals(actualCellLocation, cdmaCellLocation);
}
@Test
@SmallTest
public void testGetPhoneType() {
assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType());
// Switch to CDMA
switchToCdma();
assertEquals(PhoneConstants.PHONE_TYPE_CDMA, mPhoneUT.getPhoneType());
}
@Test
@SmallTest
public void testGetDataConnectionState() {
// There are several cases possible. Testing few of them for now.
// 1. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn != APN_TYPE_EMERGENCY
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSST).getCurrentDataConnectionState();
assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState(
PhoneConstants.APN_TYPE_ALL));
// 2. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY, apn
// not connected
doReturn(DctConstants.State.IDLE).when(mDcTracker).getState(
PhoneConstants.APN_TYPE_EMERGENCY);
assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState(
PhoneConstants.APN_TYPE_EMERGENCY));
// 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY,
// APN is connected, callTracker state = idle
doReturn(DctConstants.State.CONNECTED).when(mDcTracker).getState(
PhoneConstants.APN_TYPE_EMERGENCY);
mCT.mState = PhoneConstants.State.IDLE;
assertEquals(PhoneConstants.DataState.CONNECTED, mPhoneUT.getDataConnectionState(
PhoneConstants.APN_TYPE_EMERGENCY));
// 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY,
// APN enabled and CONNECTED, callTracker state != idle, !isConcurrentVoiceAndDataAllowed
mCT.mState = PhoneConstants.State.RINGING;
doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
assertEquals(PhoneConstants.DataState.SUSPENDED, mPhoneUT.getDataConnectionState(
PhoneConstants.APN_TYPE_EMERGENCY));
}
@Test
@SmallTest
public void testHandleInCallMmiCommands() {
try {
// Switch to CDMA
switchToCdma();
assertFalse(mPhoneUT.handleInCallMmiCommands("0"));
// Switch to GSM
switchToGsm();
mCT.mForegroundCall = mGsmCdmaCall;
mCT.mBackgroundCall = mGsmCdmaCall;
mCT.mRingingCall = mGsmCdmaCall;
doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState();
// !isInCall
assertFalse(mPhoneUT.handleInCallMmiCommands("0"));
// isInCall
doReturn(GsmCdmaCall.State.ACTIVE).when(mGsmCdmaCall).getState();
assertTrue(mPhoneUT.handleInCallMmiCommands("0"));
// empty dialString
assertFalse(mPhoneUT.handleInCallMmiCommands(""));
assertFalse(mPhoneUT.handleInCallMmiCommands(null));
} catch (Exception e) {
fail(e.toString());
}
}
@Test
@SmallTest
public void testDial() throws Exception {
try {
mSST.mSS = mServiceState;
doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
mCT.mForegroundCall = mGsmCdmaCall;
mCT.mBackgroundCall = mGsmCdmaCall;
mCT.mRingingCall = mGsmCdmaCall;
doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState();
replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
Connection connection = mPhoneUT.dial("1234567890",
new PhoneInternalInterface.DialArgs.Builder().build());
verify(mCT).dialGsm("1234567890", null, null);
} catch (CallStateException e) {
fail();
}
}
@Test
@SmallTest
public void testHandlePinMmi() {
assertFalse(mPhoneUT.handlePinMmi("1234567890"));
}
@Test
@SmallTest
public void testEmergencySmsMode() {
String emergencyNumber = "111";
String nonEmergencyNumber = "222";
int timeout = 200;
mContextFixture.getCarrierConfigBundle().putInt(
CarrierConfigManager.KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, timeout);
doReturn(true).when(mTelephonyManager).isEmergencyNumber(emergencyNumber);
mPhoneUT.notifySmsSent(nonEmergencyNumber);
processAllMessages();
assertFalse(mPhoneUT.isInEmergencySmsMode());
mPhoneUT.notifySmsSent(emergencyNumber);
processAllMessages();
assertTrue(mPhoneUT.isInEmergencySmsMode());
// mTimeLastEmergencySmsSentMs uses System.currentTimeMillis()
waitForMs(timeout + 5);
processAllMessages();
assertFalse(mPhoneUT.isInEmergencySmsMode());
// Feature not supported
mContextFixture.getCarrierConfigBundle().putInt(
CarrierConfigManager.KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0);
mPhoneUT.notifySmsSent(emergencyNumber);
processAllMessages();
assertFalse(mPhoneUT.isInEmergencySmsMode());
}
@Test
@SmallTest
public void testSendBurstDtmf() {
//Should do nothing for GSM
mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
anyInt(), nullable(Message.class));
switchToCdma();
//invalid character
mPhoneUT.sendBurstDtmf("12345a67890", 0, 0, null);
verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
anyInt(), nullable(Message.class));
//state IDLE
mCT.mState = PhoneConstants.State.IDLE;
mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
anyInt(), nullable(Message.class));
//state RINGING
mCT.mState = PhoneConstants.State.RINGING;
mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
anyInt(), nullable(Message.class));
mCT.mState = PhoneConstants.State.OFFHOOK;
mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
verify(mSimulatedCommandsVerifier).sendBurstDtmf("1234567890", 0, 0, null);
}
@Test
@SmallTest
public void testVoiceMailNumberGsm() {
String voiceMailNumber = "1234567890";
// first test for GSM
assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType());
// no resource or sharedPreference set -- should be null
assertEquals(null, mPhoneUT.getVoiceMailNumber());
// config_telephony_use_own_number_for_voicemail
mContextFixture.getCarrierConfigBundle()
.putBoolean(CarrierConfigManager
.KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL, true);
doReturn(voiceMailNumber).when(mSimRecords).getMsisdnNumber();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
// voicemail number from config
mContextFixture.getCarrierConfigBundle().
putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING, voiceMailNumber);
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
// voicemail number from config for roaming network
String voiceMailNumberForRoaming = "1234567892";
mContextFixture.getCarrierConfigBundle()
.putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_ROAMING_STRING,
voiceMailNumberForRoaming);
// voicemail number from config for roaming network and ims unregistered
String voiceMailNumberForImsRoamingAndUnregistered = "1234567893";
mContextFixture.getCarrierConfigBundle().putString(
CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING,
voiceMailNumberForImsRoamingAndUnregistered);
//Verify voicemail number for home
doReturn(false).when(mSST.mSS).getRoaming();
doReturn(true).when(mSST).isImsRegistered();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
//Move to ims condition, verify voicemail number for ims unregistered
doReturn(false).when(mSST).isImsRegistered();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
//Move to roaming condition, verify voicemail number for roaming
doReturn(true).when(mSST.mSS).getRoaming();
assertEquals(voiceMailNumberForImsRoamingAndUnregistered, mPhoneUT.getVoiceMailNumber());
//Move to ims condition, verify voicemail number for roaming
doReturn(true).when(mSST).isImsRegistered();
assertEquals(voiceMailNumberForRoaming, mPhoneUT.getVoiceMailNumber());
//Move to home condition, verify voicemail number for home
doReturn(false).when(mSST.mSS).getRoaming();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
// voicemail number that is explicitly set
voiceMailNumber = "1234567891";
mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null);
verify(mSimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber),
nullable(Message.class));
doReturn(voiceMailNumber).when(mSimRecords).getVoiceMailNumber();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
}
@Test
@SmallTest
public void testVoiceMailNumberCdma() {
switchToCdma();
String voiceMailNumber = "1234567890";
// config_telephony_use_own_number_for_voicemail
mContextFixture.getCarrierConfigBundle()
.putBoolean(CarrierConfigManager
.KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL, true);
doReturn(voiceMailNumber).when(mSST).getMdnNumber();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
// voicemail number from config
voiceMailNumber = "1234567891";
mContextFixture.getCarrierConfigBundle().
putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING, voiceMailNumber);
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
// voicemail number from config for roaming network
String voiceMailNumberForRoaming = "1234567892";
mContextFixture.getCarrierConfigBundle()
.putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_ROAMING_STRING,
voiceMailNumberForRoaming);
// voicemail number from config for roaming network and ims unregistered
String voiceMailNumberForImsRoamingAndUnregistered = "1234567893";
mContextFixture.getCarrierConfigBundle().putString(
CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING,
voiceMailNumberForImsRoamingAndUnregistered);
//Verify voicemail number for home
doReturn(false).when(mSST.mSS).getRoaming();
doReturn(true).when(mSST).isImsRegistered();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
//Move to ims condition, verify voicemail number for ims unregistered
doReturn(false).when(mSST).isImsRegistered();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
//Move to roaming condition, verify voicemail number for roaming
doReturn(true).when(mSST.mSS).getRoaming();
assertEquals(voiceMailNumberForImsRoamingAndUnregistered, mPhoneUT.getVoiceMailNumber());
//Move to ims condition, verify voicemail number for roaming
doReturn(true).when(mSST).isImsRegistered();
assertEquals(voiceMailNumberForRoaming, mPhoneUT.getVoiceMailNumber());
//Move to home condition, verify voicemail number for home
doReturn(false).when(mSST.mSS).getRoaming();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
// voicemail number from sharedPreference
voiceMailNumber = "1234567893";
mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null);
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
InOrder inOrder = inOrder(mSimRecords);
inOrder.verify(mSimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber),
messageArgumentCaptor.capture());
// SIM does not support voicemail number (IccVmNotSupportedException) so should be saved in
// shared pref
Message msg = messageArgumentCaptor.getValue();
AsyncResult.forMessage(msg).exception =
new IccVmNotSupportedException("setVoiceMailNumber not implemented");
msg.sendToTarget();
processAllMessages();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
// voicemail number from SIM
voiceMailNumber = "1234567894";
mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null);
messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
inOrder.verify(mSimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber),
messageArgumentCaptor.capture());
// successfully saved on SIM
msg = messageArgumentCaptor.getValue();
AsyncResult.forMessage(msg);
msg.sendToTarget();
processAllMessages();
doReturn(voiceMailNumber).when(mSimRecords).getVoiceMailNumber();
assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
}
@FlakyTest
@Test
@Ignore
public void testVoiceMailCount() {
// initial value
assertEquals(0, mPhoneUT.getVoiceMessageCount());
// old sharedPreference set (testing upgrade from M to N scenario)
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sharedPreferences.edit();
String imsi = "1234567890";
editor.putString("vm_id_key", imsi);
editor.putInt("vm_count_key", 5);
editor.apply();
doReturn(imsi).when(mSimRecords).getIMSI();
// updateVoiceMail should read old shared pref and delete it and new sharedPref should be
// updated now
doReturn(-1).when(mSimRecords).getVoiceMessageCount();
mPhoneUT.updateVoiceMail();
assertEquals(5, mPhoneUT.getVoiceMessageCount());
assertEquals(null, sharedPreferences.getString("vm_id_key", null));
assertEquals(5, sharedPreferences.getInt("vm_count_key" + mPhoneUT.getSubId(), 0));
// sim records return count as 0, that overrides shared preference
doReturn(0).when(mSimRecords).getVoiceMessageCount();
mPhoneUT.updateVoiceMail();
assertEquals(0, mPhoneUT.getVoiceMessageCount());
// sim records return count as -1
doReturn(-1).when(mSimRecords).getVoiceMessageCount();
mPhoneUT.updateVoiceMail();
assertEquals(-1, mPhoneUT.getVoiceMessageCount());
// sim records return count as -1 and sharedPreference says 0
mPhoneUT.setVoiceMessageCount(0);
mPhoneUT.updateVoiceMail();
assertEquals(-1, mPhoneUT.getVoiceMessageCount());
// sim records return count as -1 and sharedPreference says 2
mPhoneUT.setVoiceMessageCount(2);
mPhoneUT.updateVoiceMail();
assertEquals(2, mPhoneUT.getVoiceMessageCount());
// sim records return count as 0 and sharedPreference says 2
doReturn(0).when(mSimRecords).getVoiceMessageCount();
mPhoneUT.setVoiceMessageCount(2);
mPhoneUT.updateVoiceMail();
assertEquals(0, mPhoneUT.getVoiceMessageCount());
}
@Test
@SmallTest
public void testGetCallForwardingOption() {
// invalid reason (-1)
mPhoneUT.getCallForwardingOption(-1, null);
verify(mSimulatedCommandsVerifier, times(0)).queryCallForwardStatus(
anyInt(), anyInt(), nullable(String.class), nullable(Message.class));
// valid reason
String imsi = "1234567890";
doReturn(imsi).when(mSimRecords).getIMSI();
mPhoneUT.getCallForwardingOption(CF_REASON_UNCONDITIONAL, null);
verify(mSimulatedCommandsVerifier).queryCallForwardStatus(
eq(CF_REASON_UNCONDITIONAL), eq(CommandsInterface.SERVICE_CLASS_VOICE),
nullable(String.class), nullable(Message.class));
processAllMessages();
verify(mSimRecords).setVoiceCallForwardingFlag(anyInt(), anyBoolean(),
nullable(String.class));
// should have updated shared preferences
SharedPreferences sharedPreferences = PreferenceManager.
getDefaultSharedPreferences(mContext);
assertEquals(IccRecords.CALL_FORWARDING_STATUS_DISABLED,
sharedPreferences.getInt(Phone.CF_STATUS + mPhoneUT.getSubId(),
IccRecords.CALL_FORWARDING_STATUS_ENABLED));
// clean up
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(Phone.CF_STATUS + mPhoneUT.getSubId());
editor.apply();
}
@Test
@SmallTest
public void testSetCallForwardingOption() {
String cfNumber = "1234567890";
// invalid action
mPhoneUT.setCallForwardingOption(-1, CF_REASON_UNCONDITIONAL,
cfNumber, 0, null);
verify(mSimulatedCommandsVerifier, times(0)).setCallForward(anyInt(), anyInt(), anyInt(),
nullable(String.class), anyInt(), nullable(Message.class));
// valid action
mPhoneUT.setCallForwardingOption(CF_ACTION_ENABLE, CF_REASON_UNCONDITIONAL, cfNumber, 0,
null);
verify(mSimulatedCommandsVerifier).setCallForward(eq(CF_ACTION_ENABLE),
eq(CF_REASON_UNCONDITIONAL), anyInt(), eq(cfNumber), eq(0),
nullable(Message.class));
processAllMessages();
verify(mSimRecords).setVoiceCallForwardingFlag(anyInt(), anyBoolean(), eq(cfNumber));
}
/**
* GsmCdmaPhone handles a lot of messages. This function verifies behavior for messages that are
* received when obj is created and that are received on phone type switch
*/
@FlakyTest
@Ignore
@Test
@SmallTest
public void testHandleInitialMessages() {
// EVENT_RADIO_AVAILABLE
verify(mSimulatedCommandsVerifier).getBasebandVersion(nullable(Message.class));
verify(mSimulatedCommandsVerifier).getDeviceIdentity(nullable(Message.class));
verify(mSimulatedCommandsVerifier).getRadioCapability(nullable(Message.class));
// once as part of constructor, and once on radio available
verify(mSimulatedCommandsVerifier, times(2)).startLceService(anyInt(), anyBoolean(),
nullable(Message.class));
// EVENT_RADIO_ON
verify(mSimulatedCommandsVerifier).getVoiceRadioTechnology(nullable(Message.class));
verify(mSimulatedCommandsVerifier).setPreferredNetworkType(
eq(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA), nullable(Message.class));
// verify responses for above requests:
// baseband version
verify(mTelephonyManager).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()),
nullable(String.class));
// IMEI
assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei());
// IMEISV
assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn());
// radio capability
verify(mSimulatedCommandsVerifier).getNetworkSelectionMode(nullable(Message.class));
switchToCdma(); // this leads to eventRadioAvailable handling on cdma
// EVENT_RADIO_AVAILABLE
verify(mSimulatedCommandsVerifier, times(2)).getBasebandVersion(nullable(Message.class));
verify(mSimulatedCommandsVerifier, times(2)).getDeviceIdentity(nullable(Message.class));
verify(mSimulatedCommandsVerifier, times(3)).startLceService(anyInt(), anyBoolean(),
nullable(Message.class));
// EVENT_RADIO_ON
verify(mSimulatedCommandsVerifier, times(2)).getVoiceRadioTechnology(
nullable(Message.class));
// once on radio on, and once on get baseband version
verify(mSimulatedCommandsVerifier, times(3)).setPreferredNetworkType(
eq(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA), nullable(Message.class));
// verify responses for above requests:
// baseband version
verify(mTelephonyManager, times(2)).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()),
nullable(String.class));
// device identity
assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei());
assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn());
assertEquals(SimulatedCommands.FAKE_ESN, mPhoneUT.getEsn());
assertEquals(SimulatedCommands.FAKE_MEID, mPhoneUT.getMeid());
}
@Test
@SmallTest
public void testEmergencyCallbackMessages() throws Exception {
verify(mSimulatedCommandsVerifier).setEmergencyCallbackMode(eq(mPhoneUT), anyInt(),
nullable(Object.class));
verify(mSimulatedCommandsVerifier).registerForExitEmergencyCallbackMode(eq(mPhoneUT),
anyInt(), nullable(Object.class));
// verify handling of emergency callback mode
mSimulatedCommands.notifyEmergencyCallbackMode();
processAllMessages();
verifyEcbmIntentSent(1 /*times*/, true /*isInEcm*/);
assertTrue(mPhoneUT.isInEcm());
// verify that wakeLock is acquired in ECM
assertTrue(mPhoneUT.getWakeLock().isHeld());
mPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT, null);
mPhoneUT.registerForEmergencyCallToggle(mTestHandler, EVENT_EMERGENCY_CALL_TOGGLE, null);
// verify handling of emergency callback mode exit
mSimulatedCommands.notifyExitEmergencyCallbackMode();
processAllMessages();
verifyEcbmIntentSent(2 /*times*/, false /*isInEcm*/);
assertFalse(mPhoneUT.isInEcm());
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
// verify EcmExitRespRegistrant and mEmergencyCallToggledRegistrants are notified
verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
anyLong());
List<Message> msgList = messageArgumentCaptor.getAllValues();
assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, msgList.get(0).what);
assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
// verify setInternalDataEnabled
verify(mDataEnabledSettings).setInternalDataEnabled(true);
// verify wakeLock released
assertFalse(mPhoneUT.getWakeLock().isHeld());
}
private void verifyEcbmIntentSent(int times, boolean isInEcm) throws Exception {
ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeast(times)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
any());
Intent intent = intentArgumentCaptor.getValue();
assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
assertEquals(isInEcm, intent.getBooleanExtra(
TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
}
@Test
@SmallTest
public void testEcmCancelledPreservedThroughSrvcc() throws Exception {
replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
assertFalse(mPhoneUT.isEcmCanceledForEmergency());
// Set ECM cancelled state on ImsPhone to be transferred via migrateFrom
doReturn(true).when(mImsPhone).isEcmCanceledForEmergency();
verify(mSimulatedCommandsVerifier).registerForSrvccStateChanged(any(),
eq(EVENT_SRVCC_STATE_CHANGED), any());
// Start SRVCC
Message msg = Message.obtain();
msg.what = EVENT_SRVCC_STATE_CHANGED;
msg.obj = new AsyncResult(null, new int[]{TelephonyManager.SRVCC_STATE_HANDOVER_STARTED},
null);
mPhoneUT.sendMessage(msg);
processAllMessages();
// verify ECM cancelled is transferred correctly.
assertTrue(mPhoneUT.isEcmCanceledForEmergency());
}
@Test
@SmallTest
public void testModemResetInEmergencyCallbackMessages() {
verify(mSimulatedCommandsVerifier).setEmergencyCallbackMode(eq(mPhoneUT), anyInt(),
nullable(Object.class));
verify(mSimulatedCommandsVerifier).registerForModemReset(eq(mPhoneUT),
anyInt(), nullable(Object.class));
switchToCdma();
// verify handling of emergency callback mode
mSimulatedCommands.notifyEmergencyCallbackMode();
processAllMessages();
// verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
try {
verify(mContext, atLeast(1)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
any());
} catch (Exception e) {
fail("Unexpected exception: " + e.getStackTrace());
}
Intent intent = intentArgumentCaptor.getValue();
assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
assertEquals(true, intent.getBooleanExtra(
TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
assertEquals(true, mPhoneUT.isInEcm());
// verify that wakeLock is acquired in ECM
assertEquals(true, mPhoneUT.getWakeLock().isHeld());
mPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT, null);
mPhoneUT.registerForEmergencyCallToggle(mTestHandler, EVENT_EMERGENCY_CALL_TOGGLE, null);
// verify handling of emergency callback mode exit when modem resets
mSimulatedCommands.notifyModemReset();
processAllMessages();
// verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
try {
verify(mContext, atLeast(2)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
any());
} catch (Exception e) {
fail("Unexpected exception: " + e.getStackTrace());
}
intent = intentArgumentCaptor.getValue();
assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
assertEquals(false, intent.getBooleanExtra(
TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, true));
assertEquals(false, mPhoneUT.isInEcm());
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
// verify EcmExitRespRegistrant and mEmergencyCallToggledRegistrants are notified
verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
anyLong());
List<Message> msgList = messageArgumentCaptor.getAllValues();
assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, msgList.get(0).what);
assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
// verify setInternalDataEnabled
verify(mDataEnabledSettings).setInternalDataEnabled(true);
// verify wakeLock released
assertEquals(false, mPhoneUT.getWakeLock().isHeld());
}
@Test
@SmallTest
public void testCallForwardingIndicator() {
doReturn(IccRecords.CALL_FORWARDING_STATUS_UNKNOWN).when(mSimRecords).
getVoiceCallForwardingFlag();
// invalid subId
doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionController).
getSubIdUsingPhoneId(anyInt());
assertEquals(false, mPhoneUT.getCallForwardingIndicator());
// valid subId, sharedPreference not present
int subId1 = 0;
int subId2 = 1;
doReturn(subId1).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
assertEquals(false, mPhoneUT.getCallForwardingIndicator());
// old sharedPreference present
String imsi = "1234";
doReturn(imsi).when(mSimRecords).getIMSI();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sp.edit();
editor.putString(Phone.CF_ID, imsi);
editor.putInt(Phone.CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_ENABLED);
editor.apply();
assertEquals(true, mPhoneUT.getCallForwardingIndicator());
// old sharedPreference should be removed now
assertEquals(null, sp.getString(Phone.CF_ID, null));
assertEquals(IccRecords.CALL_FORWARDING_STATUS_UNKNOWN,
sp.getInt(Phone.CF_ID, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN));
// now verify value from new sharedPreference
assertEquals(true, mPhoneUT.getCallForwardingIndicator());
// check for another subId
doReturn(subId2).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
assertEquals(false, mPhoneUT.getCallForwardingIndicator());
// set value for the new subId in sharedPreference
editor.putInt(Phone.CF_STATUS + subId2, IccRecords.CALL_FORWARDING_STATUS_ENABLED);
editor.apply();
assertEquals(true, mPhoneUT.getCallForwardingIndicator());
// switching back to previous subId, stored value should still be available
doReturn(subId1).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
assertEquals(true, mPhoneUT.getCallForwardingIndicator());
// cleanup
editor.remove(Phone.CF_STATUS + subId1);
editor.remove(Phone.CF_STATUS + subId2);
editor.apply();
}
@Test
@SmallTest
public void testGetIccCardUnknownAndAbsent() {
// If UiccSlot.isStateUnknown is true, we should return a dummy IccCard with the state
// set to UNKNOWN
doReturn(null).when(mUiccController).getUiccProfileForPhone(anyInt());
UiccSlot mockSlot = mock(UiccSlot.class);
doReturn(mockSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
doReturn(true).when(mockSlot).isStateUnknown();
IccCard iccCard = mPhoneUT.getIccCard();
assertEquals(IccCardConstants.State.UNKNOWN, iccCard.getState());
// if isStateUnknown is false, we should return a dummy IccCard with the state set to
// ABSENT
doReturn(false).when(mockSlot).isStateUnknown();
iccCard = mPhoneUT.getIccCard();
assertEquals(IccCardConstants.State.ABSENT, iccCard.getState());
}
@Test
@SmallTest
public void testGetEmptyIccCard() {
doReturn(null).when(mUiccController).getUiccProfileForPhone(anyInt());
IccCard iccCard = mPhoneUT.getIccCard();
// The iccCard should be a dummy object, not null.
assertTrue(!(iccCard instanceof UiccProfile));
assertTrue(iccCard != null);
assertEquals(IccCardConstants.State.UNKNOWN, iccCard.getState());
assertEquals(null, iccCard.getIccRecords());
assertEquals(false, iccCard.getIccLockEnabled());
assertEquals(false, iccCard.getIccFdnEnabled());
assertEquals(false, iccCard.isApplicationOnIcc(
IccCardApplicationStatus.AppType.APPTYPE_SIM));
assertEquals(false, iccCard.hasIccCard());
assertEquals(false, iccCard.getIccPin2Blocked());
assertEquals(false, iccCard.getIccPuk2Blocked());
Message onComplete = mTestHandler.obtainMessage(EVENT_SET_ICC_LOCK_ENABLED);
iccCard.setIccLockEnabled(true, "password", onComplete);
processAllMessages();
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
// Verify that message is sent back with exception.
verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
anyLong());
Message message = messageArgumentCaptor.getAllValues().get(0);
AsyncResult ret = (AsyncResult) message.obj;
assertEquals(EVENT_SET_ICC_LOCK_ENABLED, message.what);
assertTrue(ret.exception != null);
}
@Test
@SmallTest
public void testGetCsCallRadioTech() {
ServiceState ss = new ServiceState();
mSST.mSS = ss;
// vrs in-service, vrat umts, expected umts
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UMTS)
.build();
ss.addNetworkRegistrationInfo(nri);
assertEquals(mPhoneUT.getCsCallRadioTech(), ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
// vrs oos, vrat umts, expected unknown
ss.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
assertEquals(mPhoneUT.getCsCallRadioTech(), ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
// vrs in-service, vrat lte, expected unknown
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
nri = new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.build();
ss.addNetworkRegistrationInfo(nri);
assertEquals(mPhoneUT.getCsCallRadioTech(), ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
}
@Test
@SmallTest
public void testGetLine1NumberForGsmPhone() {
final String msisdn = "+1234567890";
doReturn(msisdn).when(mSimRecords).getMsisdnNumber();
switchToGsm();
assertEquals(msisdn, mPhoneUT.getLine1Number());
}
@Test
@SmallTest
public void testGetLine1NumberForCdmaPhone() {
final String mdn = "1234567890";
final String msisdn = "+1234567890";
doReturn(mdn).when(mSST).getMdnNumber();
doReturn(msisdn).when(mSimRecords).getMsisdnNumber();
switchToCdma();
assertEquals(mdn, mPhoneUT.getLine1Number());
mContextFixture.getCarrierConfigBundle().putBoolean(
CarrierConfigManager.KEY_USE_USIM_BOOL, true);
assertEquals(msisdn, mPhoneUT.getLine1Number());
}
@Test
@SmallTest
public void testEnableUiccApplications() throws Exception {
mPhoneUT.mCi = mMockCi;
// UiccSlot is null. Doing nothing.
mPhoneUT.enableUiccApplications(true, null);
verify(mMockCi, never()).enableUiccApplications(anyBoolean(), any());
// Card state is not PRESENT. Doing nothing.
doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
doReturn(IccCardStatus.CardState.CARDSTATE_ABSENT).when(mUiccSlot).getCardState();
mPhoneUT.enableUiccApplications(true, null);
verify(mMockCi, never()).enableUiccApplications(anyBoolean(), any());
doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
Message message = Message.obtain();
mPhoneUT.enableUiccApplications(true, message);
verify(mMockCi).enableUiccApplications(eq(true), eq(message));
}
@Test
@SmallTest
public void testReapplyUiccApplicationEnablementNotNeeded() throws Exception {
mPhoneUT.mCi = mMockCi;
// UiccSlot is null, or not present, or mUiccApplicationsEnabled is not available, or IccId
// is not available, Doing nothing.
doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
Message.obtain(mPhoneUT, EVENT_ICC_CHANGED, null).sendToTarget();
processAllMessages();
doReturn(IccCardStatus.CardState.CARDSTATE_ABSENT).when(mUiccSlot).getCardState();
Message.obtain(mPhoneUT, EVENT_ICC_CHANGED, null).sendToTarget();
processAllMessages();
doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
Message.obtain(mPhoneUT, EVENT_ICC_CHANGED, null).sendToTarget();
Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
new AsyncResult(null, true, null)).sendToTarget();
processAllMessages();
verify(mSubscriptionController, never()).getSubInfoForIccId(any());
// Have IccId defined. But expected value and current value are the same. So no RIL command
// should be sent.
String iccId = "Fake iccId";
doReturn(iccId).when(mUiccSlot).getIccId();
Message.obtain(mPhoneUT, EVENT_ICC_CHANGED, null).sendToTarget();
processAllMessages();
verify(mSubscriptionController).getSubInfoForIccId(iccId);
verify(mMockCi, never()).enableUiccApplications(anyBoolean(), any());
}
@Test
@SmallTest
public void testReapplyUiccApplicationEnablementSuccess() throws Exception {
mPhoneUT.mCi = mMockCi;
// Set SIM to be present, with a fake iccId, and notify enablement being false.
doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
String iccId = "Fake iccId";
doReturn(iccId).when(mUiccSlot).getIccId();
Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
new AsyncResult(null, false, null)).sendToTarget();
processAllMessages();
// Should try to enable uicc applications as by default hey are expected to be true.
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(mMockCi, times(1)).enableUiccApplications(eq(true), messageCaptor.capture());
// Send message back with no exception.
AsyncResult.forMessage(messageCaptor.getValue(), null, null);
messageCaptor.getValue().sendToTarget();
processAllMessages();
// There shouldn't be any retry message.
moveTimeForward(5000);
processAllMessages();
verify(mMockCi, times(1)).enableUiccApplications(eq(true), any());
}
@Test
@SmallTest
public void testSetRadioPower() throws Exception {
mPhoneUT.setRadioPower(false);
verify(mSST).setRadioPower(false, false, false, false);
// Turn on radio for emergency call.
mPhoneUT.setRadioPower(true, true, false, true);
verify(mSST).setRadioPower(true, true, false, true);
}
@Test
@SmallTest
public void testReapplyUiccApplicationEnablementRetry() throws Exception {
mPhoneUT.mCi = mMockCi;
// Set SIM to be present, with a fake iccId, and notify enablement being false.
doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
String iccId = "Fake iccId";
doReturn(iccId).when(mUiccSlot).getIccId();
Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
new AsyncResult(null, false, null)).sendToTarget();
processAllMessages();
// Should try to enable uicc applications as by default hey are expected to be true.
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(mMockCi).enableUiccApplications(eq(true), messageCaptor.capture());
clearInvocations(mMockCi);
for (int i = 0; i < GsmCdmaPhone.ENABLE_UICC_APPS_MAX_RETRIES; i++) {
// Send message back with SIM_BUSY exception. Should retry.
AsyncResult.forMessage(messageCaptor.getValue(), null, new CommandException(
CommandException.Error.SIM_BUSY));
messageCaptor.getValue().sendToTarget();
processAllMessages();
// There should be a retry message.
moveTimeForward(5000);
processAllMessages();
verify(mMockCi).enableUiccApplications(eq(true), messageCaptor.capture());
clearInvocations(mMockCi);
}
// Reaches max retries. Should NOT retry.
AsyncResult.forMessage(messageCaptor.getValue(), null, new CommandException(
CommandException.Error.SIM_BUSY));
messageCaptor.getValue().sendToTarget();
processAllMessages();
// There should NOT be a retry message.
moveTimeForward(5000);
processAllMessages();
verify(mMockCi, never()).enableUiccApplications(eq(true), messageCaptor.capture());
clearInvocations(mMockCi);
}
@Test
@SmallTest
public void testSendUssdInService() throws Exception {
PhoneInternalInterface.DialArgs dialArgs = new PhoneInternalInterface.DialArgs
.Builder().setVideoState(VideoProfile.STATE_AUDIO_ONLY).build();
setupTestSendUssd(dialArgs);
// ServiceState is in service.
doReturn(ServiceState.STATE_IN_SERVICE).when(mSST.mSS).getState();
mPhoneUT.dial("*135#", dialArgs);
verify(mMockCi).sendUSSD(eq("*135#"), any());
}
@Test
@SmallTest
public void testSendUssdInOutOfService() throws Exception {
PhoneInternalInterface.DialArgs dialArgs = new PhoneInternalInterface.DialArgs
.Builder().setVideoState(VideoProfile.STATE_AUDIO_ONLY).build();
setupTestSendUssd(dialArgs);
// ServiceState is out of service
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSST.mSS)
.getState(); /* CS out of service */
doReturn(ServiceState.STATE_IN_SERVICE).when(mSST.mSS).getDataRegState();
doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_GSM).when(mSST.mSS)
.getRilDataRadioTechnology(); /* PS not in LTE */
mPhoneUT.dial("*135#", dialArgs);
verify(mMockCi).sendUSSD(eq("*135#"), any());
}
@Test
@SmallTest
public void testSendUssdInAirplaneMode() throws Exception {
PhoneInternalInterface.DialArgs dialArgs = new PhoneInternalInterface.DialArgs
.Builder().setVideoState(VideoProfile.STATE_AUDIO_ONLY).build();
setupTestSendUssd(dialArgs);
// ServiceState is airplane mode.
doReturn(ServiceState.STATE_POWER_OFF).when(mSST.mSS).getState(); /* CS POWER_OFF */
mPhoneUT.dial("*135#", dialArgs);
verify(mMockCi).sendUSSD(eq("*135#"), any());
}
private void setupTestSendUssd(PhoneInternalInterface.DialArgs dialArgs) throws Exception {
mPhoneUT.mCi = mMockCi;
ServiceState mImsServiceState = Mockito.mock(ServiceState.class);
CallStateException callStateException = Mockito.mock(CallStateException.class);
// Enable VoWiFi
doReturn(true).when(mImsManager).isVolteEnabledByPlatform();
doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
doReturn(mImsServiceState).when(mImsPhone).getServiceState();
doReturn(ServiceState.STATE_IN_SERVICE).when(mImsServiceState).getState();
doReturn(true).when(mImsPhone).isWifiCallingEnabled();
// Disable UT/XCAP
doReturn(false).when(mImsPhone).isUtEnabled();
// Throw CallStateException(Phone.CS_FALLBACK) from ImsPhone.dial().
doReturn(Phone.CS_FALLBACK).when(callStateException).getMessage();
doThrow(callStateException).when(mImsPhone).dial("*135#", dialArgs);
replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
}
}