blob: bb5378040da32fc6ecd7a26b2c0e0f3e3f28f12a [file] [log] [blame]
/*
* Copyright 2020 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.google.android.iwlan;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.ipsec.ike.ike3gpp.Ike3gppParams.PDU_SESSION_ID_UNSET;
import static android.telephony.TelephonyManager.CALL_STATE_IDLE;
import static android.telephony.TelephonyManager.CALL_STATE_RINGING;
import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_NR;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.google.android.iwlan.epdg.EpdgTunnelManager.BRINGDOWN_REASON_DEACTIVATE_DATA_CALL;
import static com.google.android.iwlan.epdg.EpdgTunnelManager.BRINGDOWN_REASON_NETWORK_UPDATE_WHEN_TUNNEL_IN_BRINGUP;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doNothing;
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.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
import android.net.ipsec.ike.exceptions.IkeInternalException;
import android.net.vcn.VcnTransportInfo;
import android.os.PersistableBundle;
import android.os.test.TestLooper;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.DataFailCause;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
import android.telephony.data.DataServiceCallback;
import android.telephony.data.IDataServiceCallback;
import android.telephony.data.NetworkSliceInfo;
import android.telephony.data.TrafficDescriptor;
import android.telephony.ims.ImsManager;
import android.telephony.ims.ImsMmTelManager;
import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider;
import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider.IwlanTunnelCallback;
import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider.TunnelState;
import com.google.android.iwlan.epdg.EpdgSelector;
import com.google.android.iwlan.epdg.EpdgTunnelManager;
import com.google.android.iwlan.epdg.NetworkSliceSelectionAssistanceInformation;
import com.google.android.iwlan.epdg.TunnelLinkProperties;
import com.google.android.iwlan.epdg.TunnelSetupRequest;
import com.google.android.iwlan.flags.FeatureFlags;
import com.google.android.iwlan.proto.MetricsAtom;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.LongSummaryStatistics;
public class IwlanDataServiceTest {
private static final int DEFAULT_SLOT_INDEX = 0;
private static final int DEFAULT_SUB_INDEX = 0;
private static final int INVALID_SUB_INDEX = -1;
private static final int LINK_MTU = 1280;
private static final String TEST_APN_NAME = "ims";
private static final String IP_ADDRESS = "192.0.2.1";
private static final String DNS_ADDRESS = "8.8.8.8";
private static final String GATEWAY_ADDRESS = "0.0.0.0";
private static final String PSCF_ADDRESS = "10.159.204.230";
private static final String INTERFACE_NAME = "ipsec6";
@Mock private Context mMockContext;
@Mock private SubscriptionManager mMockSubscriptionManager;
@Mock private SubscriptionInfo mMockSubscriptionInfo;
@Mock private ContentResolver mMockContentResolver;
@Mock private ConnectivityManager mMockConnectivityManager;
@Mock private DataServiceCallback mMockDataServiceCallback;
@Mock private EpdgTunnelManager mMockEpdgTunnelManager;
@Mock private IwlanDataServiceProvider mMockIwlanDataServiceProvider;
@Mock private Network mMockNetwork;
@Mock private TunnelLinkProperties mMockTunnelLinkProperties;
@Mock private ErrorPolicyManager mMockErrorPolicyManager;
@Mock private ImsManager mMockImsManager;
@Mock private ImsMmTelManager mMockImsMmTelManager;
@Mock private TelephonyManager mMockTelephonyManager;
@Mock private EpdgSelector mMockEpdgSelector;
@Mock private LinkAddress mMockIPv4LinkAddress;
@Mock private LinkAddress mMockIPv6LinkAddress;
@Mock private Inet4Address mMockInet4Address;
@Mock private Inet6Address mMockInet6Address;
@Mock private CarrierConfigManager mMockCarrierConfigManager;
@Mock private FeatureFlags mFakeFeatureFlags;
MockitoSession mStaticMockSession;
private LinkProperties mLinkProperties;
private List<DataCallResponse> mResultDataCallList;
private @DataServiceCallback.ResultCode int mResultCode;
private IwlanDataService mIwlanDataService;
private IwlanDataServiceProvider mSpyIwlanDataServiceProvider;
private TestLooper mTestLooper = new TestLooper();
private long mMockedCalendarTime;
private ArgumentCaptor<NetworkCallback> mNetworkCallbackCaptor =
ArgumentCaptor.forClass(NetworkCallback.class);
private final class IwlanDataServiceCallback extends IDataServiceCallback.Stub {
private final String mTag;
IwlanDataServiceCallback(String tag) {
mTag = tag;
}
@Override
public void onSetupDataCallComplete(
@DataServiceCallback.ResultCode int resultCode, DataCallResponse response) {}
@Override
public void onDeactivateDataCallComplete(@DataServiceCallback.ResultCode int resultCode) {}
@Override
public void onSetInitialAttachApnComplete(@DataServiceCallback.ResultCode int resultCode) {}
@Override
public void onSetDataProfileComplete(@DataServiceCallback.ResultCode int resultCode) {}
@Override
public void onRequestDataCallListComplete(
@DataServiceCallback.ResultCode int resultCode,
List<DataCallResponse> dataCallList) {
mResultCode = resultCode;
mResultDataCallList = new ArrayList<DataCallResponse>(dataCallList);
}
@Override
public void onDataCallListChanged(List<DataCallResponse> dataCallList) {}
@Override
public void onHandoverStarted(@DataServiceCallback.ResultCode int result) {}
@Override
public void onHandoverCancelled(@DataServiceCallback.ResultCode int result) {}
@Override
public void onApnUnthrottled(String apn) {}
@Override
public void onDataProfileUnthrottled(DataProfile dataProfile) {}
}
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mStaticMockSession =
mockitoSession()
.mockStatic(EpdgSelector.class)
.mockStatic(EpdgTunnelManager.class)
.mockStatic(ErrorPolicyManager.class)
.mockStatic(IwlanBroadcastReceiver.class)
.mockStatic(SubscriptionManager.class)
.mockStatic(IwlanCarrierConfig.class)
.strictness(Strictness.LENIENT)
.startMocking();
when(mMockContext.getSystemService(eq(ConnectivityManager.class)))
.thenReturn(mMockConnectivityManager);
when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
.thenReturn(mMockSubscriptionManager);
doNothing()
.when(mMockConnectivityManager)
.registerSystemDefaultNetworkCallback(mNetworkCallbackCaptor.capture(), any());
when(EpdgTunnelManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX))
.thenReturn(mMockEpdgTunnelManager);
when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt()))
.thenReturn(mMockSubscriptionInfo);
when(mMockSubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DEFAULT_SUB_INDEX);
when(mMockSubscriptionManager.getSlotIndex(DEFAULT_SUB_INDEX))
.thenReturn(DEFAULT_SLOT_INDEX);
when(mMockSubscriptionManager.getSlotIndex(DEFAULT_SUB_INDEX + 1))
.thenReturn(DEFAULT_SLOT_INDEX + 1);
when(mMockSubscriptionInfo.getSubscriptionId()).thenReturn(DEFAULT_SUB_INDEX);
when(mMockContext.getSystemService(eq(TelephonyManager.class)))
.thenReturn(mMockTelephonyManager);
when(mMockTelephonyManager.createForSubscriptionId(eq(DEFAULT_SUB_INDEX)))
.thenReturn(mMockTelephonyManager);
when(mMockTelephonyManager.isNetworkRoaming()).thenReturn(false);
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
when(mMockContext.getSystemService(eq(ImsManager.class))).thenReturn(mMockImsManager);
when(mMockImsManager.getImsMmTelManager(anyInt())).thenReturn(mMockImsMmTelManager);
when(mMockImsMmTelManager.isVoWiFiSettingEnabled()).thenReturn(false);
when(EpdgSelector.getSelectorInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockEpdgSelector);
when(mMockIPv4LinkAddress.getAddress()).thenReturn(mMockInet4Address);
when(mMockIPv6LinkAddress.getAddress()).thenReturn(mMockInet6Address);
mIwlanDataService = spy(new IwlanDataService(mFakeFeatureFlags));
when(mMockContext.getSystemService(eq(CarrierConfigManager.class)))
.thenReturn(mMockCarrierConfigManager);
// Injects the test looper into the IwlanDataServiceHandler
doReturn(mTestLooper.getLooper()).when(mIwlanDataService).getLooper();
mIwlanDataService.setAppContext(mMockContext);
mSpyIwlanDataServiceProvider =
spy(
(IwlanDataServiceProvider)
mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX));
mTestLooper.dispatchAll();
when(Calendar.getInstance().getTime()).thenAnswer(i -> mMockedCalendarTime);
mLinkProperties = new LinkProperties();
mLinkProperties.setInterfaceName("wlan0");
mLinkProperties.addLinkAddress(mMockIPv4LinkAddress);
when(mMockConnectivityManager.getLinkProperties(eq(mMockNetwork)))
.thenReturn(mLinkProperties);
when(mMockTunnelLinkProperties.ifaceName()).thenReturn("mockipsec0");
}
private void moveTimeForwardAndDispatch(long milliSeconds) {
mTestLooper.moveTimeForward(milliSeconds);
mTestLooper.dispatchAll();
}
@After
public void cleanUp() throws Exception {
mStaticMockSession.finishMocking();
mSpyIwlanDataServiceProvider.close();
mTestLooper.dispatchAll();
if (mIwlanDataService != null) {
mIwlanDataService.onDestroy();
}
}
public Network createMockNetwork(LinkProperties linkProperties) {
Network network = mock(Network.class);
when(mMockConnectivityManager.getLinkProperties(eq(network))).thenReturn(linkProperties);
return network;
}
private NetworkCallback getNetworkMonitorCallback() {
return mNetworkCallbackCaptor.getValue();
}
private void onSystemDefaultNetworkConnected(
Network network, LinkProperties linkProperties, int transportType, int subId) {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
transportType,
subId /* unused if transportType is TRANSPORT_WIFI */,
false /* isVcn */);
NetworkCallback networkMonitorCallback = getNetworkMonitorCallback();
networkMonitorCallback.onCapabilitiesChanged(network, nc);
networkMonitorCallback.onLinkPropertiesChanged(network, linkProperties);
mTestLooper.dispatchAll();
}
private void onSystemDefaultNetworkConnected(int transportType) {
Network newNetwork = createMockNetwork(mLinkProperties);
onSystemDefaultNetworkConnected(
newNetwork, mLinkProperties, transportType, DEFAULT_SUB_INDEX);
}
private void onSystemDefaultNetworkLost() {
NetworkCallback networkMonitorCallback = getNetworkMonitorCallback();
networkMonitorCallback.onLost(mMockNetwork);
mTestLooper.dispatchAll();
}
@Test
public void testWifiOnConnected() {
onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
assertTrue(
mIwlanDataService.isNetworkConnected(
false /* isActiveDataOnOtherSub */, false /* isCstEnabled */));
}
@Test
public void testWifiOnLost() {
when(mMockIwlanDataServiceProvider.getSlotIndex()).thenReturn(DEFAULT_SLOT_INDEX + 1);
mIwlanDataService.addIwlanDataServiceProvider(mMockIwlanDataServiceProvider);
onSystemDefaultNetworkLost();
assertFalse(
mIwlanDataService.isNetworkConnected(
false /* isActiveDataOnOtherSub */, false /* isCstEnabled */));
verify(mMockIwlanDataServiceProvider).forceCloseTunnelsInDeactivatingState();
mIwlanDataService.removeDataServiceProvider(mMockIwlanDataServiceProvider);
mTestLooper.dispatchAll();
}
@Test
public void testWifiOnReconnected() {
Network newNetwork = createMockNetwork(mLinkProperties);
onSystemDefaultNetworkConnected(
newNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
verify(mMockEpdgTunnelManager, times(1)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
onSystemDefaultNetworkLost();
onSystemDefaultNetworkConnected(
newNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
verify(mMockEpdgTunnelManager, times(2)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
}
@Test
public void testOnLinkPropertiesChangedForConnectedNetwork() {
NetworkCallback networkCallback = getNetworkMonitorCallback();
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
clearInvocations(mMockEpdgTunnelManager);
LinkProperties newLinkProperties = new LinkProperties(mLinkProperties);
newLinkProperties.setInterfaceName("wlan0");
newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
verify(mMockEpdgTunnelManager, times(1))
.updateNetwork(eq(mMockNetwork), eq(newLinkProperties));
}
@Test
public void testOnLinkPropertiesChangedForNonConnectedNetwork() {
NetworkCallback networkCallback = getNetworkMonitorCallback();
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
clearInvocations(mMockEpdgTunnelManager);
LinkProperties newLinkProperties = new LinkProperties();
newLinkProperties.setInterfaceName("wlan0");
newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
Network newNetwork = createMockNetwork(newLinkProperties);
networkCallback.onLinkPropertiesChanged(newNetwork, newLinkProperties);
verify(mMockEpdgTunnelManager, never())
.updateNetwork(eq(newNetwork), any(LinkProperties.class));
}
@Test
public void testOnLinkPropertiesChangedWithClatInstalled() throws Exception {
NetworkCallback networkCallback = getNetworkMonitorCallback();
mLinkProperties.setLinkAddresses(
new ArrayList<>(Collections.singletonList(mMockIPv6LinkAddress)));
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
clearInvocations(mMockEpdgTunnelManager);
// LinkProperties#addStackedLink() is marked with @UnsupportedAppUsage
LinkProperties newLinkProperties = new LinkProperties(mLinkProperties);
newLinkProperties.setInterfaceName("wlan0");
LinkProperties stackedLink = new LinkProperties();
stackedLink.setInterfaceName("v4-wlan0");
stackedLink.addLinkAddress(mMockIPv4LinkAddress);
Class<?>[] parameterTypes = new Class<?>[] {LinkProperties.class};
Object[] args = new Object[] {stackedLink};
callUnsupportedAppUsageMethod(newLinkProperties, "addStackedLink", parameterTypes, args);
assertNotEquals(mLinkProperties, newLinkProperties);
networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
verify(mMockEpdgTunnelManager, times(1))
.updateNetwork(eq(mMockNetwork), eq(newLinkProperties));
}
@Test
public void testOnLinkPropertiesChangedForBringingUpIkeSession() {
DataProfile dp = buildImsDataProfile();
NetworkCallback networkCallback = getNetworkMonitorCallback();
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
clearInvocations(mMockEpdgTunnelManager);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
false /* isHandover */,
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
LinkProperties newLinkProperties = new LinkProperties(mLinkProperties);
newLinkProperties.setInterfaceName("wlan0");
newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
verify(mMockEpdgTunnelManager, times(1))
.updateNetwork(eq(mMockNetwork), eq(newLinkProperties));
verify(mMockEpdgTunnelManager, never())
.closeTunnel(any(), anyBoolean(), any(), any(), anyInt());
}
@Test
public void testNetworkNotConnectedWithCellularOnSameSubAndCrossSimEnabled()
throws InterruptedException {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
boolean isActiveDataOnOtherSub =
mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
assertFalse(isActiveDataOnOtherSub);
assertFalse(
mIwlanDataService.isNetworkConnected(
isActiveDataOnOtherSub, true /* isCstEnabled */));
}
@Test
public void testCrossSimNetworkConnectedWithCellularOnDifferentSub()
throws InterruptedException {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, false /* isVcn */);
getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
boolean isActiveDataOnOtherSub =
mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
assertTrue(isActiveDataOnOtherSub);
assertTrue(
mIwlanDataService.isNetworkConnected(
isActiveDataOnOtherSub, true /* isCstEnabled */));
}
@Test
public void testCrossSimNetworkConnectedWithVcnCellularOnDifferentSub()
throws InterruptedException {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, true /* isVcn */);
getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
boolean isActiveDataOnOtherSub =
mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
assertTrue(isActiveDataOnOtherSub);
assertTrue(
mIwlanDataService.isNetworkConnected(
isActiveDataOnOtherSub, true /* isCstEnabled */));
}
@Test
public void testOnCrossSimCallingEnable_doNotUpdateTunnelManagerIfCellularDataOnSameSub()
throws Exception {
when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
Network newNetwork = createMockNetwork(mLinkProperties);
onSystemDefaultNetworkConnected(
newNetwork, mLinkProperties, TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX);
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT,
DEFAULT_SLOT_INDEX,
0 /* unused */)
.sendToTarget();
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, never())
.updateNetwork(eq(newNetwork), any(LinkProperties.class));
}
@Test
public void testOnCrossSimCallingEnable_updateTunnelManagerIfCellularDataOnDifferentSub()
throws Exception {
when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
Network newNetwork = createMockNetwork(mLinkProperties);
onSystemDefaultNetworkConnected(
newNetwork, mLinkProperties, TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1);
verify(mMockEpdgTunnelManager, times(1)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT,
DEFAULT_SLOT_INDEX,
0 /* unused */)
.sendToTarget();
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, times(2)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
}
@Test
public void testOnCrossSimCallingEnable_doNotUpdateTunnelManagerIfNoNetwork() throws Exception {
when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
onSystemDefaultNetworkLost();
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT,
DEFAULT_SLOT_INDEX,
0 /* unused */)
.sendToTarget();
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, never())
.updateNetwork(any(Network.class), any(LinkProperties.class));
}
@Test
public void testOnEthernetConnection_doNotUpdateTunnelManager() throws Exception {
Network newNetwork = createMockNetwork(mLinkProperties);
onSystemDefaultNetworkConnected(
newNetwork, mLinkProperties, TRANSPORT_ETHERNET, DEFAULT_SUB_INDEX);
verify(mMockEpdgTunnelManager, never())
.updateNetwork(eq(newNetwork), any(LinkProperties.class));
}
@Test
public void testAddDuplicateDataServiceProviderThrows() throws Exception {
when(mMockIwlanDataServiceProvider.getSlotIndex()).thenReturn(DEFAULT_SLOT_INDEX);
assertThrows(
IllegalStateException.class,
() -> mIwlanDataService.addIwlanDataServiceProvider(mMockIwlanDataServiceProvider));
}
@Test
public void testRemoveDataServiceProvider() {
when(mMockIwlanDataServiceProvider.getSlotIndex()).thenReturn(DEFAULT_SLOT_INDEX);
mIwlanDataService.removeDataServiceProvider(mMockIwlanDataServiceProvider);
mTestLooper.dispatchAll();
verify(mIwlanDataService, times(1)).deinitNetworkCallback();
mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX);
mTestLooper.dispatchAll();
}
@Test
public void testRequestDataCallListPass() throws Exception {
DataProfile dp = buildImsDataProfile();
List<LinkAddress> mInternalAddressList;
List<InetAddress> mDNSAddressList;
List<InetAddress> mGatewayAddressList;
List<InetAddress> mPCSFAddressList;
IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
TunnelLinkProperties mLinkProperties = createTunnelLinkProperties();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
new DataServiceCallback(callback),
TunnelState.TUNNEL_UP,
mLinkProperties,
false, /* isHandover */
1, /* pduSessionId */
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
mTestLooper.dispatchAll();
assertEquals(mResultCode, DataServiceCallback.RESULT_SUCCESS);
assertEquals(mResultDataCallList.size(), 1);
for (DataCallResponse dataCallInfo : mResultDataCallList) {
assertEquals(dataCallInfo.getId(), TEST_APN_NAME.hashCode());
assertEquals(dataCallInfo.getLinkStatus(), DataCallResponse.LINK_STATUS_ACTIVE);
assertEquals(dataCallInfo.getProtocolType(), ApnSetting.PROTOCOL_IP);
assertEquals(dataCallInfo.getInterfaceName(), INTERFACE_NAME);
mInternalAddressList = dataCallInfo.getAddresses();
assertEquals(mInternalAddressList.size(), 1);
for (LinkAddress mLinkAddress : mInternalAddressList) {
assertEquals(mLinkAddress, new LinkAddress(InetAddress.getByName(IP_ADDRESS), 3));
}
mDNSAddressList = dataCallInfo.getDnsAddresses();
assertEquals(mDNSAddressList.size(), 1);
for (InetAddress mInetAddress : mDNSAddressList) {
assertEquals(mInetAddress, InetAddress.getByName(DNS_ADDRESS));
}
mGatewayAddressList = dataCallInfo.getGatewayAddresses();
assertEquals(mGatewayAddressList.size(), 1);
for (InetAddress mInetAddress : mGatewayAddressList) {
assertEquals(mInetAddress, Inet4Address.getByName(GATEWAY_ADDRESS));
}
mPCSFAddressList = dataCallInfo.getPcscfAddresses();
assertEquals(mPCSFAddressList.size(), 1);
for (InetAddress mInetAddress : mPCSFAddressList) {
assertEquals(mInetAddress, InetAddress.getByName(PSCF_ADDRESS));
}
assertEquals(dataCallInfo.getMtuV4(), LINK_MTU);
assertEquals(dataCallInfo.getMtuV6(), LINK_MTU);
}
}
@Test
public void testRequestDataCallListEmpty() throws Exception {
IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
mSpyIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
mTestLooper.dispatchAll();
assertEquals(mResultCode, DataServiceCallback.RESULT_SUCCESS);
assertEquals(mResultDataCallList.size(), 0);
}
@Test
public void testIwlanSetupDataCallWithInvalidArg() {
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.UNKNOWN, /* AccessNetworkType */
null, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
2, /* pdu session id */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, timeout(1000).times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG), isNull());
}
@Test
public void testIwlanSetupDataCallWithIllegalState() {
DataProfile dp = buildImsDataProfile();
/* Wifi is not connected */
onSystemDefaultNetworkLost();
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pdu session id */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, timeout(1000).times(1))
.onSetupDataCallComplete(
eq(5 /*DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */),
isNull());
}
@Test
public void testIwlanDeactivateDataCallWithInvalidArg() {
mSpyIwlanDataServiceProvider.deactivateDataCall(
0, /* cid */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, timeout(1000).times(1))
.onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG));
}
@Test
public void testIwlanSetupDataCallWithBringUpTunnel() {
DataProfile dp = buildImsDataProfile();
/* Wifi is connected */
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
/* Check bringUpTunnel() is called. */
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(
any(TunnelSetupRequest.class),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class));
/* Check callback result is RESULT_SUCCESS when onOpened() is called. */
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
}
@Test
public void testIwlanSetupDataCallWithBringUpTunnelAndNullApnSetting() {
DataProfile dp = buildImsDataProfileWithEmptyApnSetting();
/* Wifi is connected */
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG), isNull());
}
@Test
public void testSliceInfoInclusionInDataCallResponse() throws Exception {
DataProfile dp = buildImsDataProfile();
/* Wifi is connected */
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
/* Check bringUpTunnel() is called. */
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(
any(TunnelSetupRequest.class),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class));
/* Check callback result is RESULT_SUCCESS when onOpened() is called. */
TunnelLinkProperties tp = createTunnelLinkProperties();
ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
ArgumentCaptor.forClass(DataCallResponse.class);
mSpyIwlanDataServiceProvider.getIwlanTunnelCallback().onOpened(TEST_APN_NAME, tp);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
/* check that sliceinfo is filled up and matches */
DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
assertNotNull(dataCallResponse.getSliceInfo());
assertEquals(dataCallResponse.getSliceInfo(), tp.sliceInfo().get());
}
@Test
public void testIwlanDeactivateDataCallWithCloseTunnel() {
DataProfile dp = buildImsDataProfile();
onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
false, /* isHandover */
1, /* pduSessionId */
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.deactivateDataCall(
TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
DataService.REQUEST_REASON_NORMAL,
mMockDataServiceCallback);
mTestLooper.dispatchAll();
/* Check closeTunnel() is called. */
verify(mMockEpdgTunnelManager, times(1))
.closeTunnel(
eq(TEST_APN_NAME),
eq(false),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(BRINGDOWN_REASON_DEACTIVATE_DATA_CALL));
/* Check callback result is RESULT_SUCCESS when onClosed() is called. */
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
}
@Test
public void testDeactivateDataCall_ImmediateReleaseAfterHandover() {
DataProfile dp = buildImsDataProfile();
onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_UP,
null, /* linkProperties */
false, /* isHandover */
1, /* pduSessionId */
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.deactivateDataCall(
TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
DataService.REQUEST_REASON_HANDOVER,
mMockDataServiceCallback);
mTestLooper.dispatchAll();
moveTimeForwardAndDispatch(50);
/* Check closeTunnel() is called. */
verify(mMockEpdgTunnelManager, times(1))
.closeTunnel(
eq(TEST_APN_NAME),
eq(true) /* forceClose */,
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(BRINGDOWN_REASON_DEACTIVATE_DATA_CALL));
/* Check callback result is RESULT_SUCCESS when onClosed() is called. */
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
}
@Test
public void testDeactivateDataCall_DelayedReleaseAfterHandover() {
DataProfile dp = buildImsDataProfile();
when(IwlanCarrierConfig.getConfigInt(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT))
.thenReturn(3);
onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_UP,
null, /* linkProperties */
false, /* isHandover */
1, /* pduSessionId */
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.deactivateDataCall(
TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
DataService.REQUEST_REASON_HANDOVER,
mMockDataServiceCallback);
mTestLooper.dispatchAll();
moveTimeForwardAndDispatch(2950);
/* Check closeTunnel() is called. */
verify(mMockEpdgTunnelManager, never())
.closeTunnel(
eq(TEST_APN_NAME),
anyBoolean(),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(BRINGDOWN_REASON_DEACTIVATE_DATA_CALL));
moveTimeForwardAndDispatch(50);
/* Check closeTunnel() is called. */
verify(mMockEpdgTunnelManager, times(1))
.closeTunnel(
eq(TEST_APN_NAME),
eq(true) /* forceClose */,
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(BRINGDOWN_REASON_DEACTIVATE_DATA_CALL));
/* Check callback result is RESULT_SUCCESS when onClosed() is called. */
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
}
@Test
public void testDeactivateDataCall_DelayedReleaseAfterHandover_NetworkReleaseBeforeDelay() {
DataProfile dp = buildImsDataProfile();
when(IwlanCarrierConfig.getConfigInt(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT))
.thenReturn(3);
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.NONE);
onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_UP,
null, /* linkProperties */
false, /* isHandover */
1, /* pduSessionId */
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, /* type IMS */
true,
13, /* LTE */
false,
true,
1 /* Transport WiFi */);
mSpyIwlanDataServiceProvider.deactivateDataCall(
TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
DataService.REQUEST_REASON_HANDOVER,
mMockDataServiceCallback);
mTestLooper.dispatchAll();
moveTimeForwardAndDispatch(50);
/* Check closeTunnel() is called. */
verify(mMockEpdgTunnelManager, never())
.closeTunnel(
eq(TEST_APN_NAME),
anyBoolean(),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
anyInt());
/* Check callback result is RESULT_SUCCESS when onClosed() is called. */
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG));
moveTimeForwardAndDispatch(4000);
verify(mMockEpdgTunnelManager, never())
.closeTunnel(
eq(TEST_APN_NAME),
anyBoolean(),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
anyInt());
// No additional callbacks are involved.
verify(mMockDataServiceCallback, times(1)).onDeactivateDataCallComplete(anyInt());
}
@Test
public void testHandoverFailureModeDefault() {
DataProfile dp = buildImsDataProfile();
int setupDataReason = DataService.REQUEST_REASON_NORMAL;
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getRemainingRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(5L);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.USER_AUTHENTICATION);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
(setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, // type IMS
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
ArgumentCaptor.forClass(DataCallResponse.class);
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
assertEquals(
dataCallResponse.getHandoverFailureMode(),
DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY);
assertEquals(dataCallResponse.getCause(), DataFailCause.USER_AUTHENTICATION);
assertEquals(dataCallResponse.getRetryDurationMillis(), 5L);
}
@Test
public void testHandoverFailureModeHandover() {
DataProfile dp = buildImsDataProfile();
int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getRemainingRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
.thenReturn(false);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
(setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, // type IMS
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
ArgumentCaptor.forClass(DataCallResponse.class);
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
assertEquals(
dataCallResponse.getHandoverFailureMode(),
DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER);
assertEquals(dataCallResponse.getCause(), DataFailCause.ERROR_UNSPECIFIED);
assertEquals(dataCallResponse.getRetryDurationMillis(), -1L);
}
@Test
public void testSupportInitialAttachSuccessOnIms() {
DataProfile dp = buildImsDataProfile();
int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getRemainingRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
.thenReturn(true);
// APN = IMS, in idle call state
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CALL_STATE_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
CALL_STATE_IDLE)
.sendToTarget();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
(setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, // type IMS
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
ArgumentCaptor.forClass(DataCallResponse.class);
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
// Not on video or voice call
assertEquals(
DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL,
dataCallResponse.getHandoverFailureMode());
}
@Test
public void testSupportInitialAttachSuccessOnEmergency() {
DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getRemainingRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
.thenReturn(true);
// APN = Emergency, in idle call state
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CALL_STATE_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
CALL_STATE_IDLE)
.sendToTarget();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
(setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
512, // type Emergency
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
ArgumentCaptor.forClass(DataCallResponse.class);
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
// Not on video or voice call
assertEquals(
DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL,
dataCallResponse.getHandoverFailureMode());
}
@Test
public void testSupportInitialAttachOnImsCall() {
DataProfile dp = buildImsDataProfile();
int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getRemainingRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
.thenReturn(true);
// APN = IMS, in call
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CALL_STATE_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
TelephonyManager.CALL_STATE_OFFHOOK)
.sendToTarget();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null /* linkProperties */,
(setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, // type IMS
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
ArgumentCaptor.forClass(DataCallResponse.class);
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
// In call state
assertEquals(
DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER,
dataCallResponse.getHandoverFailureMode());
}
@Test
public void testSupportInitialAttachOnEmergencyCall() {
DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getRemainingRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
.thenReturn(true);
// APN = Emergency, in call
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CALL_STATE_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
TelephonyManager.CALL_STATE_OFFHOOK)
.sendToTarget();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null /* linkProperties */,
(setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
512, // type Emergency
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
ArgumentCaptor.forClass(DataCallResponse.class);
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
// In call state
assertEquals(
DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER,
dataCallResponse.getHandoverFailureMode());
}
@Test
public void testDnsPrefetching() throws Exception {
NetworkCallback networkCallback = getNetworkMonitorCallback();
/* Wifi is connected */
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
networkCallback.onLinkPropertiesChanged(mMockNetwork, mLinkProperties);
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
0 /* unused */)
.sendToTarget();
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.WIFI_CALLING_ENABLE_EVENT,
DEFAULT_SLOT_INDEX,
0 /* unused */)
.sendToTarget();
mTestLooper.dispatchAll();
LinkProperties newLinkProperties = new LinkProperties();
newLinkProperties.setInterfaceName("wlan0");
newLinkProperties.addLinkAddress(mMockIPv4LinkAddress);
newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
/* Prefetching will be triggered twice.
1. Network connected, CarrierConfig ready, WifiCallingSetting enabled
2. Connection ipFamily changed.
*/
verify(mMockEpdgSelector, times(2))
.getValidatedServerList(
eq(0),
eq(EpdgSelector.PROTO_FILTER_IPV4V6),
eq(EpdgSelector.SYSTEM_PREFERRED),
eq(false),
eq(false),
eq(mMockNetwork),
isNull());
verify(mMockEpdgSelector, times(2))
.getValidatedServerList(
eq(0),
eq(EpdgSelector.PROTO_FILTER_IPV4V6),
eq(EpdgSelector.SYSTEM_PREFERRED),
eq(false),
eq(true),
eq(mMockNetwork),
isNull());
}
private void advanceCalendarByTimeMs(long time, Calendar calendar) {
mMockedCalendarTime += time;
if (calendar != null) {
calendar.setTimeInMillis(mMockedCalendarTime);
}
mTestLooper.dispatchAll();
}
private DataProfile buildImsDataProfileWithEmptyApnSetting() {
return new DataProfile.Builder()
.setTrafficDescriptor(
new TrafficDescriptor.Builder().setDataNetworkName("").build())
.setType(1)
.enable(true)
.setPreferred(true)
.build();
}
private DataProfile buildImsDataProfile() {
return buildDataProfile(ApnSetting.TYPE_IMS);
}
private DataProfile buildDataProfile(int supportedApnTypesBitmask) {
return new DataProfile.Builder()
.setApnSetting(
new ApnSetting.Builder()
.setProfileId(1)
.setEntryName(TEST_APN_NAME)
.setApnName(TEST_APN_NAME)
.setProtocol(ApnSetting.PROTOCOL_IPV4V6)
.setAuthType(ApnSetting.AUTH_TYPE_NONE)
.setUser("")
.setPassword("")
.setApnTypeBitmask(supportedApnTypesBitmask)
.setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
.setNetworkTypeBitmask(
(int) TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)
.setPersistent(true)
.build())
.setType(1) // 3gpp
.enable(true)
.setPreferred(true)
.build();
}
private NetworkCapabilities prepareNetworkCapabilitiesForTest(
int transportType, int subId, boolean isVcn) {
NetworkCapabilities.Builder builder =
new NetworkCapabilities.Builder().addTransportType(transportType);
if (isVcn) {
builder.setTransportInfo(new VcnTransportInfo(subId));
} else {
builder.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId));
}
return builder.build();
}
@Test
public void testIwlanSetupDataCallFailsWithCellularAndCstDisabled() throws Exception {
DataProfile dp = buildImsDataProfile();
/* CST is disabled, and data is on the same sub as the data service provider */
when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(false);
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pdu session id */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, timeout(1000).times(1))
.onSetupDataCallComplete(
eq(5 /* DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */),
isNull());
}
@Test
public void testIwlanSetupDataCallFailsWithCellularOnSameSubAndCstEnabled() throws Exception {
DataProfile dp = buildImsDataProfile();
/* CST is enabled, but data is on the same sub as the DataServiceProvider */
when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, timeout(1000).times(1))
.onSetupDataCallComplete(
eq(5 /* DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */),
isNull());
}
@Test
public void testIwlanSetupDataCallSucceedsWithCellularOnDifferentSubAndCstEnabled()
throws Exception {
DataProfile dp = buildImsDataProfile();
/* CST is enabled, but data is on the same sub as the DataServiceProvider */
when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, false /* isVcn */);
getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
/* Check bringUpTunnel() is called. */
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(
any(TunnelSetupRequest.class),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class));
/* Check callback result is RESULT_SUCCESS when onOpened() is called. */
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, times(1))
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
}
@Test
public void testIwlanTunnelStatsFailureCounts() {
DataProfile dp = buildImsDataProfile();
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
long count = 3L;
for (int i = 0; i < count; i++) {
mockTunnelSetupFail(dp);
mTestLooper.dispatchAll();
}
IwlanDataServiceProvider.IwlanDataTunnelStats stats =
mSpyIwlanDataServiceProvider.getTunnelStats();
long result = stats.mTunnelSetupFailureCounts.get(TEST_APN_NAME);
assertEquals(result, count);
}
@Test
public void testIwlanTunnelStatsUnsolDownCounts() {
DataProfile dp = buildImsDataProfile();
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
long count = 3L;
for (int i = 0; i < count; i++) {
mockTunnelSetupSuccess(dp, 0, null);
mockUnsolTunnelDown();
}
IwlanDataServiceProvider.IwlanDataTunnelStats stats =
mSpyIwlanDataServiceProvider.getTunnelStats();
long result = stats.mUnsolTunnelDownCounts.get(TEST_APN_NAME);
assertEquals(result, count);
}
@Test
public void testIwlanTunnelStats() {
DataProfile dp = buildImsDataProfile();
Calendar calendar = mock(Calendar.class);
when(calendar.getTime()).thenAnswer(i -> new Date(mMockedCalendarTime));
mSpyIwlanDataServiceProvider.setCalendar(calendar);
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
LongSummaryStatistics tunnelSetupSuccessStats = new LongSummaryStatistics();
LongSummaryStatistics tunnelUpStats = new LongSummaryStatistics();
Date beforeSetup = calendar.getTime();
mockTunnelSetupSuccess(dp, 0, calendar);
Date tunnelUp = calendar.getTime();
mockDeactivateTunnel(0, calendar);
Date tunnelDown = calendar.getTime();
tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
beforeSetup = calendar.getTime();
mockTunnelSetupSuccess(dp, 1000, calendar);
tunnelUp = calendar.getTime();
mockDeactivateTunnel(3000, calendar);
tunnelDown = calendar.getTime();
tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
beforeSetup = calendar.getTime();
mockTunnelSetupSuccess(dp, 600, calendar);
tunnelUp = calendar.getTime();
mockDeactivateTunnel(500, calendar);
tunnelDown = calendar.getTime();
tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
IwlanDataServiceProvider.IwlanDataTunnelStats stats =
mSpyIwlanDataServiceProvider.getTunnelStats();
LongSummaryStatistics finalSetupStats = stats.mTunnelSetupSuccessStats.get(TEST_APN_NAME);
LongSummaryStatistics finalUpStats = stats.mTunnelUpStats.get(TEST_APN_NAME);
assertEquals(tunnelSetupSuccessStats.getAverage(), finalSetupStats.getAverage(), 0);
assertEquals(tunnelSetupSuccessStats.getCount(), finalSetupStats.getCount());
assertEquals(tunnelSetupSuccessStats.getMax(), finalSetupStats.getMax(), 0);
assertEquals(tunnelUpStats.getAverage(), finalUpStats.getAverage(), 0);
assertEquals(tunnelUpStats.getCount(), finalUpStats.getCount());
assertEquals(tunnelUpStats.getMax(), finalUpStats.getMax(), 0);
}
@Test
public void testUnexpectedTunnelClosedIsSuppressed() {
mockUnsolTunnelDown();
}
@Test
public void testIwlanDataServiceHandlerOnUnbind() {
DataProfile dp = buildImsDataProfile();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_UP,
null /* linkProperties */,
false /* isHandover */,
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, // type IMS
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
// Simulate IwlanDataService.onUnbind() which force close all tunnels
mSpyIwlanDataServiceProvider.forceCloseTunnels(EpdgTunnelManager.BRINGDOWN_REASON_UNKNOWN);
// Simulate DataService.onUnbind() which remove all IwlanDataServiceProviders
mSpyIwlanDataServiceProvider.close();
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, atLeastOnce())
.closeTunnel(
eq(TEST_APN_NAME),
eq(true),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(EpdgTunnelManager.BRINGDOWN_REASON_UNKNOWN));
assertNotNull(mIwlanDataService.mIwlanDataServiceHandler);
// Should not raise NullPointerException
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
}
@Test
public void testBackToBackOnBindAndOnUnbindDoesNotThrow() {
mIwlanDataService.onBind(null);
mIwlanDataService.onUnbind(null);
}
@Test
public void testMetricsWhenTunnelClosedWithWrappedException() {
DataProfile dp = buildImsDataProfile();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
false /* isHandover */,
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, // type IMS
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
MetricsAtom metricsAtom = mSpyIwlanDataServiceProvider.getMetricsAtomByApn(TEST_APN_NAME);
assertNotNull(metricsAtom);
String exceptionMessage = "Some exception message";
Exception mockException = spy(new IllegalStateException(exceptionMessage));
String firstDeclaringClassName = "test.test.TestClass";
String firstMethodName = "someMethod";
String firstFileName = "TestClass.java";
int firstLineNumber = 12345;
StackTraceElement[] stackTraceElements = {
new StackTraceElement(
firstDeclaringClassName, firstMethodName, firstFileName, firstLineNumber),
new StackTraceElement("test", "test", "test.java", 123)
};
doReturn(stackTraceElements).when(mockException).getStackTrace();
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(new IkeInternalException(mockException)));
mTestLooper.dispatchAll();
var expectedStackFirstFrame =
firstDeclaringClassName
+ "."
+ firstMethodName
+ "("
+ firstFileName
+ ":"
+ firstLineNumber
+ ")";
assertEquals(
mockException.getClass().getCanonicalName(),
metricsAtom.getIwlanErrorWrappedClassname());
assertEquals(expectedStackFirstFrame, metricsAtom.getIwlanErrorWrappedStackFirstFrame());
}
@Test
public void testMetricsWhenTunnelClosedWithoutWrappedException() {
DataProfile dp = buildImsDataProfile();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
false /* isHandover */,
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, // type IMS
true,
13, // LTE
false,
true,
1 // Transport Wi-Fi
);
MetricsAtom metricsAtom = mSpyIwlanDataServiceProvider.getMetricsAtomByApn(TEST_APN_NAME);
assertNotNull(metricsAtom);
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(
TEST_APN_NAME,
new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED));
mTestLooper.dispatchAll();
assertEquals(null, metricsAtom.getIwlanErrorWrappedClassname());
assertEquals(null, metricsAtom.getIwlanErrorWrappedStackFirstFrame());
}
@Test
public void testMetricsWhenTunnelClosedWithErrorCount() {
DataProfile dp = buildImsDataProfile();
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
TunnelState.TUNNEL_IN_BRINGUP,
null, /* linkProperties */
false /* isHandover */,
1 /* pduSessionId */,
true /* isImsOrEmergency */,
true /* isDataCallSetupWithN1 */);
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME,
64, /* type IMS */
true,
13, /* LTE */
false,
true,
1 /* Transport Wi-Fi */);
MetricsAtom metricsAtom = mSpyIwlanDataServiceProvider.getMetricsAtomByApn(TEST_APN_NAME);
assertNotNull(metricsAtom);
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
when(mMockErrorPolicyManager.getLastErrorCountOfSameCause(eq(TEST_APN_NAME))).thenReturn(5);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.IKE_PROTOCOL_EXCEPTION));
mTestLooper.dispatchAll();
assertEquals(5, metricsAtom.getErrorCountOfSameCause());
}
private void mockTunnelSetupFail(DataProfile dp) {
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
doReturn(true)
.when(mMockEpdgTunnelManager)
.bringUpTunnel(
any(TunnelSetupRequest.class),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class));
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION));
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, atLeastOnce())
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
}
private void mockTunnelSetupSuccess(DataProfile dp, long setupTime, Calendar calendar) {
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
doReturn(true)
.when(mMockEpdgTunnelManager)
.bringUpTunnel(
any(TunnelSetupRequest.class),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class));
mTestLooper.dispatchAll();
advanceCalendarByTimeMs(setupTime, calendar);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, atLeastOnce())
.onSetupDataCallComplete(
eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
}
private void mockUnsolTunnelDown() {
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION));
mTestLooper.dispatchAll();
}
private void mockDeactivateTunnel(long deactivationTime, Calendar calendar) {
mSpyIwlanDataServiceProvider.deactivateDataCall(
TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
DataService.REQUEST_REASON_NORMAL /* DataService.REQUEST_REASON_NORMAL */,
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, atLeastOnce())
.closeTunnel(
eq(TEST_APN_NAME),
anyBoolean(),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(BRINGDOWN_REASON_DEACTIVATE_DATA_CALL));
advanceCalendarByTimeMs(deactivationTime, calendar);
mSpyIwlanDataServiceProvider
.getIwlanTunnelCallback()
.onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
mTestLooper.dispatchAll();
verify(mMockDataServiceCallback, atLeastOnce())
.onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
}
private Object callUnsupportedAppUsageMethod(
Object target, String methodName, Class<?>[] parameterTypes, Object[] args)
throws Exception {
Method method = target.getClass().getDeclaredMethod(methodName, parameterTypes);
method.setAccessible(true);
return method.invoke(target, args);
}
@Test
public void testNetworkChangeDuringTunnelBringUp_closeTunnel() {
DataProfile dp = buildImsDataProfile();
Network newNetwork1 = createMockNetwork(mLinkProperties);
onSystemDefaultNetworkConnected(
newNetwork1, mLinkProperties, TRANSPORT_WIFI, DEFAULT_SUB_INDEX);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
true, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
1, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
/* Check bringUpTunnel() is called. */
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(
any(TunnelSetupRequest.class),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class));
Network newNetwork2 = createMockNetwork(mLinkProperties);
onSystemDefaultNetworkConnected(
newNetwork2, mLinkProperties, TRANSPORT_WIFI, DEFAULT_SUB_INDEX);
verify(mMockEpdgTunnelManager, times(1))
.closeTunnel(
any(),
anyBoolean(),
any(),
any(),
eq(BRINGDOWN_REASON_NETWORK_UPDATE_WHEN_TUNNEL_IN_BRINGUP));
}
public static TunnelLinkProperties createTunnelLinkProperties() throws Exception {
final String IP_ADDRESS = "192.0.2.1";
final String DNS_ADDRESS = "8.8.8.8";
final String PSCF_ADDRESS = "10.159.204.230";
final String INTERFACE_NAME = "ipsec6";
final NetworkSliceInfo SLICE_INFO =
NetworkSliceSelectionAssistanceInformation.getSliceInfo(new byte[] {1});
List<LinkAddress> mInternalAddressList = new ArrayList<>();
List<InetAddress> mDNSAddressList = new ArrayList<>();
List<InetAddress> mPCSFAddressList = new ArrayList<>();
mInternalAddressList.add(new LinkAddress(InetAddress.getByName(IP_ADDRESS), 3));
mDNSAddressList.add(InetAddress.getByName(DNS_ADDRESS));
mPCSFAddressList.add(InetAddress.getByName(PSCF_ADDRESS));
return TunnelLinkProperties.builder()
.setInternalAddresses(mInternalAddressList)
.setDnsAddresses(mDNSAddressList)
.setPcscfAddresses(mPCSFAddressList)
.setIfaceName(INTERFACE_NAME)
.setSliceInfo(SLICE_INFO)
.build();
}
private void setupMockForGetConfig(PersistableBundle bundle) {
if (bundle == null) {
bundle = new PersistableBundle();
}
when(mMockContext.getSystemService(eq(CarrierConfigManager.class)))
.thenReturn(mMockCarrierConfigManager);
when(mMockCarrierConfigManager.getConfigForSubId(DEFAULT_SLOT_INDEX)).thenReturn(bundle);
}
private void mockCarrierConfigForN1Mode(boolean supportN1Mode) {
PersistableBundle bundle = new PersistableBundle();
if (supportN1Mode) {
bundle.putIntArray(
CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY,
new int[] {
CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA,
CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA
});
} else {
bundle.putIntArray(
CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY,
new int[] {CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA});
}
setupMockForGetConfig(bundle);
}
private void mockCallState(int callState) {
onSystemDefaultNetworkConnected(TRANSPORT_CELLULAR);
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CALL_STATE_CHANGED_EVENT, DEFAULT_SLOT_INDEX, callState)
.sendToTarget();
mSpyIwlanDataServiceProvider.setMetricsAtom(
TEST_APN_NAME, 64, true, TelephonyManager.NETWORK_TYPE_LTE, false, true, 1);
}
private void updatePreferredNetworkType(long networkTypeBitmask) {
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.PREFERRED_NETWORK_TYPE_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
0 /* unused */,
networkTypeBitmask)
.sendToTarget();
mTestLooper.dispatchAll();
}
@Test
public void testIsN1ModeSupported() {
PersistableBundle bundle = new PersistableBundle();
bundle.putIntArray(
CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY,
new int[] {
CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA,
CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA
});
setupMockForGetConfig(bundle);
assertTrue(mSpyIwlanDataServiceProvider.isN1ModeSupported());
bundle.putIntArray(
CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY,
new int[] {
CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA,
});
setupMockForGetConfig(bundle);
assertFalse(mSpyIwlanDataServiceProvider.isN1ModeSupported());
}
@Test
public void testMultipleAllowedNetworkTypeChangeInIdle_updateN1Mode() throws Exception {
mockCarrierConfigForN1Mode(true);
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL))
.thenReturn(true);
mockCallState(CALL_STATE_IDLE);
mockSetupDataCallWithPduSessionId(0);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_NR);
/* Check closeTunnel() is called. */
verify(mMockEpdgTunnelManager, atLeastOnce())
.closeTunnel(
eq(TEST_APN_NAME),
eq(true),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(EpdgTunnelManager.BRINGDOWN_REASON_ENABLE_N1_MODE));
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_LTE);
verify(mMockEpdgTunnelManager, atLeastOnce())
.closeTunnel(
eq(TEST_APN_NAME),
eq(true),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(EpdgTunnelManager.BRINGDOWN_REASON_DISABLE_N1_MODE));
}
@Test
public void testMultipleAllowedNetworkTypeChangeInCall_preferenceChanged_updateAfterCallEnds()
throws Exception {
mockCarrierConfigForN1Mode(true);
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL))
.thenReturn(true);
mockCallState(CALL_STATE_RINGING);
mockSetupDataCallWithPduSessionId(0);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_NR);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_LTE);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_NR);
verify(mMockEpdgTunnelManager, never())
.closeTunnel(any(), anyBoolean(), any(), any(), anyInt());
// in idle call state
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CALL_STATE_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
CALL_STATE_IDLE)
.sendToTarget();
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, atLeastOnce())
.closeTunnel(
eq(TEST_APN_NAME),
eq(true),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class),
eq(EpdgTunnelManager.BRINGDOWN_REASON_ENABLE_N1_MODE));
}
@Test
public void testMultipleAllowedNetworkTypeChangeInCall_preferenceNotChanged_noUpdate()
throws Exception {
mockCarrierConfigForN1Mode(true);
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL))
.thenReturn(true);
mockCallState(CALL_STATE_RINGING);
mockSetupDataCallWithPduSessionId(0);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_NR);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_LTE);
verify(mMockEpdgTunnelManager, never())
.closeTunnel(any(), anyBoolean(), any(), any(), anyInt());
// in idle call state
mIwlanDataService
.mIwlanDataServiceHandler
.obtainMessage(
IwlanEventListener.CALL_STATE_CHANGED_EVENT,
DEFAULT_SLOT_INDEX,
CALL_STATE_IDLE)
.sendToTarget();
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, never())
.closeTunnel(any(), anyBoolean(), any(), any(), anyInt());
}
@Test
public void testOnAllowedNetworkTypeChange_flagDisabled_noTunnelClose() {
mockCarrierConfigForN1Mode(true);
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL))
.thenReturn(false);
mockCallState(CALL_STATE_IDLE);
mockSetupDataCallWithPduSessionId(0);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_NR);
verify(mMockEpdgTunnelManager, never())
.closeTunnel(any(), anyBoolean(), any(), any(), anyInt());
}
@Test
public void testOnAllowedNetworkTypeChange_n1ModeNotSupported_noTunnelClose() {
mockCarrierConfigForN1Mode(false);
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL))
.thenReturn(true);
mockCallState(CALL_STATE_IDLE);
mockSetupDataCallWithPduSessionId(0);
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_NR);
verify(mMockEpdgTunnelManager, never())
.closeTunnel(any(), anyBoolean(), any(), any(), anyInt());
}
@Test
public void testN1ModeNotSupported_tunnelBringupWithNoN1ModeCapability() {
mockCarrierConfigForN1Mode(false);
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL))
.thenReturn(true);
mockSetupDataCallWithPduSessionId(1);
ArgumentCaptor<TunnelSetupRequest> tunnelSetupRequestCaptor =
ArgumentCaptor.forClass(TunnelSetupRequest.class);
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(tunnelSetupRequestCaptor.capture(), any(), any());
TunnelSetupRequest tunnelSetupRequest = tunnelSetupRequestCaptor.getValue();
assertEquals(PDU_SESSION_ID_UNSET, tunnelSetupRequest.getPduSessionId());
}
@Test
public void testNoN1ModeCapabilityInOngoingDataCall_newTunnelBringup_doNotIncludeN1() {
mockCarrierConfigForN1Mode(true);
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL))
.thenReturn(true);
mockSetupDataCallWithPduSessionId(0);
ArgumentCaptor<TunnelSetupRequest> tunnelSetupRequestCaptor =
ArgumentCaptor.forClass(TunnelSetupRequest.class);
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(tunnelSetupRequestCaptor.capture(), any(), any());
TunnelSetupRequest tunnelSetupRequest = tunnelSetupRequestCaptor.getValue();
assertEquals(PDU_SESSION_ID_UNSET, tunnelSetupRequest.getPduSessionId());
updatePreferredNetworkType(NETWORK_TYPE_BITMASK_NR);
mockSetupDataCallWithPduSessionId(1);
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(tunnelSetupRequestCaptor.capture(), any(), any());
tunnelSetupRequest = tunnelSetupRequestCaptor.getValue();
assertEquals(PDU_SESSION_ID_UNSET, tunnelSetupRequest.getPduSessionId());
}
private void mockSetupDataCallWithPduSessionId(int pduSessionId) {
DataProfile dp = buildImsDataProfile();
verifySetupDataCallRequestHandled(pduSessionId, dp);
}
private void verifySetupDataCallRequestHandled(int pduSessionId, DataProfile dp) {
onSystemDefaultNetworkConnected(
mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
false, /* allowRoaming */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
null, /* LinkProperties */
pduSessionId, /* pduSessionId */
null, /* sliceInfo */
null, /* trafficDescriptor */
true, /* matchAllRuleAllowed */
mMockDataServiceCallback);
mTestLooper.dispatchAll();
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(
any(TunnelSetupRequest.class),
any(IwlanTunnelCallback.class),
any(IwlanTunnelMetricsImpl.class));
}
@Test
public void testN1ModeForEmergencySession() {
int pduSessionId = 5;
DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
verifySetupDataCallRequestHandled(pduSessionId, dp);
ArgumentCaptor<TunnelSetupRequest> tunnelSetupRequestCaptor =
ArgumentCaptor.forClass(TunnelSetupRequest.class);
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(tunnelSetupRequestCaptor.capture(), any(), any());
TunnelSetupRequest tunnelSetupRequest = tunnelSetupRequestCaptor.getValue();
assertEquals(pduSessionId, tunnelSetupRequest.getPduSessionId());
}
@Test
public void testN1ModeExclusionForEmergencySession() {
when(IwlanCarrierConfig.getConfigBoolean(
mMockContext,
DEFAULT_SLOT_INDEX,
IwlanCarrierConfig.KEY_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL))
.thenReturn(true);
DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
verifySetupDataCallRequestHandled(5 /* pduSessionId */, dp);
ArgumentCaptor<TunnelSetupRequest> tunnelSetupRequestCaptor =
ArgumentCaptor.forClass(TunnelSetupRequest.class);
verify(mMockEpdgTunnelManager, times(1))
.bringUpTunnel(tunnelSetupRequestCaptor.capture(), any(), any());
TunnelSetupRequest tunnelSetupRequest = tunnelSetupRequestCaptor.getValue();
assertEquals(PDU_SESSION_ID_UNSET, tunnelSetupRequest.getPduSessionId());
}
}