blob: cfd36c22090fd446213346132cdf8e20370f3707 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
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.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.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.IAlarmManager;
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.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.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellSignalStrength;
import android.telephony.CellSignalStrengthCdma;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.CellSignalStrengthLte;
import android.telephony.CellSignalStrengthNr;
import android.telephony.CellSignalStrengthTdscdma;
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.INetworkService;
import android.telephony.LteVopsSupportInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkService;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
import android.util.TimestampedValue;
import androidx.test.filters.FlakyTest;
import com.android.internal.R;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
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.Mock;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class ServiceStateTrackerTest extends TelephonyTest {
@Mock
private ProxyController mProxyController;
@Mock
private Handler mTestHandler;
@Mock
protected IAlarmManager mAlarmManager;
private CellularNetworkService mCellularNetworkService;
@Mock
private NetworkService mIwlanNetworkService;
@Mock
private INetworkService.Stub mIwlanNetworkServiceStub;
@Mock
private SubscriptionInfo mSubInfo;
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 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() {
sst = new ServiceStateTracker(mPhone, mSimulatedCommands);
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("ServiceStateTrackerTest");
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).isDisconnected();
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();
mSSTTestHandler = new ServiceStateTrackerTestHandler(getClass().getSimpleName());
mSSTTestHandler.start();
waitUntilReady();
waitForMs(600);
Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
mContext.sendBroadcast(intent);
waitForMs(100);
// 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);
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
mContextFixture.putBooleanResource(
com.android.internal.R.bool.config_display_no_service_when_sim_unready, false);
logd("ServiceStateTrackerTest -Setup!");
}
@After
public void tearDown() throws Exception {
sst = null;
mSSTTestHandler.quit();
mSSTTestHandler.join();
super.tearDown();
}
@Test
@MediumTest
public void testSetRadioPower() {
boolean oldState = (mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
sst.setRadioPower(!oldState);
waitForMs(100);
assertTrue(oldState
!= (mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON));
}
@Test
@MediumTest
public void testSetRadioPowerFromCarrier() {
// Carrier disable radio power
sst.setRadioPowerFromCarrier(false);
waitForMs(100);
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);
waitForMs(100);
assertFalse(mSimulatedCommands.getRadioState()
== TelephonyManager.RADIO_POWER_ON);
assertTrue(sst.getDesiredPowerState());
assertFalse(sst.getPowerStateFromCarrier());
// Carrier re-enable radio power
sst.setRadioPowerFromCarrier(true);
waitForMs(100);
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);
waitForMs(100);
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);
waitForMs(500);
sst.pollState();
waitForMs(250);
// 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();
waitForMs(250);
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));
waitForMs(750);
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 SPN_STRINGS_UPDATED_ACTION.
List<Intent> intents = intentArgumentCaptor.getAllValues();
logd("Total " + intents.size() + " intents");
for (Intent intent : intents) {
logd(" " + intent.getAction());
}
Intent intent = intents.get(2);
assertEquals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION, intent.getAction());
Bundle b = intent.getExtras();
// For boolean we need to make sure the key exists first
assertTrue(b.containsKey(TelephonyIntents.EXTRA_SHOW_SPN));
assertFalse(b.getBoolean(TelephonyIntents.EXTRA_SHOW_SPN));
assertEquals(null, b.getString(TelephonyIntents.EXTRA_SPN));
assertEquals(null, b.getString(TelephonyIntents.EXTRA_DATA_SPN));
// For boolean we need to make sure the key exists first
assertTrue(b.containsKey(TelephonyIntents.EXTRA_SHOW_PLMN));
assertTrue(b.getBoolean(TelephonyIntents.EXTRA_SHOW_PLMN));
assertEquals(SimulatedCommands.FAKE_LONG_NAME, b.getString(TelephonyIntents.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"));
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);
waitForMs(200);
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));
waitForMs(200);
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));
waitForMs(200);
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));
waitForMs(200);
// 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));
waitForMs(200);
// Nothing happened because the IMS service state was not affected the merged service state.
verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
}
private void sendSignalStrength(SignalStrength ss) {
mSimulatedCommands.setSignalStrength(ss);
mSimulatedCommands.notifySignalStrength();
waitForMs(300);
}
@Test
@MediumTest
public void testSignalStrength() {
// Send in GSM Signal Strength Info and expect isGsm == true
SignalStrength ss = new SignalStrength(
new CellSignalStrengthCdma(),
new CellSignalStrengthGsm(-53, 0, SignalStrength.INVALID),
new CellSignalStrengthWcdma(),
new CellSignalStrengthTdscdma(),
new CellSignalStrengthLte(),
new CellSignalStrengthNr());
sendSignalStrength(ss);
assertEquals(sst.getSignalStrength(), ss);
assertEquals(sst.getSignalStrength().isGsm(), true);
// Send in CDMA+LTE Signal Strength Info and expect isGsm == true
ss = new SignalStrength(
new CellSignalStrengthCdma(-90, -12,
SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
new CellSignalStrengthGsm(),
new CellSignalStrengthWcdma(),
new CellSignalStrengthTdscdma(),
new CellSignalStrengthLte(
-110, -114, -5, 0, SignalStrength.INVALID, SignalStrength.INVALID),
new CellSignalStrengthNr());
sendSignalStrength(ss);
assertEquals(sst.getSignalStrength(), ss);
assertEquals(sst.getSignalStrength().isGsm(), true);
// Send in CDMA-only Signal Strength Info and expect isGsm == false
ss = new SignalStrength(
new CellSignalStrengthCdma(-90, -12,
SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
new CellSignalStrengthGsm(),
new CellSignalStrengthWcdma(),
new CellSignalStrengthTdscdma(),
new CellSignalStrengthLte(),
new CellSignalStrengthNr());
sendSignalStrength(ss);
assertEquals(sst.getSignalStrength(), ss);
assertEquals(sst.getSignalStrength().isGsm(), false);
}
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);
waitForMs(300);
}
@Test
public void testLteSignalStrengthReportingCriteria() {
SignalStrength ss = new SignalStrength(
new CellSignalStrengthCdma(),
new CellSignalStrengthGsm(),
new CellSignalStrengthWcdma(),
new CellSignalStrengthTdscdma(),
new CellSignalStrengthLte(
-110, /* rssi */
-114, /* rsrp */
-5, /* rsrq */
0, /* rssnr */
SignalStrength.INVALID, /* cqi */
SignalStrength.INVALID /* ta */),
new CellSignalStrengthNr());
mBundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL,
true);
sendCarrierConfigUpdate();
mSimulatedCommands.setSignalStrength(ss);
mSimulatedCommands.notifySignalStrength();
waitForMs(300);
// Default thresholds are POOR=-115 MODERATE=-105 GOOD=-95 GREAT=-85
assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, sst.getSignalStrength().getLevel());
int[] lteThresholds = {
-130, // SIGNAL_STRENGTH_POOR
-120, // SIGNAL_STRENGTH_MODERATE
-110, // SIGNAL_STRENGTH_GOOD
-100, // SIGNAL_STRENGTH_GREAT
};
mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
lteThresholds);
sendCarrierConfigUpdate();
mSimulatedCommands.setSignalStrength(ss);
mSimulatedCommands.notifySignalStrength();
waitForMs(300);
assertEquals(sst.getSignalStrength().getLevel(),
CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
}
@Test
public void testWcdmaSignalStrengthReportingCriteria() {
SignalStrength ss = new SignalStrength(
new CellSignalStrengthCdma(),
new CellSignalStrengthGsm(),
new CellSignalStrengthWcdma(-79, 0, -85, -5),
new CellSignalStrengthTdscdma(),
new CellSignalStrengthLte(),
new CellSignalStrengthNr());
mSimulatedCommands.setSignalStrength(ss);
mSimulatedCommands.notifySignalStrength();
waitForMs(300);
assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
int[] wcdmaThresholds = {
-110, // SIGNAL_STRENGTH_POOR
-100, // SIGNAL_STRENGTH_MODERATE
-90, // SIGNAL_STRENGTH_GOOD
-80 // SIGNAL_STRENGTH_GREAT
};
mBundle.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
wcdmaThresholds);
mBundle.putString(
CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
"rscp");
sendCarrierConfigUpdate();
mSimulatedCommands.setSignalStrength(ss);
mSimulatedCommands.notifySignalStrength();
waitForMs(300);
assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
}
@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");
NetworkRegistrationInfo result = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setCellIdentity(cellIdentityGsm)
.build();
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_GET_LOC_DONE,
new AsyncResult(null, result, null)));
waitForMs(200);
WorkSource workSource = new WorkSource(Process.myUid(), mContext.getPackageName());
GsmCellLocation cl = (GsmCellLocation) sst.getCellLocation();
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)));
waitForMs(200);
WorkSource workSource = new WorkSource(Process.myUid(), mContext.getPackageName());
CdmaCellLocation cl = (CdmaCellLocation) sst.getCellLocation();
assertEquals(5, cl.getBaseStationLatitude());
assertEquals(4, cl.getBaseStationLongitude());
}
@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);
waitForMs(100);
// 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
waitForMs(200);
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();
waitForMs(200);
// 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();
waitForMs(100);
// Unregister registrant
sst.unregisterForVoiceRoamingOn(mTestHandler);
// Enable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
// 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();
waitForMs(100);
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();
waitForMs(200);
// 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();
waitForMs(100);
// Unregister registrant
sst.unregisterForVoiceRoamingOff(mTestHandler);
// Disable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
// 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();
waitForMs(200);
// 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();
waitForMs(100);
// Unregister registrant
sst.unregisterForDataRoamingOn(mTestHandler);
// Enable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
// 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();
waitForMs(100);
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();
waitForMs(100);
// 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();
waitForMs(100);
// Unregister registrant
sst.unregisterForDataRoamingOff(mTestHandler);
// Disable roaming
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
// 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();
waitForMs(100);
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();
waitForMs(200);
// 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();
waitForMs(100);
// 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();
waitForMs(100);
// 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();
waitForMs(100);
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();
waitForMs(200);
// 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();
waitForMs(100);
// 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();
waitForMs(100);
// 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();
waitForMs(200);
// 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();
waitForMs(100);
// 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();
waitForMs(100);
// 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);
waitForMs(100);
// 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);
waitForMs(100);
// 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();
waitForMs(100);
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();
waitForMs(100);
// 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();
waitForMs(100);
// Unregister registrant
sst.unregisterForNetworkAttached(mTestHandler);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
// 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();
waitForMs(100);
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();
waitForMs(100);
// 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();
waitForMs(100);
// Unregister registrant
sst.unregisterForNetworkAttached(mTestHandler);
waitForMs(100);
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();
waitForMs(100);
// 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);
waitForMs(100);
// 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);
waitForMs(100);
// 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]);
waitForMs(100);
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());
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 = 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());
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 = 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());
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 = 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());
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 = 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 = 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();
waitForMs(200);
// 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();
waitForMs(200);
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
@MediumTest
public void testEnableLocationUpdates() throws Exception {
sst.enableLocationUpdates();
verify(mSimulatedCommandsVerifier, times(1)).setLocationUpdates(eq(true),
any(Message.class));
}
@Test
@SmallTest
public void testDisableLocationUpdates() throws Exception {
sst.disableLocationUpdates();
verify(mSimulatedCommandsVerifier, times(1)).setLocationUpdates(eq(false),
nullable(Message.class));
}
@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();
waitForMs(200);
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);
waitForMs(100);
sst.requestShutdown();
waitForMs(100);
assertFalse(mSimulatedCommands.getRadioState()
!= TelephonyManager.RADIO_POWER_UNAVAILABLE);
}
@Test
@SmallTest
public void testShuttingDownRequestWithRadioPowerFailResponse() throws Exception {
sst.setRadioPower(true);
waitForMs(100);
// Simulate RIL fails the radio power settings.
mSimulatedCommands.setRadioPowerFailResponse(true);
sst.setRadioPower(false);
waitForMs(100);
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
sst.requestShutdown();
waitForMs(100);
assertFalse(mSimulatedCommands.getRadioState()
!= TelephonyManager.RADIO_POWER_UNAVAILABLE);
}
@Test
@SmallTest
public void testSetTimeFromNITZStr() throws Exception {
{
// Mock sending incorrect nitz str from RIL
mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0");
waitForMs(200);
verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
}
{
// Mock sending correct nitz str from RIL
String nitzStr = "15/06/20,00:00:00+0";
NitzData expectedNitzData = NitzData.parse(nitzStr);
mSimulatedCommands.triggerNITZupdate(nitzStr);
waitForMs(200);
ArgumentCaptor<TimestampedValue<NitzData>> argumentsCaptor =
ArgumentCaptor.forClass(TimestampedValue.class);
verify(mNitzStateMachine, times(1))
.handleNitzReceived(argumentsCaptor.capture());
// Confirm the argument was what we expected.
TimestampedValue<NitzData> actualNitzSignal = argumentsCaptor.getValue();
assertEquals(expectedNitzData, actualNitzSignal.getValue());
assertTrue(actualNitzSignal.getReferenceTimeMillis() <= SystemClock.elapsedRealtime());
}
}
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, 1, false, false, false, lteVopsSupportInfo, false);
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)));
waitForMs(200);
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
state, voiceRat, 0, false,
null, cid, false, 0, 0, 0);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForMs(200);
}
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, 1, false, false, false, lteVopsSupportInfo, false);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForMs(200);
// CS WWAN
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
state, voiceRat, 0, false,
null, cid, false, 0, 0, 0);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForMs(200);
// PS WLAN
NetworkRegistrationInfo dataIwlanResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
iwlanState, iwlanDataRat, 0, false,
null, null, 1, false, false, false, lteVopsSupportInfo, false);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_IWLAN_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataIwlanResult, null)));
waitForMs(200);
}
// 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");
// 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");
// 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");
changeRegState(1, cellIdentity, 16, 1);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilDataRadioTechnology());
}
// TODO(nharold): This actually seems like broken behavior; rather than preserve it, we should
// probably remove it.
// GSM, Edge, GPRS are grouped under the same family where Edge > GPRS > GSM.
// Expect no rat update from E to G immediately following cell id change.
// Expect ratratchet (from G to E) for the following rat update within the cell location.
@Test
public void testRatRatchetWithCellChangeBeforeRatChange() throws Exception {
// cell ID update
CellIdentityGsm cellIdentity =
new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst");
changeRegState(1, cellIdentity, 16, 2);
assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
// RAT: EDGE -> GPRS, cell ID unchanged. Expect no rat ratchet following cell Id change.
changeRegState(1, cellIdentity, 16, 1);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilDataRadioTechnology());
// RAT: GPRS -> EDGE should ratchet.
changeRegState(1, cellIdentity, 16, 2);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
}
private void sendPhyChanConfigChange(int[] bandwidths) {
ArrayList<PhysicalChannelConfig> pc = new ArrayList<>();
int ssType = PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING;
for (int bw : bandwidths) {
pc.add(new PhysicalChannelConfig.Builder()
.setCellConnectionStatus(ssType)
.setCellBandwidthDownlinkKhz(bw)
.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)));
waitForMs(100);
}
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, 1, false, false, false, lteVopsSupportInfo, false);
NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE,
0, false, null, 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)));
waitForMs(200);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForMs(200);
}
@Test
public void testPhyChanBandwidthUpdatedOnDataRegState() throws Exception {
// Cell ID change should trigger hasLocationChanged.
CellIdentityLte cellIdentity5 =
new CellIdentityLte(1, 1, 5, 1, 5000, "001", "01", "test", "tst");
sendPhyChanConfigChange(new int[] {10000});
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, 12345, "001", "01", "test", "tst");
sendPhyChanConfigChange(new int[] {10000});
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, 10000, "001", "01", "test", "tst");
sendPhyChanConfigChange(new int[] {10000, 5000});
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, 10000, "1", "1", "test", "tst");
sendRegStateUpdateForLteCellId(cellIdentity10);
assertTrue(Arrays.equals(new int[] {10000}, sst.mSS.getCellBandwidths()));
sendPhyChanConfigChange(new int[] {10000, 5000});
assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
}
@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, false);
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)));
waitForMs(200);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForMs(200);
assertTrue(Arrays.equals(new int[0], 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(mTransportManager.isAnyApnPreferredOnIwlan()).thenReturn(false);
// Start state: Cell data only LTE + IWLAN
CellIdentityLte cellIdentity =
new CellIdentityLte(1, 1, 5, 1, 5000, "001", "01", "test", "tst");
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(mTransportManager.isAnyApnPreferredOnIwlan()).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();
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 testOnVopsInfoChanged() {
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, 5000, "001", "01", "test", "tst");
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, 1, false, false, false, lteVopsSupportInfo, false);
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, false, 0, 0, 0);
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, voiceResult, null)));
waitForMs(200);
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, 1, false, false, false,
lteVopsSupportInfo, false);
sst.mPollingContext[0] = 1;
sst.sendMessage(sst.obtainMessage(
ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
new AsyncResult(sst.mPollingContext, dataResult, null)));
waitForMs(200);
sSnetworkRegistrationInfo =
sst.mSS.getNetworkRegistrationInfo(2, 1);
assertEquals(lteVopsSupportInfo,
sSnetworkRegistrationInfo.getDataSpecificInfo().getLteVopsSupportInfo());
}
@Test
@SmallTest
public void testEriLoading() {
sst.obtainMessage(GsmCdmaPhone.EVENT_CARRIER_CONFIG_CHANGED, null).sendToTarget();
waitForMs(100);
verify(mEriManager, times(1)).loadEriFile();
}
private void enableCdnr() {
mBundle.putBoolean(
CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, true);
sendCarrierConfigUpdate();
}
@Test
public void testUpdateSpnDisplay_noService_displayEmergencyCallOnly() {
enableCdnr();
// 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);
doReturn(ss).when(mSST).getServiceState();
// update the spn
sst.updateSpnDisplay();
// Plmn should be shown, and the string is "Emergency call only"
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyIntents.EXTRA_PLMN))
.isEqualTo(CARRIER_NAME_DISPLAY_EMERGENCY_CALL);
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testUpdateSpnDisplay_noServiceAndEmergencyCallNotAvailable_displayOOS() {
enableCdnr();
// 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);
doReturn(ss).when(mSST).getServiceState();
// update the spn
sst.updateSpnDisplay();
// Plmn should be shown, and the string is "No service"
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyIntents.EXTRA_PLMN))
.isEqualTo(CARRIER_NAME_DISPLAY_NO_SERVICE);
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testUpdateSpnDisplay_flightMode_displayOOS() {
enableCdnr();
// 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);
doReturn(ss).when(mSST).getServiceState();
// update the spn
sst.updateSpnDisplay();
// Plmn should be shown, and the string is "No service"
Bundle b = getExtrasFromLastSpnUpdateIntent();
assertThat(b.getString(TelephonyIntents.EXTRA_PLMN))
.isEqualTo(CARRIER_NAME_DISPLAY_NO_SERVICE);
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_PLMN)).isTrue();
}
@Test
public void testUpdateSpnDisplay_spnNotEmptyAndWifiCallingEnabled_showSpnOnly() {
enableCdnr();
// 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(TelephonyIntents.EXTRA_SPN))
.isEqualTo(String.format(WIFI_CALLING_VOICE_FORMAT, spn));
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_SPN)).isTrue();
assertThat(b.getString(TelephonyIntents.EXTRA_DATA_SPN))
.isEqualTo(String.format(WIFI_CALLING_DATA_FORMAT, spn));
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_PLMN)).isFalse();
}
@Test
public void testUpdateSpnDisplay_spnEmptyAndWifiCallingEnabled_showPlmnOnly() {
// set empty service provider name
mBundle.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, "");
enableCdnr();
// 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(TelephonyIntents.EXTRA_PLMN))
.isEqualTo(String.format(WIFI_CALLING_VOICE_FORMAT, plmn));
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_PLMN)).isTrue();
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_SPN)).isFalse();
}
@Test
public void testUpdateSpnDisplay_inServiceNoWifiCalling_showSpnAndPlmn() {
enableCdnr();
// 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(TelephonyIntents.EXTRA_SPN)).isEqualTo(spn);
assertThat(b.getBoolean(TelephonyIntents.EXTRA_SHOW_SPN)).isTrue();
assertThat(b.getString(TelephonyIntents.EXTRA_PLMN)).isEqualTo(plmn);
assertThat(b.getBoolean(TelephonyIntents.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();
}
}