blob: 7d9891d374d947bfbc3725215f707b37e2eb0263 [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.google.common.truth.Truth.assertThat;
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.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
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 static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.CellIdentity;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityNr;
import android.telephony.CellIdentityTdscdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.INetworkService;
import android.telephony.LteVopsSupportInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkService;
import android.telephony.NrVopsSupportInfo;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
import android.util.Pair;
import androidx.test.filters.FlakyTest;
import com.android.internal.R;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.metrics.ServiceStateStats;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
import com.android.internal.telephony.uicc.IccRecords;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
public class ServiceStateTrackerTest extends TelephonyTest {
// Mocked classes
private ProxyController mProxyController;
private Handler mTestHandler;
private NetworkService mIwlanNetworkService;
private INetworkService.Stub mIwlanNetworkServiceStub;
private SubscriptionInfo mSubInfo;
private ServiceStateStats mServiceStateStats;
private CellularNetworkService mCellularNetworkService;
// SST now delegates all signal strength operations to SSC
// Add Mock SSC as the dependency to avoid NPE
private SignalStrengthController mSsc;
private ServiceStateTracker sst;
private ServiceStateTrackerTestHandler mSSTTestHandler;
private PersistableBundle mBundle;
private static final int EVENT_REGISTERED_TO_NETWORK = 1;
private static final int EVENT_SUBSCRIPTION_INFO_READY = 2;
private static final int EVENT_DATA_ROAMING_ON = 3;
private static final int EVENT_DATA_ROAMING_OFF = 4;
private static final int EVENT_DATA_CONNECTION_ATTACHED = 5;
private static final int EVENT_DATA_CONNECTION_DETACHED = 6;
private static final int EVENT_DATA_RAT_CHANGED = 7;
private static final int EVENT_PS_RESTRICT_ENABLED = 8;
private static final int EVENT_PS_RESTRICT_DISABLED = 9;
private static final int EVENT_VOICE_ROAMING_ON = 10;
private static final int EVENT_VOICE_ROAMING_OFF = 11;
private static final int EVENT_VOICE_RAT_CHANGED = 12;
private static final int PHONE_ID = 0;
private static final String CARRIER_NAME_DISPLAY_NO_SERVICE = "No service";
private static final String CARRIER_NAME_DISPLAY_EMERGENCY_CALL = "emergency call";
private static final String WIFI_CALLING_VOICE_FORMAT = "%s wifi calling";
private static final String CROSS_SIM_CALLING_VOICE_FORMAT = "%s Cross-SIM Calling";
private static final String WIFI_CALLING_DATA_FORMAT = "%s wifi data";
private static final String WIFI_CALLING_FLIGHT_MODE_FORMAT = "%s flight mode";
private static final String[] WIFI_CALLING_FORMATTERS = {
WIFI_CALLING_VOICE_FORMAT,
WIFI_CALLING_DATA_FORMAT,
WIFI_CALLING_FLIGHT_MODE_FORMAT };
private static final String HOME_PLMN = "310260";
private static final String PLMN1 = "480123";
private static final String PLMN2 = "586111";
private static final String HOME_PNN = "home pnn";
private static final String[] CARRIER_CONFIG_SPDI = new String[] {HOME_PLMN, PLMN2};
private static final String[] CARRIER_CONFIG_EHPLMN = new String[] {HOME_PLMN, PLMN1};
private static final String[] CARRIER_CONFIG_PNN = new String[] {
String.format("%s,%s", HOME_PNN, "short"), "f2,s2"
};
private class ServiceStateTrackerTestHandler extends HandlerThread {
private ServiceStateTrackerTestHandler(String name) {
super(name);
}
@Override
public void onLooperPrepared() {
mSsc = new SignalStrengthController(mPhone);
doReturn(mSsc).when(mPhone).getSignalStrengthController();
sst = new ServiceStateTracker(mPhone, mSimulatedCommands);
sst.setServiceStateStats(mServiceStateStats);
doReturn(sst).when(mPhone).getServiceStateTracker();
setReady(true);
}
}
private void addNetworkService() {
mCellularNetworkService = new CellularNetworkService();
ServiceInfo CellularServiceInfo = new ServiceInfo();
CellularServiceInfo.packageName = "com.android.phone";
CellularServiceInfo.name = "CellularNetworkService";
CellularServiceInfo.permission = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
IntentFilter cellularIntentfilter = new IntentFilter();
mContextFixture.addService(
NetworkService.SERVICE_INTERFACE,
new ComponentName("com.android.phone",
"com.android.internal.telephony.CellularNetworkService"),
"com.android.phone",
mCellularNetworkService.mBinder,
CellularServiceInfo,
cellularIntentfilter);
ServiceInfo iwlanServiceInfo = new ServiceInfo();
iwlanServiceInfo.packageName = "com.xyz.iwlan.networkservice";
iwlanServiceInfo.name = "IwlanNetworkService";
iwlanServiceInfo.permission = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
IntentFilter iwlanIntentFilter = new IntentFilter();
mContextFixture.addService(
NetworkService.SERVICE_INTERFACE,
new ComponentName("com.xyz.iwlan.networkservice",
"com.xyz.iwlan.IwlanNetworkService"),
"com.xyz.iwlan.networkservice",
mIwlanNetworkServiceStub,
iwlanServiceInfo,
iwlanIntentFilter);
}
@Before
public void setUp() throws Exception {
logd("ServiceStateTrackerTest +Setup!");
super.setUp(getClass().getSimpleName());
mProxyController = Mockito.mock(ProxyController.class);
mTestHandler = Mockito.mock(Handler.class);
mIwlanNetworkService = Mockito.mock(NetworkService.class);
mIwlanNetworkServiceStub = Mockito.mock(INetworkService.Stub.class);
mSubInfo = Mockito.mock(SubscriptionInfo.class);
mServiceStateStats = Mockito.mock(ServiceStateStats.class);
mContextFixture.putResource(R.string.config_wwan_network_service_package,
"com.android.phone");
mContextFixture.putResource(R.string.config_wlan_network_service_package,
"com.xyz.iwlan.networkservice");
doReturn(mIwlanNetworkServiceStub).when(mIwlanNetworkServiceStub).asBinder();
addNetworkService();
doReturn(true).when(mDcTracker).areAllDataDisconnected();
doReturn(new ServiceState()).when(mPhone).getServiceState();
replaceInstance(ProxyController.class, "sProxyController", null, mProxyController);
mBundle = mContextFixture.getCarrierConfigBundle();
mBundle.putStringArray(
CarrierConfigManager.KEY_ROAMING_OPERATOR_STRING_ARRAY, new String[]{"123456"});
mBundle.putStringArray(
CarrierConfigManager.KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, new String[]{"123456"});
mBundle.putStringArray(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES,
// UMTS < GPRS < EDGE
new String[]{"3,1,2"});
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA);
doReturn(PHONE_ID).when(mPhone).getPhoneId();
int dds = SubscriptionManager.getDefaultDataSubscriptionId();
doReturn(dds).when(mPhone).getSubId();
doReturn(true).when(mPhone).areAllDataDisconnected();
doReturn(true).when(mPackageManager)
.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA);
mSSTTestHandler = new ServiceStateTrackerTestHandler(getClass().getSimpleName());
mSSTTestHandler.start();
waitUntilReady();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Override SPN related resource
mContextFixture.putResource(
com.android.internal.R.string.lockscreen_carrier_default,
CARRIER_NAME_DISPLAY_NO_SERVICE);
mContextFixture.putResource(
com.android.internal.R.string.emergency_calls_only,
CARRIER_NAME_DISPLAY_EMERGENCY_CALL);
mContextFixture.putStringArrayResource(
com.android.internal.R.array.wfcSpnFormats,
WIFI_CALLING_FORMATTERS);
// Start with power off delay disabled.
mContextFixture.putIntResource(
com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 0);
mBundle.putBoolean(
CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, true);
mBundle.putInt(CarrierConfigManager.KEY_WFC_SPN_FORMAT_IDX_INT, 0);
mBundle.putInt(CarrierConfigManager.KEY_WFC_DATA_SPN_FORMAT_IDX_INT, 1);
mBundle.putInt(CarrierConfigManager.KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT, 2);
// Show SPN is required when roaming
// Show PLMN is required when non-roaming.
doReturn(IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN
| IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN)
.when(mSimRecords).getCarrierNameDisplayCondition();
mBundle.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, "SPN from carrier config");
mBundle.putInt(CarrierConfigManager.KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT,
IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN
| IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN);
mBundle.putStringArray(CarrierConfigManager.KEY_SPDI_OVERRIDE_STRING_ARRAY,
CARRIER_CONFIG_SPDI);
mBundle.putStringArray(CarrierConfigManager.KEY_EHPLMN_OVERRIDE_STRING_ARRAY,
CARRIER_CONFIG_EHPLMN);
mBundle.putStringArray(CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY,
CARRIER_CONFIG_PNN);
// Do not force display "No service" when sim is not ready in any locales
mContextFixture.putStringArrayResource(
com.android.internal.R.array.config_display_no_service_when_sim_unready,
new String[0]);
mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
new int[] {
-110, /* SIGNAL_STRENGTH_POOR */
-90, /* SIGNAL_STRENGTH_MODERATE */
-80, /* SIGNAL_STRENGTH_GOOD */
-65, /* SIGNAL_STRENGTH_GREAT */
});
mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY,
new int[] {
-31, /* SIGNAL_STRENGTH_POOR */
-19, /* SIGNAL_STRENGTH_MODERATE */
-7, /* SIGNAL_STRENGTH_GOOD */
6 /* SIGNAL_STRENGTH_GREAT */
});
mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY,
new int[] {
-5, /* SIGNAL_STRENGTH_POOR */
5, /* SIGNAL_STRENGTH_MODERATE */
15, /* SIGNAL_STRENGTH_GOOD */
30 /* SIGNAL_STRENGTH_GREAT */
});
Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
mContext.sendBroadcast(intent);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
logd("ServiceStateTrackerTest -Setup!");
}
@After
public void tearDown() throws Exception {
sst.removeCallbacksAndMessages(null);
sst = null;
mSSTTestHandler.quit();
mSSTTestHandler.join();
mSSTTestHandler = null;
if (mCellularNetworkService != null) {
mCellularNetworkService.onDestroy();
mCellularNetworkService = null;
}
mSsc = null;
mBundle = null;
super.tearDown();
}
private static String getPlmnFromCellIdentity(final CellIdentity ci) {
if (ci == null || ci instanceof CellIdentityCdma) return "";
final String mcc = ci.getMccString();
final String mnc = ci.getMncString();
if (TextUtils.isEmpty(mcc) || TextUtils.isEmpty(mnc)) return "";
return mcc + mnc;
}
@Test
@MediumTest
public void testSetRadioPower() {
boolean oldState = (mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
sst.setRadioPower(!oldState);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(oldState
!= (mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON));
}
@Test
@SmallTest
public void testSetRadioPowerOnForEmergencyCall() {
// Turn off radio first.
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
// Turn on radio for emergency call.
sst.setRadioPower(true, true, true, false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.mSetRadioPowerForEmergencyCall);
assertTrue(mSimulatedCommands.mSetRadioPowerAsSelectedPhoneForEmergencyCall);
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
// If we try again without forceApply=true, no command should be sent to modem. Because
// radio power is already ON.
sst.setRadioPower(true, false, false, false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.mSetRadioPowerForEmergencyCall);
assertTrue(mSimulatedCommands.mSetRadioPowerAsSelectedPhoneForEmergencyCall);
// Call setRadioPower on with forceApply=true. ForEmergencyCall and isSelectedPhone should
// be cleared.
sst.setRadioPower(true, false, false, true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(mSimulatedCommands.mSetRadioPowerForEmergencyCall);
assertFalse(mSimulatedCommands.mSetRadioPowerAsSelectedPhoneForEmergencyCall);
}
@Test
@MediumTest
public void testSetRadioPowerForReason() {
// Radio does not turn on if off for other reason and not emergency call.
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
assertTrue(sst.getRadioPowerOffReasons().isEmpty());
sst.setRadioPowerForReason(false, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
assertTrue(sst.getRadioPowerOffReasons().size() == 1);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
sst.setRadioPowerForReason(true, false, false, false, Phone.RADIO_POWER_REASON_USER);
assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
assertTrue(sst.getRadioPowerOffReasons().size() == 1);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
// Radio power state reason is removed and radio turns on if turned on for same reason it
// had been turned off for.
sst.setRadioPowerForReason(true, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
assertTrue(sst.getRadioPowerOffReasons().isEmpty());
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
// Turn radio off, then successfully turn radio on for emergency call.
sst.setRadioPowerForReason(false, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
assertTrue(sst.getRadioPowerOffReasons().size() == 1);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
sst.setRadioPower(true, true, true, false);
assertTrue(sst.getRadioPowerOffReasons().isEmpty());
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
}
@Test
@MediumTest
public void testSetRadioPowerFromCarrier() {
// Carrier disable radio power
sst.setRadioPowerFromCarrier(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(mSimulatedCommands.getRadioState()
== TelephonyManager.RADIO_POWER_ON);
assertTrue(sst.getDesiredPowerState());
assertFalse(sst.getPowerStateFromCarrier());
// User toggle radio power will not overrides carrier settings
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(mSimulatedCommands.getRadioState()
== TelephonyManager.RADIO_POWER_ON);
assertTrue(sst.getDesiredPowerState());
assertFalse(sst.getPowerStateFromCarrier());
// Carrier re-enable radio power
sst.setRadioPowerFromCarrier(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
assertTrue(sst.getDesiredPowerState());
assertTrue(sst.getPowerStateFromCarrier());
// User toggle radio power off (airplane mode) and set carrier on
sst.setRadioPower(false);
sst.setRadioPowerFromCarrier(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(mSimulatedCommands.getRadioState()
== TelephonyManager.RADIO_POWER_ON);
assertFalse(sst.getDesiredPowerState());
assertTrue(sst.getPowerStateFromCarrier());
}
@Test
@MediumTest
public void testRilTrafficAfterSetRadioPower() {
sst.setRadioPower(true);
final int getOperatorCallCount = mSimulatedCommands.getGetOperatorCallCount();
final int getDataRegistrationStateCallCount =
mSimulatedCommands.getGetDataRegistrationStateCallCount();
final int getVoiceRegistrationStateCallCount =
mSimulatedCommands.getGetVoiceRegistrationStateCallCount();
final int getNetworkSelectionModeCallCount =
mSimulatedCommands.getGetNetworkSelectionModeCallCount();
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.pollState();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// This test was meant to be for *no* ril traffic. However, RADIO_STATE_CHANGED is
// considered a modem triggered action and that causes a pollState() to be done
assertEquals(getOperatorCallCount + 1, mSimulatedCommands.getGetOperatorCallCount());
assertEquals(getDataRegistrationStateCallCount + 1,
mSimulatedCommands.getGetDataRegistrationStateCallCount());
assertEquals(getVoiceRegistrationStateCallCount + 1,
mSimulatedCommands.getGetVoiceRegistrationStateCallCount());
assertEquals(getNetworkSelectionModeCallCount + 1,
mSimulatedCommands.getGetNetworkSelectionModeCallCount());
// Note that if the poll is triggered by a network change notification
// and the modem is supposed to be off, we should still do the poll
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(getOperatorCallCount + 2 , mSimulatedCommands.getGetOperatorCallCount());
assertEquals(getDataRegistrationStateCallCount + 2,
mSimulatedCommands.getGetDataRegistrationStateCallCount());
assertEquals(getVoiceRegistrationStateCallCount + 2,
mSimulatedCommands.getGetVoiceRegistrationStateCallCount());
assertEquals(getNetworkSelectionModeCallCount + 2,
mSimulatedCommands.getGetNetworkSelectionModeCallCount());
}
@FlakyTest
@Ignore
@Test
@MediumTest
public void testSpnUpdateShowPlmnOnly() {
doReturn(0).when(mSimRecords).getCarrierNameDisplayCondition();
doReturn(IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN).
when(mUiccCardApplication3gpp).getState();
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_NETWORK_STATE_CHANGED, null));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContextFixture.getTestDouble(), times(3))
.sendStickyBroadcastAsUser(intentArgumentCaptor.capture(), eq(UserHandle.ALL));
// We only want to verify the intent SERVICE_PROVIDERS_UPDATED.
List<Intent> intents = intentArgumentCaptor.getAllValues();
logd("Total " + intents.size() + " intents");
for (Intent intent : intents) {
logd(" " + intent.getAction());
}
Intent intent = intents.get(2);
assertEquals(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED, intent.getAction());
Bundle b = intent.getExtras();
// For boolean we need to make sure the key exists first
assertTrue(b.containsKey(TelephonyManager.EXTRA_SHOW_SPN));
assertFalse(b.getBoolean(TelephonyManager.EXTRA_SHOW_SPN));
assertEquals(null, b.getString(TelephonyManager.EXTRA_SPN));
assertEquals(null, b.getString(TelephonyManager.EXTRA_DATA_SPN));
// For boolean we need to make sure the key exists first
assertTrue(b.containsKey(TelephonyManager.EXTRA_SHOW_PLMN));
assertTrue(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN));
assertEquals(SimulatedCommands.FAKE_LONG_NAME, b.getString(TelephonyManager.EXTRA_PLMN));
ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mTelephonyManager).setDataNetworkTypeForPhone(anyInt(), intArgumentCaptor.capture());
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA,
intArgumentCaptor.getValue().intValue());
}
private CellInfoGsm getCellInfoGsm() {
CellInfoGsm tmp = new CellInfoGsm();
tmp.setCellIdentity(new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst",
Collections.emptyList()));
tmp.setCellSignalStrength(new CellSignalStrengthGsm(-85, 2, 3));
return tmp;
}
@Test
@MediumTest
public void testCachedCellInfoList() {
ArrayList<CellInfo> list = new ArrayList();
list.add(getCellInfoGsm());
mSimulatedCommands.setCellInfoList(list);
WorkSource workSource = new WorkSource(Process.myUid(),
mContext.getPackageName());
// null worksource and no response message will update the writethrough cache
sst.requestAllCellInfo(null, null);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(sst.getAllCellInfo(), list);
}
private static class CellInfoHandler extends Handler {
// Need to define this here so that it's accessible
public List<CellInfo> cellInfoResult;
CellInfoHandler(Looper l) {
super(l);
}
@Override
public void handleMessage(Message msg) {
synchronized (msg) {
assertTrue("handler received null message", msg.obj != null);
AsyncResult ar = (AsyncResult) msg.obj;
cellInfoResult = (List<CellInfo>) ar.result;
msg.notifyAll();
}
}
}
@Test
@MediumTest
public void testGetCellInfoResponse() throws InterruptedException {
mSimulatedCommands.setCellInfoListBehavior(true);
ArrayList<CellInfo> list = new ArrayList();
list.add(getCellInfoGsm());
mSimulatedCommands.setCellInfoList(list);
CellInfoHandler cih = new CellInfoHandler(mSSTTestHandler.getLooper());
Message rsp = cih.obtainMessage(0x7357);
sst.requestAllCellInfo(null, rsp);
synchronized (rsp) {
if (cih.cellInfoResult == null) rsp.wait(5000);
}
AsyncResult ar = (AsyncResult) rsp.obj;
assertTrue("CellInfo Response Not Received", cih.cellInfoResult != null);
assertEquals(getCellInfoGsm(), cih.cellInfoResult.get(0));
}
@Test
@MediumTest
public void testGetCellInfoResponseTimeout() throws InterruptedException {
mSimulatedCommands.setCellInfoListBehavior(false);
CellInfoHandler cih = new CellInfoHandler(mSSTTestHandler.getLooper());
Message rsp = cih.obtainMessage(0x7357);
sst.requestAllCellInfo(null, rsp);
synchronized (rsp) {
if (cih.cellInfoResult == null) rsp.wait(5000);
}
assertTrue("Spurious CellInfo Response Received", cih.cellInfoResult == null);
}
@Test
@MediumTest
public void testImsRegState() {
// Simulate IMS registered
mSimulatedCommands.setImsRegistrationState(new int[]{1, PhoneConstants.PHONE_TYPE_GSM});
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_IMS_STATE_CHANGED, null));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(sst.isImsRegistered());
// Simulate IMS unregistered
mSimulatedCommands.setImsRegistrationState(new int[]{0, PhoneConstants.PHONE_TYPE_GSM});
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_IMS_STATE_CHANGED, null));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(sst.isImsRegistered());
}
@Test
public void testOnImsServiceStateChanged() {
// The service state of GsmCdmaPhone is STATE_OUT_OF_SERVICE, and IMS is unregistered.
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
sst.mSS = ss;
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_IMS_SERVICE_STATE_CHANGED));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// The listener will be notified that the service state was changed.
verify(mPhone).notifyServiceStateChanged(any(ServiceState.class));
// The service state of GsmCdmaPhone is STATE_IN_SERVICE, and IMS is registered.
ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
sst.mSS = ss;
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_IMS_SERVICE_STATE_CHANGED));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Nothing happened because the IMS service state was not affected the merged service state.
verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
}
private void sendCarrierConfigUpdate() {
CarrierConfigManager mockConfigManager = Mockito.mock(CarrierConfigManager.class);
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
.thenReturn(mockConfigManager);
when(mockConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
Intent intent = new Intent().setAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, PHONE_ID);
mContext.sendBroadcast(intent);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
}
@Test
@MediumTest
// TODO(nharold): we probably should remove support for this procedure (GET_LOC)
public void testGsmCellLocation() {
CellIdentityGsm cellIdentityGsm = new CellIdentityGsm(
2, 3, 900, 5, "001", "01", "test", "tst", Collections.emptyList());
NetworkRegistrationInfo result = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setCellIdentity(cellIdentityGsm)
.setRegisteredPlmn("00101")
.build();
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_GET_LOC_DONE,
new AsyncResult(null, result, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
WorkSource workSource = new WorkSource(Process.myUid(), mContext.getPackageName());
GsmCellLocation cl = (GsmCellLocation) sst.getCellIdentity().asCellLocation();
assertEquals(2, cl.getLac());
assertEquals(3, cl.getCid());
}
@FlakyTest /* flakes 0.86% of the time */
@Test
@MediumTest
// TODO(nharold): we probably should remove support for this procedure (GET_LOC)
public void testCdmaCellLocation() {
CellIdentityCdma cellIdentityCdma = new CellIdentityCdma(1, 2, 3, 4, 5, "test", "tst");
NetworkRegistrationInfo result = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setCellIdentity(cellIdentityCdma)
.build();
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_GET_LOC_DONE,
new AsyncResult(null, result, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
WorkSource workSource = new WorkSource(Process.myUid(), mContext.getPackageName());
CdmaCellLocation cl = (CdmaCellLocation) sst.getCellIdentity().asCellLocation();
assertEquals(5, cl.getBaseStationLatitude());
assertEquals(4, cl.getBaseStationLongitude());
}
@Test
public void testHasLocationChanged() {
CellIdentityCdma cellIdentity = null;
CellIdentityCdma newCellIdentity = null;
boolean hasLocationChanged = (cellIdentity == null ? newCellIdentity != null
: !cellIdentity.isSameCell(newCellIdentity));
assertFalse(hasLocationChanged);
cellIdentity = new CellIdentityCdma(1, 2, 3, 4, 5, "test", "tst");
hasLocationChanged = (cellIdentity == null ? newCellIdentity != null
: !cellIdentity.isSameCell(newCellIdentity));
assertTrue(hasLocationChanged);
newCellIdentity = new CellIdentityCdma(1, 2, 3, 4, 5, "test", "tst");
hasLocationChanged = (cellIdentity == null ? newCellIdentity != null
: !cellIdentity.isSameCell(newCellIdentity));
assertFalse(hasLocationChanged);
}
@Test
@MediumTest
public void testUpdatePhoneType() {
doReturn(false).when(mPhone).isPhoneTypeGsm();
doReturn(true).when(mPhone).isPhoneTypeCdmaLte();
doReturn(CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM).when(mCdmaSSM).
getCdmaSubscriptionSource();
logd("Calling updatePhoneType");
// switch to CDMA
sst.updatePhoneType();
ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mRuimRecords).registerForRecordsLoaded(eq(sst), integerArgumentCaptor.capture(),
nullable(Object.class));
// response for mRuimRecords.registerForRecordsLoaded()
Message msg = Message.obtain();
msg.what = integerArgumentCaptor.getValue();
msg.obj = new AsyncResult(null, null, null);
sst.sendMessage(msg);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// on RUIM_RECORDS_LOADED, sst is expected to call following apis
verify(mRuimRecords, times(1)).isProvisioned();
// switch back to GSM
doReturn(true).when(mPhone).isPhoneTypeGsm();
doReturn(false).when(mPhone).isPhoneTypeCdmaLte();
// response for mRuimRecords.registerForRecordsLoaded() can be sent after switching to GSM
msg = Message.obtain();
msg.what = integerArgumentCaptor.getValue();
msg.obj = new AsyncResult(null, null, null);
sst.sendMessage(msg);
// There's no easy way to check if the msg was handled or discarded. Wait to make sure sst
// did not crash, and then verify that the functions called records loaded are not called
// again
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
verify(mRuimRecords, times(1)).isProvisioned();
}
@Test
@MediumTest
public void testRegAndUnregForVoiceRoamingOn() throws Exception {
sst.registerForVoiceRoamingOn(mTestHandler, EVENT_DATA_ROAMING_ON, null);
// Enable roaming and trigger events to notify handler registered
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_ROAMING_ON, messageArgumentCaptor.getValue().what);
// Disable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForVoiceRoamingOn(mTestHandler);
// Enable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegAndUnregForVoiceRoamingOff() throws Exception {
// Enable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForVoiceRoamingOff(mTestHandler, EVENT_DATA_ROAMING_OFF, null);
// Disable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_ROAMING_OFF, messageArgumentCaptor.getValue().what);
// Enable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForVoiceRoamingOff(mTestHandler);
// Disable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegAndUnregForDataRoamingOn() throws Exception {
sst.registerForDataRoamingOn(mTestHandler, EVENT_DATA_ROAMING_ON, null);
// Enable roaming and trigger events to notify handler registered
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_ROAMING_ON, messageArgumentCaptor.getValue().what);
// Disable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForDataRoamingOn(mTestHandler);
// Enable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegAndUnregForDataRoamingOff() throws Exception {
// Enable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForDataRoamingOff(mTestHandler, EVENT_DATA_ROAMING_OFF, null, true);
// Disable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_ROAMING_OFF, messageArgumentCaptor.getValue().what);
// Enable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForDataRoamingOff(mTestHandler);
// Disable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegAndInvalidregForDataConnAttach() throws Exception {
// Initially set service state out of service
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(23);
mSimulatedCommands.setDataRegState(23);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
// set service state in service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_CONNECTION_ATTACHED, messageArgumentCaptor.getValue().what);
// set service state out of service
mSimulatedCommands.setVoiceRegState(-1);
mSimulatedCommands.setDataRegState(-1);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegAndUnregForDataConnAttach() throws Exception {
// Initially set service state out of service
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
// set service state in service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_CONNECTION_ATTACHED, messageArgumentCaptor.getValue().what);
// set service state out of service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegAndUnregForDataConnDetach() throws Exception {
// Initially set service state in service
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
sst.registerForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
// set service state out of service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_CONNECTION_DETACHED, messageArgumentCaptor.getValue().what);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler);
// set service state out of service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegisterForVoiceRegStateOrRatChange() {
NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.build();
sst.mSS.addNetworkRegistrationInfo(nri);
sst.registerForVoiceRegStateOrRatChanged(mTestHandler, EVENT_VOICE_RAT_CHANGED, null);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Verify if message was posted to handler and value of result
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_VOICE_RAT_CHANGED, messageArgumentCaptor.getValue().what);
assertEquals(new Pair<Integer, Integer>(ServiceState.STATE_IN_SERVICE,
ServiceState.RIL_RADIO_TECHNOLOGY_LTE),
((AsyncResult)messageArgumentCaptor.getValue().obj).result);
}
@Test
@MediumTest
public void testRegisterForDataRegStateOrRatChange() {
NetworkRegistrationInfo nrs = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
sst.mSS.addNetworkRegistrationInfo(nrs);
sst.registerForDataRegStateOrRatChanged(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler, EVENT_DATA_RAT_CHANGED, null);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Verify if message was posted to handler and value of result
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_RAT_CHANGED, messageArgumentCaptor.getValue().what);
assertEquals(new Pair<Integer, Integer>(ServiceState.STATE_IN_SERVICE,
ServiceState.RIL_RADIO_TECHNOLOGY_LTE),
((AsyncResult)messageArgumentCaptor.getValue().obj).result);
}
@FlakyTest /* flakes 0.43% of the time */
@Test
@MediumTest
public void testRegAndUnregForNetworkAttached() throws Exception {
// Initially set service state out of service
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForNetworkAttached(mTestHandler, EVENT_REGISTERED_TO_NETWORK, null);
// set service state in service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_REGISTERED_TO_NETWORK, messageArgumentCaptor.getValue().what);
// set service state out of service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForNetworkAttached(mTestHandler);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify that no new message posted to handler
verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
}
@Test
@MediumTest
public void testRegAndInvalidRegForNetworkAttached() throws Exception {
// Initially set service state out of service
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(23);
mSimulatedCommands.setDataRegState(23);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForNetworkAttached(mTestHandler, EVENT_REGISTERED_TO_NETWORK, null);
// set service state in service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_REGISTERED_TO_NETWORK, messageArgumentCaptor.getValue().what);
// set service state out of service
mSimulatedCommands.setVoiceRegState(-1);
mSimulatedCommands.setDataRegState(-1);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Unregister registrant
sst.unregisterForNetworkAttached(mTestHandler);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForNetworkAttached(mTestHandler, EVENT_REGISTERED_TO_NETWORK, null);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify if registered handler has message posted to it
messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
anyLong());
assertEquals(EVENT_REGISTERED_TO_NETWORK, messageArgumentCaptor.getValue().what);
}
@Test
@MediumTest
public void testRegisterForPsRestrictedEnabled() throws Exception {
sst.mRestrictedState.setPsRestricted(true);
// Since PsRestricted is set to true, registerForPsRestrictedEnabled will
// also post message to handler
sst.registerForPsRestrictedEnabled(mTestHandler, EVENT_PS_RESTRICT_ENABLED, null);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify posted message
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_PS_RESTRICT_ENABLED, messageArgumentCaptor.getValue().what);
}
@Test
@MediumTest
public void testRegisterForPsRestrictedDisabled() throws Exception {
sst.mRestrictedState.setPsRestricted(true);
// Since PsRestricted is set to true, registerForPsRestrictedDisabled will
// also post message to handler
sst.registerForPsRestrictedDisabled(mTestHandler, EVENT_PS_RESTRICT_DISABLED, null);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify posted message
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_PS_RESTRICT_DISABLED, messageArgumentCaptor.getValue().what);
}
@Test
@MediumTest
public void testOnRestrictedStateChanged() throws Exception {
ServiceStateTracker spySst = spy(sst);
doReturn(true).when(mPhone).isPhoneTypeGsm();
doReturn(IccCardApplicationStatus.AppState.APPSTATE_READY).when(
mUiccCardApplication3gpp).getState();
ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mSimulatedCommandsVerifier).setOnRestrictedStateChanged(any(Handler.class),
intArgumentCaptor.capture(), eq(null));
// Since spy() creates a copy of sst object we need to call
// setOnRestrictedStateChanged() explicitly.
mSimulatedCommands.setOnRestrictedStateChanged(spySst,
intArgumentCaptor.getValue().intValue(), null);
// Combination of restricted state and expected notification type.
final int CS_ALL[] = {RILConstants.RIL_RESTRICTED_STATE_CS_ALL,
ServiceStateTracker.CS_ENABLED};
final int CS_NOR[] = {RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL,
ServiceStateTracker.CS_NORMAL_ENABLED};
final int CS_EME[] = {RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY,
ServiceStateTracker.CS_EMERGENCY_ENABLED};
final int CS_NON[] = {RILConstants.RIL_RESTRICTED_STATE_NONE,
ServiceStateTracker.CS_DISABLED};
final int PS_ALL[] = {RILConstants.RIL_RESTRICTED_STATE_PS_ALL,
ServiceStateTracker.PS_ENABLED};
final int PS_NON[] = {RILConstants.RIL_RESTRICTED_STATE_NONE,
ServiceStateTracker.PS_DISABLED};
int notifyCount = 0;
// cs not restricted -> cs emergency/normal restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_ALL);
// cs emergency/normal restricted -> cs normal restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_NOR);
// cs normal restricted -> cs emergency restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_EME);
// cs emergency restricted -> cs not restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_NON);
// cs not restricted -> cs normal restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_NOR);
// cs normal restricted -> cs emergency/normal restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_ALL);
// cs emergency/normal restricted -> cs emergency restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_EME);
// cs emergency restricted -> cs emergency/normal restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_ALL);
// cs emergency/normal restricted -> cs not restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_NON);
// cs not restricted -> cs emergency restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_EME);
// cs emergency restricted -> cs normal restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_NOR);
// cs normal restricted -> cs not restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, CS_NON);
// ps not restricted -> ps restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, PS_ALL);
// ps restricted -> ps not restricted
internalCheckForRestrictedStateChange(spySst, ++notifyCount, PS_NON);
}
private void internalCheckForRestrictedStateChange(ServiceStateTracker serviceStateTracker,
int times, int[] restrictedState) {
mSimulatedCommands.triggerRestrictedStateChanged(restrictedState[0]);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(serviceStateTracker, times(times)).setNotification(intArgumentCaptor.capture());
assertEquals(intArgumentCaptor.getValue().intValue(), restrictedState[1]);
}
private boolean notificationHasTitleSet(Notification n) {
// Notification has no methods to check the actual title, but #toString() includes the
// word "tick" if the title is set so we check this as a workaround
return n.toString().contains("tick");
}
private String getNotificationTitle(Notification n) {
return n.extras.getString(Notification.EXTRA_TITLE);
}
@Test
@SmallTest
public void testSetPsNotifications() {
int subId = 1;
sst.mSubId = subId;
doReturn(subId).when(mSubInfo).getSubscriptionId();
doReturn(mSubInfo).when(mSubscriptionController).getActiveSubscriptionInfo(
anyInt(), anyString(), nullable(String.class));
final NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mContextFixture.putBooleanResource(
R.bool.config_user_notification_of_restrictied_mobile_access, true);
doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
Drawable mockDrawable = Mockito.mock(Drawable.class);
Resources mockResources = mContext.getResources();
when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
mContextFixture.putResource(com.android.internal.R.string.RestrictedOnDataTitle, "test1");
sst.setNotification(ServiceStateTracker.PS_ENABLED);
ArgumentCaptor<Notification> notificationArgumentCaptor =
ArgumentCaptor.forClass(Notification.class);
verify(nm).notify(anyString(), anyInt(), notificationArgumentCaptor.capture());
// if the postedNotification has title set then it must have been the correct notification
Notification postedNotification = notificationArgumentCaptor.getValue();
assertTrue(notificationHasTitleSet(postedNotification));
assertEquals("test1", getNotificationTitle(postedNotification));
sst.setNotification(ServiceStateTracker.PS_DISABLED);
verify(nm).cancel(Integer.toString(sst.mSubId), ServiceStateTracker.PS_NOTIFICATION);
}
@Test
@SmallTest
public void testSetCsNotifications() {
int subId = 1;
sst.mSubId = subId;
doReturn(subId).when(mSubInfo).getSubscriptionId();
doReturn(mSubInfo).when(mSubscriptionController)
.getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
final NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mContextFixture.putBooleanResource(
R.bool.config_user_notification_of_restrictied_mobile_access, true);
doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
Drawable mockDrawable = Mockito.mock(Drawable.class);
Resources mockResources = mContext.getResources();
when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
mContextFixture.putResource(com.android.internal.R.string.RestrictedOnAllVoiceTitle,
"test2");
sst.setNotification(ServiceStateTracker.CS_ENABLED);
ArgumentCaptor<Notification> notificationArgumentCaptor =
ArgumentCaptor.forClass(Notification.class);
verify(nm).notify(anyString(), anyInt(), notificationArgumentCaptor.capture());
// if the postedNotification has title set then it must have been the correct notification
Notification postedNotification = notificationArgumentCaptor.getValue();
assertTrue(notificationHasTitleSet(postedNotification));
assertEquals("test2", getNotificationTitle(postedNotification));
sst.setNotification(ServiceStateTracker.CS_DISABLED);
verify(nm).cancel(Integer.toString(sst.mSubId), ServiceStateTracker.CS_NOTIFICATION);
}
@Test
@SmallTest
public void testSetCsNormalNotifications() {
int subId = 1;
sst.mSubId = subId;
doReturn(subId).when(mSubInfo).getSubscriptionId();
doReturn(mSubInfo).when(mSubscriptionController)
.getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
final NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mContextFixture.putBooleanResource(
R.bool.config_user_notification_of_restrictied_mobile_access, true);
doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
Drawable mockDrawable = Mockito.mock(Drawable.class);
Resources mockResources = mContext.getResources();
when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
mContextFixture.putResource(com.android.internal.R.string.RestrictedOnNormalTitle, "test3");
sst.setNotification(ServiceStateTracker.CS_NORMAL_ENABLED);
ArgumentCaptor<Notification> notificationArgumentCaptor =
ArgumentCaptor.forClass(Notification.class);
verify(nm).notify(anyString(), anyInt(), notificationArgumentCaptor.capture());
// if the postedNotification has title set then it must have been the correct notification
Notification postedNotification = notificationArgumentCaptor.getValue();
assertTrue(notificationHasTitleSet(postedNotification));
assertEquals("test3", getNotificationTitle(postedNotification));
sst.setNotification(ServiceStateTracker.CS_DISABLED);
verify(nm).cancel(Integer.toString(sst.mSubId), ServiceStateTracker.CS_NOTIFICATION);
}
@Test
@SmallTest
public void testSetCsEmergencyNotifications() {
int subId = 1;
sst.mSubId = subId;
doReturn(subId).when(mSubInfo).getSubscriptionId();
doReturn(mSubInfo).when(mSubscriptionController)
.getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
final NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mContextFixture.putBooleanResource(
R.bool.config_user_notification_of_restrictied_mobile_access, true);
doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
Drawable mockDrawable = Mockito.mock(Drawable.class);
Resources mockResources = mContext.getResources();
when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
mContextFixture.putResource(com.android.internal.R.string.RestrictedOnEmergencyTitle,
"test4");
sst.setNotification(ServiceStateTracker.CS_EMERGENCY_ENABLED);
ArgumentCaptor<Notification> notificationArgumentCaptor =
ArgumentCaptor.forClass(Notification.class);
verify(nm).notify(anyString(), anyInt(), notificationArgumentCaptor.capture());
// if the postedNotification has title set then it must have been the correct notification
Notification postedNotification = notificationArgumentCaptor.getValue();
assertTrue(notificationHasTitleSet(postedNotification));
assertEquals("test4", getNotificationTitle(postedNotification));
sst.setNotification(ServiceStateTracker.CS_DISABLED);
verify(nm).cancel(Integer.toString(sst.mSubId), ServiceStateTracker.CS_NOTIFICATION);
sst.setNotification(ServiceStateTracker.CS_REJECT_CAUSE_ENABLED);
}
@Test
@SmallTest
public void testSetNotificationsForGroupedSubs() {
//if subscription is grouped, no notification should be set whatsoever
int subId = 1;
int otherSubId = 2;
sst.mSubId = otherSubId;
doReturn(subId).when(mSubInfo).getSubscriptionId();
final NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mContextFixture.putBooleanResource(
R.bool.config_user_notification_of_restrictied_mobile_access, true);
doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
Drawable mockDrawable = Mockito.mock(Drawable.class);
Resources mockResources = mContext.getResources();
when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
mContextFixture.putResource(com.android.internal.R.string.RestrictedOnDataTitle, "test1");
sst.setNotification(ServiceStateTracker.EVENT_NETWORK_STATE_CHANGED);
ArgumentCaptor<Notification> notificationArgumentCaptor =
ArgumentCaptor.forClass(Notification.class);
verify(nm, never()).notify(anyString(), anyInt(), notificationArgumentCaptor.capture());
sst.setNotification(ServiceStateTracker.PS_DISABLED);
verify(nm, never()).cancel(Integer.toString(sst.mSubId),
ServiceStateTracker.PS_NOTIFICATION);
}
@Test
@MediumTest
public void testRegisterForSubscriptionInfoReady() {
sst.registerForSubscriptionInfoReady(mTestHandler, EVENT_SUBSCRIPTION_INFO_READY, null);
// Call functions which would trigger posting of message on test handler
doReturn(false).when(mPhone).isPhoneTypeGsm();
sst.updatePhoneType();
mSimulatedCommands.notifyOtaProvisionStatusChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// verify posted message
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_SUBSCRIPTION_INFO_READY, messageArgumentCaptor.getValue().what);
}
@Test
@MediumTest
public void testRoamingPhoneTypeSwitch() {
// Enable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.registerForDataRoamingOff(mTestHandler, EVENT_DATA_ROAMING_OFF, null, true);
sst.registerForVoiceRoamingOff(mTestHandler, EVENT_VOICE_ROAMING_OFF, null);
sst.registerForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
// Call functions which would trigger posting of message on test handler
doReturn(false).when(mPhone).isPhoneTypeGsm();
sst.updatePhoneType();
// verify if registered handler has message posted to it
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler, atLeast(3)).sendMessageAtTime(
messageArgumentCaptor.capture(), anyLong());
HashSet<Integer> messageSet = new HashSet<>();
for (Message m : messageArgumentCaptor.getAllValues()) {
messageSet.add(m.what);
}
assertTrue(messageSet.contains(EVENT_DATA_ROAMING_OFF));
assertTrue(messageSet.contains(EVENT_VOICE_ROAMING_OFF));
assertTrue(messageSet.contains(EVENT_DATA_CONNECTION_DETACHED));
}
@Test
@SmallTest
public void testGetDesiredPowerState() {
sst.setRadioPower(true);
assertEquals(sst.getDesiredPowerState(), true);
}
@Test
@SmallTest
public void testGetCurrentDataRegState() throws Exception {
sst.mSS.setDataRegState(ServiceState.STATE_OUT_OF_SERVICE);
assertEquals(sst.getCurrentDataConnectionState(), ServiceState.STATE_OUT_OF_SERVICE);
}
@Test
@SmallTest
public void testIsConcurrentVoiceAndDataAllowed() {
doReturn(false).when(mPhone).isPhoneTypeGsm();
sst.mSS.setCssIndicator(1);
assertEquals(true, sst.isConcurrentVoiceAndDataAllowed());
sst.mSS.setCssIndicator(0);
assertEquals(false, sst.isConcurrentVoiceAndDataAllowed());
doReturn(true).when(mPhone).isPhoneTypeGsm();
NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_HSPA)
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.build();
sst.mSS.addNetworkRegistrationInfo(nri);
assertEquals(true, sst.isConcurrentVoiceAndDataAllowed());
nri = new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_GPRS)
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.build();
sst.mSS.addNetworkRegistrationInfo(nri);
assertEquals(false, sst.isConcurrentVoiceAndDataAllowed());
sst.mSS.setCssIndicator(1);
assertEquals(true, sst.isConcurrentVoiceAndDataAllowed());
}
@Test
@MediumTest
public void testIsImsRegistered() throws Exception {
mSimulatedCommands.setImsRegistrationState(new int[]{1, PhoneConstants.PHONE_TYPE_GSM});
mSimulatedCommands.notifyImsNetworkStateChanged();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(sst.isImsRegistered(), true);
}
@Test
@SmallTest
public void testIsDeviceShuttingDown() throws Exception {
sst.requestShutdown();
assertEquals(true, sst.isDeviceShuttingDown());
}
@Test
@SmallTest
public void testShuttingDownRequest() throws Exception {
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.requestShutdown();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(mSimulatedCommands.getRadioState()
!= TelephonyManager.RADIO_POWER_UNAVAILABLE);
}
@Test
@SmallTest
public void testShuttingDownRequestWithRadioPowerFailResponse() throws Exception {
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Simulate RIL fails the radio power settings.
mSimulatedCommands.setRadioPowerFailResponse(true);
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
sst.requestShutdown();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(mSimulatedCommands.getRadioState()
!= TelephonyManager.RADIO_POWER_UNAVAILABLE);
}
@Test
@SmallTest
public void testSetImsRegisteredStateRunsShutdownImmediately() throws Exception {
doReturn(true).when(mPhone).isPhoneTypeGsm();
sst.setImsRegistrationState(true);
mSimulatedCommands.setRadioPowerFailResponse(false);
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
sst.requestShutdown();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.setImsRegistrationState(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_UNAVAILABLE, mSimulatedCommands.getRadioState());
}
@Test
@SmallTest
public void testImsRegisteredDelayShutDown() throws Exception {
doReturn(false).when(mPhone).isUsingNewDataStack();
doReturn(true).when(mPhone).isPhoneTypeGsm();
mContextFixture.putIntResource(
com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
sst.setImsRegistrationState(true);
mSimulatedCommands.setRadioPowerFailResponse(false);
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Turn off the radio and ensure radio power is still on
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
// Now set IMS reg state to false and ensure we see the modem move to power off.
sst.setImsRegistrationState(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
}
@Test
@SmallTest
public void testImsRegisteredNoDelayShutDown() throws Exception {
doReturn(true).when(mPhone).isPhoneTypeGsm();
// The radio power off delay time is 0, so there should should be no delay.
sst.setImsRegistrationState(true);
mSimulatedCommands.setRadioPowerFailResponse(false);
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Turn off the radio and ensure radio power is off
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
}
@Test
@SmallTest
public void testImsRegisteredDelayShutDownTimeout() throws Exception {
doReturn(false).when(mPhone).isUsingNewDataStack();
doReturn(true).when(mPhone).isPhoneTypeGsm();
mContextFixture.putIntResource(
com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
sst.setImsRegistrationState(true);
mSimulatedCommands.setRadioPowerFailResponse(false);
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Turn off the radio and ensure radio power is still on
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
// Ensure that if we never turn deregister for IMS, we still eventually see radio state
// move to off.
// Timeout for IMS reg + some extra time to remove race conditions
waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(),
sst.getRadioPowerOffDelayTimeoutForImsRegistration() + 1000, 1000);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
}
@Test
@SmallTest
public void testImsRegisteredAPMOnOffToggle() throws Exception {
doReturn(true).when(mPhone).isPhoneTypeGsm();
mContextFixture.putIntResource(
com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
sst.setImsRegistrationState(true);
mSimulatedCommands.setRadioPowerFailResponse(false);
sst.setRadioPower(true);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// Turn off the radio and ensure radio power is still on and then turn it back on again
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.setRadioPower(true);
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
// Ensure the timeout was cancelled and we still see radio power is on.
// Timeout for IMS reg + some extra time to remove race conditions
waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(),
sst.getRadioPowerOffDelayTimeoutForImsRegistration() + 1000, 1000);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
}
@Test
@SmallTest
public void testSetTimeFromNITZStr_withoutAge() throws Exception {
{
// Mock sending incorrect nitz str from RIL
mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0");
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
}
{
// Mock sending correct nitz str from RIL with a zero ageMs
String nitzStr = "15/06/20,00:00:00+0";
NitzData expectedNitzData = NitzData.parse(nitzStr);
mSimulatedCommands.triggerNITZupdate(nitzStr);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
ArgumentCaptor<NitzSignal> argumentsCaptor =
ArgumentCaptor.forClass(NitzSignal.class);
verify(mNitzStateMachine, times(1))
.handleNitzReceived(argumentsCaptor.capture());
// Confirm the argument was what we expected.
NitzSignal actualNitzSignal = argumentsCaptor.getValue();
assertEquals(expectedNitzData, actualNitzSignal.getNitzData());
assertTrue(actualNitzSignal.getReceiptElapsedRealtimeMillis()
<= SystemClock.elapsedRealtime());
assertEquals(actualNitzSignal.getAgeMillis(), 0);
}
}
@Test
@SmallTest
public void testSetTimeFromNITZStr_withAge() throws Exception {
{
// Mock sending incorrect nitz str from RIL with a non-zero ageMs
long ageMs = 60 * 1000;
mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0", ageMs);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
}
{
// Mock sending correct nitz str from RIL with a non-zero ageMs
String nitzStr = "21/08/15,00:00:00+0";
long ageMs = 60 * 1000;
NitzData expectedNitzData = NitzData.parse(nitzStr);
mSimulatedCommands.triggerNITZupdate(nitzStr, ageMs);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
ArgumentCaptor<NitzSignal> argumentsCaptor =
ArgumentCaptor.forClass(NitzSignal.class);
verify(mNitzStateMachine, times(1))
.handleNitzReceived(argumentsCaptor.capture());
// Confirm the argument was what we expected.
NitzSignal actualNitzSignal = argumentsCaptor.getValue();
assertEquals(expectedNitzData, actualNitzSignal.getNitzData());
assertTrue(actualNitzSignal.getReceiptElapsedRealtimeMillis()
<= SystemClock.elapsedRealtime());
assertEquals(actualNitzSignal.getAgeMillis(), ageMs);
}
}
private void changeRegState(int state, CellIdentity cid, int rat) {
changeRegState(state, cid, rat, rat);
}
private void changeRegState(int state, CellIdentity cid, int voiceRat, int dataRat) {
LteVopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
state, dataRat, 0, false, null, cid, getPlmnFromCellIdentity(cid),
1, false, false, false, lteVopsSupportInfo);
sst.mPollingContext[0] = 2;
// update data reg state to be in service
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
state, voiceRat, 0, false,
null, cid, getPlmnFromCellIdentity(cid), false, 0, 0, 0);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
}
private void changeRegStateWithIwlan(int state, CellIdentity cid, int voiceRat, int dataRat,
int iwlanState, int iwlanDataRat) {
LteVopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
sst.mPollingContext[0] = 3;
// PS WWAN
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
state, dataRat, 0, false, null, cid, getPlmnFromCellIdentity(cid),
1, false, false, false, lteVopsSupportInfo);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// CS WWAN
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
state, voiceRat, 0, false, null, cid, getPlmnFromCellIdentity(cid), false, 0, 0, 0);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
// PS WLAN
NetworkRegistrationInfo dataIwlanResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
iwlanState, iwlanDataRat, 0, false,
null, null, "", 1, false, false, false, lteVopsSupportInfo);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_IWLAN_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataIwlanResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
}
@Test
public void testPollStateOperatorWhileNotRegistered() {
final String[] oldOpNamesResult = new String[] { "Old carrier long", "Old carrier", "" };
final String[] badOpNamesResult = null;
sst.mPollingContext[0] = 1;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_OPERATOR,
new AsyncResult(sst.mPollingContext, oldOpNamesResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(oldOpNamesResult[0], sst.getServiceState().getOperatorAlpha());
// if the device is not registered, the modem returns an invalid operator
sst.mPollingContext[0] = 1;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_OPERATOR,
new AsyncResult(sst.mPollingContext, badOpNamesResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(null, sst.getServiceState().getOperatorAlpha());
}
@Test
public void testCSEmergencyRegistrationState() throws Exception {
CellIdentityGsm cellIdentity =
new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst",
Collections.emptyList());
NetworkRegistrationInfo dataReg = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
0, 16, 0, false, null, cellIdentity, getPlmnFromCellIdentity(cellIdentity),
1, false, false, false, null);
NetworkRegistrationInfo voiceReg = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
0, 16, 0, true, null, cellIdentity, getPlmnFromCellIdentity(cellIdentity),
false, 0, 0, 0);
sst.mPollingContext[0] = 2;
// update data reg state to be in oos
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataReg, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceReg, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(sst.mSS.isEmergencyOnly());
}
@Test
public void testPSEmergencyRegistrationState() throws Exception {
CellIdentityGsm cellIdentity =
new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst",
Collections.emptyList());
NetworkRegistrationInfo dataReg = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
0, 16, 0, true, null, cellIdentity, getPlmnFromCellIdentity(cellIdentity),
1, false, false, false, null);
NetworkRegistrationInfo voiceReg = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
0, 16, 0, false, null, cellIdentity, getPlmnFromCellIdentity(cellIdentity),
false, 0, 0, 0);
sst.mPollingContext[0] = 2;
// update data reg state to be in oos
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataReg, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceReg, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(sst.mSS.isEmergencyOnly());
}
// Edge and GPRS are grouped under the same family and Edge has higher rate than GPRS.
// Expect no rat update when move from E to G.
@Test
public void testRatRatchet() throws Exception {
CellIdentityGsm cellIdentity =
new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst",
Collections.emptyList());
// start on GPRS
changeRegState(1, cellIdentity, 16, 1);
assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilDataRadioTechnology());
// upgrade to EDGE
changeRegState(1, cellIdentity, 16, 2);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
// drop back to GPRS and expect a ratchet
changeRegState(1, cellIdentity, 16, 1);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
}
// Edge and GPRS are grouped under the same family and Edge has higher rate than GPRS.
// Bypass rat rachet when cell id changed. Expect rat update from E to G
@Test
public void testRatRatchetWithCellChange() throws Exception {
CellIdentityGsm cellIdentity =
new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst",
Collections.emptyList());
// update data reg state to be in service
changeRegState(1, cellIdentity, 16, 2);
assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GSM, sst.mSS.getRilVoiceRadioTechnology());
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
// RAT: EDGE -> GPRS cell ID: 1 -> 2
cellIdentity = new CellIdentityGsm(0, 2, 900, 5, "001", "01", "test", "tst",
Collections.emptyList());
changeRegState(1, cellIdentity, 16, 1);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilDataRadioTechnology());
}
private void sendPhyChanConfigChange(int[] bandwidths, int networkType, int pci,
int[][] contextIDs) {
ArrayList<PhysicalChannelConfig> pc = new ArrayList<>();
int ssType = PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING;
for (int i = 0; i < bandwidths.length; i++) {
pc.add(new PhysicalChannelConfig.Builder()
.setCellConnectionStatus(ssType)
.setCellBandwidthDownlinkKhz(bandwidths[i])
.setContextIds(contextIDs != null ? contextIDs[i] : new int[0])
.setNetworkType(networkType)
.setBand(1)
.setPhysicalCellId(pci)
.build());
// All cells after the first are secondary serving cells.
ssType = PhysicalChannelConfig.CONNECTION_SECONDARY_SERVING;
}
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_PHYSICAL_CHANNEL_CONFIG,
new AsyncResult(null, pc, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
}
private void sendPhyChanConfigChange(int[] bandwidths, int networkType, int pci) {
sendPhyChanConfigChange(bandwidths, networkType, pci, null);
}
private void sendRegStateUpdateForLteCellId(CellIdentityLte cellId) {
LteVopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE,
0, false, null, cellId, getPlmnFromCellIdentity(cellId), 1, false, false, false,
lteVopsSupportInfo);
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE,
0, false, null, cellId, getPlmnFromCellIdentity(cellId), false, 0, 0, 0);
sst.mPollingContext[0] = 2;
// update data reg state to be in service
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
}
private void sendRegStateUpdateForNrCellId(CellIdentityNr cellId) {
LteVopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_NR,
0, false, null, cellId, getPlmnFromCellIdentity(cellId), 1, false, false, false,
lteVopsSupportInfo);
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_NR,
0, false, null, cellId, getPlmnFromCellIdentity(cellId), false, 0, 0, 0);
sst.mPollingContext[0] = 2;
// update data reg state to be in service
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
}
private void sendRegStateUpdateForLteOnOos() throws Exception {
LteVopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, "", 1, false, false,
false, lteVopsSupportInfo);
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, "", false, 0, 0, 0);
sst.mPollingContext[0] = 2;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
}
@Test
public void testPhyChanBandwidthUpdatedOnDataRegState() throws Exception {
// Cell ID change should trigger hasLocationChanged.
CellIdentityLte cellIdentity5 =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
"tst", Collections.emptyList(), null);
sendPhyChanConfigChange(new int[] {10000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
sendRegStateUpdateForLteCellId(cellIdentity5);
assertTrue(Arrays.equals(new int[] {5000}, sst.mSS.getCellBandwidths()));
}
@Test
public void testPhyChanBandwidthNotUpdatedWhenInvalidInCellIdentity() throws Exception {
// Cell ID change should trigger hasLocationChanged.
CellIdentityLte cellIdentityInv =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 12345, "001", "01", "test",
"tst", Collections.emptyList(), null);
sendPhyChanConfigChange(new int[] {10000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
sendRegStateUpdateForLteCellId(cellIdentityInv);
assertTrue(Arrays.equals(new int[] {10000}, sst.mSS.getCellBandwidths()));
}
@Test
public void testPhyChanBandwidthPrefersCarrierAggregationReport() throws Exception {
// Cell ID change should trigger hasLocationChanged.
CellIdentityLte cellIdentity10 =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 10000, "001", "01", "test",
"tst", Collections.emptyList(), null);
sendPhyChanConfigChange(new int[] {10000, 5000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
sendRegStateUpdateForLteCellId(cellIdentity10);
assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
}
@Test
public void testPhyChanBandwidthRatchetedOnPhyChanBandwidth() throws Exception {
// LTE Cell with bandwidth = 10000
CellIdentityLte cellIdentity10 =
new CellIdentityLte(1, 1, 1, 1, new int[] {1, 2}, 10000, "1", "1", "test",
"tst", Collections.emptyList(), null);
sendRegStateUpdateForLteCellId(cellIdentity10);
assertTrue(Arrays.equals(new int[] {10000}, sst.mSS.getCellBandwidths()));
sendPhyChanConfigChange(new int[] {10000, 5000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
}
@Test
public void testUpdateNrFrequencyRangeFromPhysicalChannelConfigs() {
when(mPhone.getDataNetworkController().isInternetNetwork(eq(3))).thenReturn(true);
sendPhyChanConfigChange(new int[] {1000, 500}, TelephonyManager.NETWORK_TYPE_NR, 1,
new int[][]{{0, 1}, {2, 3}});
assertEquals(ServiceState.FREQUENCY_RANGE_MID, sst.mSS.getNrFrequencyRange());
}
@Test
public void testPhyChanBandwidthResetsOnOos() throws Exception {
testPhyChanBandwidthRatchetedOnPhyChanBandwidth();
LteVopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, "", 1, false, false,
false, lteVopsSupportInfo);
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, "", false, 0, 0, 0);
sst.mPollingContext[0] = 2;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(0, sst.mSS.getCellBandwidths().length);
}
@Test
public void testPhyChanBandwidthForNr() {
// NR Cell with bandwidth = 10000
CellIdentityNr nrCi = new CellIdentityNr(
0, 0, 0, new int[] {}, "", "", 5, "", "", Collections.emptyList());
sendPhyChanConfigChange(new int[] {10000, 5000}, TelephonyManager.NETWORK_TYPE_NR, 0);
sendRegStateUpdateForNrCellId(nrCi);
assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
}
/**
* Ensure that TransportManager changes due to transport preference changes are picked up in the
* new ServiceState when a poll event occurs. This causes ServiceState#getRilDataRadioTechnology
* to change even though the underlying transports have not changed state.
*/
@SmallTest
@Test
public void testRilDataTechnologyChangeTransportPreference() {
when(mAccessNetworksManager.isAnyApnOnIwlan()).thenReturn(false);
// Start state: Cell data only LTE + IWLAN
CellIdentityLte cellIdentity =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
"tst", Collections.emptyList(), null);
changeRegStateWithIwlan(
// WWAN
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, cellIdentity,
TelephonyManager.NETWORK_TYPE_UNKNOWN, TelephonyManager.NETWORK_TYPE_LTE,
// WLAN
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
TelephonyManager.NETWORK_TYPE_IWLAN);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_LTE, sst.mSS.getRilDataRadioTechnology());
sst.registerForDataRegStateOrRatChanged(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
mTestHandler, EVENT_DATA_RAT_CHANGED, null);
// transport preference change for a PDN for IWLAN occurred, no registration change, but
// trigger unrelated poll to pick up transport preference.
when(mAccessNetworksManager.isAnyApnOnIwlan()).thenReturn(true);
changeRegStateWithIwlan(
// WWAN
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, cellIdentity,
TelephonyManager.NETWORK_TYPE_UNKNOWN, TelephonyManager.NETWORK_TYPE_LTE,
// WLAN
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
TelephonyManager.NETWORK_TYPE_IWLAN);
// Now check to make sure a transport independent notification occurred for the registrants.
// There will be two, one when the registration happened and another when the transport
// preference changed.
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
anyLong());
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, sst.mSS.getRilDataRadioTechnology());
}
@Test
public void testGetServiceProviderNameWithBrandOverride() {
String brandOverride = "spn from brand override";
doReturn(brandOverride).when(mUiccProfile).getOperatorBrandOverride();
assertThat(sst.getServiceProviderName()).isEqualTo(brandOverride);
}
@Test
public void testGetServiceProviderNameWithCarrierConfigOverride() {
String carrierOverride = "spn from carrier override";
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, true);
mBundle.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, carrierOverride);
assertThat(sst.getServiceProviderName()).isEqualTo(carrierOverride);
}
@Test
public void testGetServiceProviderNameWithSimRecord() {
String spn = "spn from sim record";
doReturn(spn).when(mSimRecords).getServiceProviderName();
assertThat(sst.getServiceProviderName()).isEqualTo(spn);
}
@Test
public void testGetServiceProviderNameWithAllSource() {
String brandOverride = "spn from brand override";
doReturn(brandOverride).when(mUiccProfile).getOperatorBrandOverride();
String carrierOverride = "spn from carrier override";
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, true);
mBundle.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, carrierOverride);
String spn = "spn from sim record";
doReturn(spn).when(mSimRecords).getServiceProviderName();
// Operator brand override has highest priority
assertThat(sst.getServiceProviderName()).isEqualTo(brandOverride);
// Remove the brand override
doReturn(null).when(mUiccProfile).getOperatorBrandOverride();
// Carrier config override has 2nd priority
assertThat(sst.getServiceProviderName()).isEqualTo(carrierOverride);
// Remove the carrier config override
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
// SPN from sim has lowest priority
assertThat(sst.getServiceProviderName()).isEqualTo(spn);
}
@Test
public void testGetCarrierNameDisplayConditionWithBrandOverride() {
String brandOverride = "spn from brand override";
doReturn(brandOverride).when(mUiccProfile).getOperatorBrandOverride();
// Only show spn because all PLMNs will be considered HOME PLMNs.
assertThat(sst.getCarrierNameDisplayBitmask(new ServiceState())).isEqualTo(
ServiceStateTracker.CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN);
}
@Test
@SmallTest
public void testGetMdn() throws Exception {
doReturn(false).when(mPhone).isPhoneTypeGsm();
doReturn(false).when(mPhone).isPhoneTypeCdma();
doReturn(true).when(mPhone).isPhoneTypeCdmaLte();
doReturn(CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM).when(mCdmaSSM)
.getCdmaSubscriptionSource();
doReturn(PHONE_ID).when(mPhone).getPhoneId();
logd("Calling updatePhoneType");
// switch to CDMA
sst.updatePhoneType();
// trigger RUIM_RECORDS_LOADED
ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mRuimRecords).registerForRecordsLoaded(eq(sst), integerArgumentCaptor.capture(),
nullable(Object.class));
// response for mRuimRecords.registerForRecordsLoaded()
Message msg = Message.obtain();
msg.what = integerArgumentCaptor.getValue();
msg.obj = new AsyncResult(null, null, null);
sst.sendMessage(msg);
// wait for RUIM_RECORDS_LOADED to be handled
waitForHandlerAction(sst, 5000);
// mdn should be null as nothing populated it
assertEquals(null, sst.getMdnNumber());
// if ruim is provisioned, mdn should still be null
doReturn(true).when(mRuimRecords).isProvisioned();
assertEquals(null, sst.getMdnNumber());
// if ruim is not provisioned, and mdn is non null, sst should still return the correct
// value
doReturn(false).when(mRuimRecords).isProvisioned();
String mockMdn = "mockMdn";
doReturn(mockMdn).when(mRuimRecords).getMdn();
// trigger RUIM_RECORDS_LOADED
Message msg1 = Message.obtain();
msg1.what = integerArgumentCaptor.getValue();
msg1.obj = new AsyncResult(null, null, null);
sst.sendMessage(msg1);
// wait for RUIM_RECORDS_LOADED to be handled
waitForHandlerAction(sst, 5000);
assertEquals(mockMdn, sst.getMdnNumber());
}
@Test
@SmallTest
public void testOnLteVopsInfoChanged() {
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
sst.mSS = ss;
CellIdentityLte cellId =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
"tst", Collections.emptyList(), null);
LteVopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED);
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE,
0, false, null, cellId, "00101", 1, false, false, false, lteVopsSupportInfo);
sst.mPollingContext[0] = 2;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
TelephonyManager.NETWORK_TYPE_LTE, 0,
false, null, cellId, "00101", false, 0, 0, 0);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
NetworkRegistrationInfo sSnetworkRegistrationInfo =
sst.mSS.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertEquals(lteVopsSupportInfo,
sSnetworkRegistrationInfo.getDataSpecificInfo().getLteVopsSupportInfo());
lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED);
dataResult = new NetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
TelephonyManager.NETWORK_TYPE_LTE, 0, false, null, cellId, "00101",
1, false, false, false, lteVopsSupportInfo);
sst.mPollingContext[0] = 1;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sSnetworkRegistrationInfo =
sst.mSS.getNetworkRegistrationInfo(2, 1);
assertEquals(lteVopsSupportInfo,
sSnetworkRegistrationInfo.getDataSpecificInfo().getLteVopsSupportInfo());
}
@Test
@SmallTest
public void testOnNrVopsInfoChanged() {
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
sst.mSS = ss;
CellIdentityLte cellId =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
"tst", Collections.emptyList(), null);
NrVopsSupportInfo nrVopsSupportInfo = new NrVopsSupportInfo(
NrVopsSupportInfo.NR_STATUS_VOPS_NOT_SUPPORTED,
NrVopsSupportInfo.NR_STATUS_EMC_NOT_SUPPORTED,
NrVopsSupportInfo.NR_STATUS_EMF_NOT_SUPPORTED);
NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_NR,
0, false, null, cellId, "00101", 1, false, false, false, nrVopsSupportInfo);
sst.mPollingContext[0] = 2;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
TelephonyManager.NETWORK_TYPE_NR, 0,
false, null, cellId, "00101", false, 0, 0, 0);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
NetworkRegistrationInfo sSnetworkRegistrationInfo =
sst.mSS.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertEquals(nrVopsSupportInfo,
sSnetworkRegistrationInfo.getDataSpecificInfo().getVopsSupportInfo());
nrVopsSupportInfo = new NrVopsSupportInfo(
NrVopsSupportInfo.NR_STATUS_VOPS_3GPP_SUPPORTED,
NrVopsSupportInfo.NR_STATUS_EMC_5GCN_ONLY,
NrVopsSupportInfo.NR_STATUS_EMF_5GCN_ONLY);
dataResult = new NetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
TelephonyManager.NETWORK_TYPE_NR, 0, false, null, cellId, "00101",
1, false, false, false, nrVopsSupportInfo);
sst.mPollingContext[0] = 1;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
sSnetworkRegistrationInfo =
sst.mSS.getNetworkRegistrationInfo(2, 1);
assertEquals(nrVopsSupportInfo,
sSnetworkRegistrationInfo.getDataSpecificInfo().getVopsSupportInfo());
}
@Test
@SmallTest
public void testEriLoading() {
sst.obtainMessage(GsmCdmaPhone.EVENT_CARRIER_CONFIG_CHANGED, null).sendToTarget();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
verify(mEriManager, times(1)).loadEriFile();
}
@Test
public void testLastKnownCellIdentity() throws Exception {
CellIdentityLte cellIdentity =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
"tst", Collections.emptyList(), null);
sendPhyChanConfigChange(new int[] {10000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
sendRegStateUpdateForLteCellId(cellIdentity);
assertEquals(ServiceState.STATE_IN_SERVICE, sst.mSS.getState());
assertEquals(cellIdentity, sst.getLastKnownCellIdentity());
assertFalse(sst.hasMessages(sst.EVENT_RESET_LAST_KNOWN_CELL_IDENTITY));
sendRegStateUpdateForLteOnOos();
assertEquals(ServiceState.STATE_OUT_OF_SERVICE, sst.mSS.getState());
assertEquals(cellIdentity, sst.getLastKnownCellIdentity());
assertTrue(sst.hasMessages(sst.EVENT_RESET_LAST_KNOWN_CELL_IDENTITY));
sst.obtainMessage(sst.EVENT_RESET_LAST_KNOWN_CELL_IDENTITY, null).sendToTarget();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertNull(sst.getLastKnownCellIdentity());
}
@Test
public void testUpdateSpnDisplay_noService_displayEmergencyCallOnly() {
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// Emergency call only
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_EMERGENCY_ONLY);
ss.setDataRegState(ServiceState.STATE_OUT_OF_SERVICE);
ss.setEmergencyOnly(true);
sst.mSS = ss;
// update the spn
sst.updateSpnDisplay();
// Plmn should be shown, and the string is "Emergency call only"
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_PLMN))
.isEqualTo(CARRIER_NAME_DISPLAY_EMERGENCY_CALL);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testUpdateSpnDisplay_noServiceAndEmergencyCallNotAvailable_displayOOS() {
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// Completely out of service
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
ss.setDataRegState(ServiceState.STATE_OUT_OF_SERVICE);
ss.setEmergencyOnly(false);
sst.mSS = ss;
// update the spn
sst.updateSpnDisplay();
// Plmn should be shown, and the string is "No service"
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_PLMN))
.isEqualTo(CARRIER_NAME_DISPLAY_NO_SERVICE);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testUpdateSpnDisplay_flightMode_displayNull() {
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// Flight mode
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_POWER_OFF);
ss.setDataRegState(ServiceState.STATE_POWER_OFF);
sst.mSS = ss;
// update the spn
sst.updateSpnDisplay();
// Plmn should be shown, and the string is null
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_PLMN)).isEqualTo(null);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testUpdateSpnDisplay_flightModeNoWifiCalling_showSpnAndPlmn() {
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// Flight mode and connected to WiFI
doReturn(ServiceState.STATE_POWER_OFF).when(mServiceState).getVoiceRegState();
doReturn(ServiceState.STATE_POWER_OFF).when(mServiceState).getDataRegState();
doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
sst.mSS = mServiceState;
// wifi-calling is disable
doReturn(false).when(mPhone).isWifiCallingEnabled();
// update the spn
sst.updateSpnDisplay();
// Show both spn & plmn
String spn = mBundle.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
String plmn = mBundle.getStringArray(CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY)[0];
plmn = plmn.split("\\s*,\\s*")[0];
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_SPN)).isEqualTo(spn);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_SPN)).isTrue();
assertThat(b.getString(TelephonyManager.EXTRA_PLMN)).isEqualTo(plmn);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testUpdateSpnDisplay_spnNotEmptyAndCrossSimCallingEnabled_showSpnOnly() {
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// In Service
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
sst.mSS = ss;
// cross-sim-calling is enable
doReturn(mImsPhone).when(mPhone).getImsPhone();
doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM).when(mImsPhone)
.getImsRegistrationTech();
String[] formats = {CROSS_SIM_CALLING_VOICE_FORMAT, "%s"};
Resources r = mContext.getResources();
doReturn(formats).when(r).getStringArray(anyInt());
// update the spn
sst.updateSpnDisplay();
// Only spn should be shown
String spn = mBundle.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_SPN))
.isEqualTo(String.format(CROSS_SIM_CALLING_VOICE_FORMAT, spn));
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_SPN)).isTrue();
assertThat(b.getString(TelephonyManager.EXTRA_DATA_SPN))
.isEqualTo(String.format(CROSS_SIM_CALLING_VOICE_FORMAT, spn));
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isFalse();
}
@Test
public void testUpdateSpnDisplay_spnNotEmptyAndWifiCallingEnabled_showSpnOnly() {
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// In Service
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
sst.mSS = ss;
// wifi-calling is enabled
doReturn(true).when(mPhone).isWifiCallingEnabled();
// update the spn
sst.updateSpnDisplay();
// Only spn should be shown
String spn = mBundle.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_SPN))
.isEqualTo(String.format(WIFI_CALLING_VOICE_FORMAT, spn));
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_SPN)).isTrue();
assertThat(b.getString(TelephonyManager.EXTRA_DATA_SPN))
.isEqualTo(String.format(WIFI_CALLING_DATA_FORMAT, spn));
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isFalse();
}
@Test
public void testUpdateSpnDisplay_spnEmptyAndWifiCallingEnabled_showPlmnOnly() {
// set empty service provider name
mBundle.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, "");
sendCarrierConfigUpdate();
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// In Service
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
sst.mSS = ss;
// wifi-calling is enabled
doReturn(true).when(mPhone).isWifiCallingEnabled();
// update the spn
sst.updateSpnDisplay();
// Only plmn should be shown
String plmn = mBundle.getStringArray(CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY)[0];
plmn = plmn.split("\\s*,\\s*")[0];
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_PLMN))
.isEqualTo(String.format(WIFI_CALLING_VOICE_FORMAT, plmn));
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_SPN)).isFalse();
}
@Test
public void testUpdateSpnDisplay_inServiceNoWifiCalling_showSpnAndPlmn() {
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
sst.mSS = ss;
// wifi-calling is disable
doReturn(false).when(mPhone).isWifiCallingEnabled();
// update the spn
sst.updateSpnDisplay();
// Show both spn & plmn
String spn = mBundle.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
String plmn = mBundle.getStringArray(CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY)[0];
plmn = plmn.split("\\s*,\\s*")[0];
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_SPN)).isEqualTo(spn);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_SPN)).isTrue();
assertThat(b.getString(TelephonyManager.EXTRA_PLMN)).isEqualTo(plmn);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testShouldForceDisplayNoService_forceBasedOnLocale() {
// set up unaffected locale (US) and clear the resource
doReturn("us").when(mLocaleTracker).getLastKnownCountryIso();
mContextFixture.putStringArrayResource(
com.android.internal.R.array.config_display_no_service_when_sim_unready,
new String[0]);
assertFalse(sst.shouldForceDisplayNoService());
// set up the resource to include Germany
mContextFixture.putStringArrayResource(
com.android.internal.R.array.config_display_no_service_when_sim_unready,
new String[]{"de"});
doReturn("us").when(mLocaleTracker).getLastKnownCountryIso();
assertFalse(sst.shouldForceDisplayNoService());
// mock the locale to Germany
doReturn("de").when(mLocaleTracker).getLastKnownCountryIso();
assertTrue(sst.shouldForceDisplayNoService());
}
@Test
public void testUpdateSpnDisplayLegacy_WlanServiceNoWifiCalling_displayOOS() {
mBundle.putBoolean(
CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, false);
sendCarrierConfigUpdate();
// GSM phone
doReturn(true).when(mPhone).isPhoneTypeGsm();
// voice out of service but data in service (connected to IWLAN)
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getDataRegistrationState();
doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
sst.mSS = mServiceState;
// wifi-calling is disable
doReturn(false).when(mPhone).isWifiCallingEnabled();
// update the spn
sst.updateSpnDisplay();
// Plmn should be shown, and the string is "No service"
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyManager.EXTRA_PLMN))
.isEqualTo(CARRIER_NAME_DISPLAY_NO_SERVICE);
assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
}
private Bundle getExtrasFromLastSpnUpdateIntent() {
// Verify the spn update notification was sent
ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContextFixture.getTestDouble(), atLeast(1))
.sendStickyBroadcastAsUser(intentArgumentCaptor.capture(), eq(UserHandle.ALL));
List<Intent> intents = intentArgumentCaptor.getAllValues();
return intents.get(intents.size() - 1).getExtras();
}
private static NetworkRegistrationInfo makeNetworkRegistrationInfo(
int domain, int transport, CellIdentity ci, boolean isRegistered) {
return new NetworkRegistrationInfo.Builder()
.setDomain(domain)
.setTransportType(transport)
.setCellIdentity(ci)
.setRegistrationState(isRegistered
? NetworkRegistrationInfo.REGISTRATION_STATE_HOME
: NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
.build();
}
@Test
public void testCellIdentitySort() {
final CellIdentityLte cellIdentityLte =
new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
"tst", Collections.emptyList(), null);
final CellIdentityGsm cellIdentityGsm = new CellIdentityGsm(
2, 3, 900, 5, "001", "01", "test", "tst", Collections.emptyList());
ServiceState ss = new ServiceState();
List<CellIdentity> cids;
// Test that PS WWAN is reported if available
ss.addNetworkRegistrationInfo(makeNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
cellIdentityLte, false));
cids = ServiceStateTracker.getPrioritizedCellIdentities(ss);
assertEquals(cids.size(), 1);
assertEquals(cids.get(0), cellIdentityLte);
// Test that CS is prioritized over PS
ss.addNetworkRegistrationInfo(makeNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
cellIdentityGsm, false));
cids = ServiceStateTracker.getPrioritizedCellIdentities(ss);
assertEquals(cids.size(), 2);
assertEquals(cids.get(0), cellIdentityGsm);
assertEquals(cids.get(1), cellIdentityLte);
// Test that WLAN is ignored
ss.addNetworkRegistrationInfo(makeNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
cellIdentityGsm, false));
cids = ServiceStateTracker.getPrioritizedCellIdentities(ss);
assertEquals(cids.size(), 2);
assertEquals(cids.get(0), cellIdentityGsm);
assertEquals(cids.get(1), cellIdentityLte);
// Test that null CellIdentities are ignored
ss.addNetworkRegistrationInfo(makeNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS,
AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
null, false));
cids = ServiceStateTracker.getPrioritizedCellIdentities(ss);
assertEquals(cids.size(), 2);
assertEquals(cids.get(0), cellIdentityGsm);
assertEquals(cids.get(1), cellIdentityLte);
// Test that registered networks are prioritized over unregistered
ss.addNetworkRegistrationInfo(makeNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
cellIdentityLte, true));
cids = ServiceStateTracker.getPrioritizedCellIdentities(ss);
assertEquals(cids.size(), 2);
assertEquals(cids.get(0), cellIdentityLte);
assertEquals(cids.get(1), cellIdentityGsm);
}
@Test
public void testGetCidFromCellIdentity() throws Exception {
CellIdentity gsmCi = new CellIdentityGsm(
0, 1, 0, 0, "", "", "", "", Collections.emptyList());
CellIdentity wcdmaCi = new CellIdentityWcdma(
0, 2, 0, 0, "", "", "", "", Collections.emptyList(), null);
CellIdentity tdscdmaCi = new CellIdentityTdscdma(
"", "", 0, 3, 0, 0, "", "", Collections.emptyList(), null);
CellIdentity lteCi = new CellIdentityLte(0, 0, 4, 0, 0);
CellIdentity nrCi = new CellIdentityNr(
0, 0, 0, new int[] {}, "", "", 5, "", "", Collections.emptyList());
Method method = ServiceStateTracker.class.getDeclaredMethod(
"getCidFromCellIdentity", CellIdentity.class);
method.setAccessible(true);
assertEquals(1, (long) method.invoke(mSST, gsmCi));
assertEquals(2, (long) method.invoke(mSST, wcdmaCi));
assertEquals(3, (long) method.invoke(mSST, tdscdmaCi));
assertEquals(4, (long) method.invoke(mSST, lteCi));
assertEquals(5, (long) method.invoke(mSST, nrCi));
}
@Test
public void testGetCombinedRegState() {
doReturn(mImsPhone).when(mPhone).getImsPhone();
// If voice/data out of service, return out of service.
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getDataRegistrationState();
assertEquals(ServiceState.STATE_OUT_OF_SERVICE, sst.getCombinedRegState(mServiceState));
// If voice is emergency only, return emergency only
doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getState();
assertEquals(ServiceState.STATE_EMERGENCY_ONLY, sst.getCombinedRegState(mServiceState));
// If data in service, return in service.
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getDataRegistrationState();
assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCombinedRegState(mServiceState));
// Check emergency
doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getState();
assertEquals(ServiceState.STATE_EMERGENCY_ONLY, sst.getCombinedRegState(mServiceState));
// If data in service and network is IWLAN but WiFi calling is off, return out of service.
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
doReturn(false).when(mImsPhone).isWifiCallingEnabled();
assertEquals(ServiceState.STATE_OUT_OF_SERVICE, sst.getCombinedRegState(mServiceState));
// Check emrgency
doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getState();
assertEquals(ServiceState.STATE_EMERGENCY_ONLY, sst.getCombinedRegState(mServiceState));
// If data in service and network is IWLAN and WiFi calling is on, return in service.
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
doReturn(true).when(mImsPhone).isWifiCallingEnabled();
assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCombinedRegState(mServiceState));
// Check emergency
doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getState();
assertEquals(ServiceState.STATE_EMERGENCY_ONLY, sst.getCombinedRegState(mServiceState));
}
}