summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-05-26 10:25:26 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-05-26 10:25:26 +0000
commit80c5091aae7eeb09c612befa55f20270131e69ea (patch)
tree01f3bf91a28d0e93be016189e68f497e78f6171b
parent7d7dc36d06218175626ede05e82da67cf669173e (diff)
parent260b35cd35a643a9de93747c6e5429f57a607d03 (diff)
downloadIwlan-80c5091aae7eeb09c612befa55f20270131e69ea.tar.gz
Snap for 10209341 from 260b35cd35a643a9de93747c6e5429f57a607d03 to mainline-healthfitness-release
Change-Id: I0518ca4aae9104890b8138fdebaa07c63ba1c0f1
-rw-r--r--AndroidManifest.xml1
-rw-r--r--assets/defaultiwlanerrorconfig.json15
-rw-r--r--com.google.android.iwlan.xml1
-rw-r--r--src/com/google/android/iwlan/ErrorPolicyManager.java18
-rw-r--r--src/com/google/android/iwlan/IwlanDataService.java249
-rw-r--r--src/com/google/android/iwlan/IwlanHelper.java42
-rw-r--r--src/com/google/android/iwlan/IwlanNetworkService.java45
-rw-r--r--src/com/google/android/iwlan/epdg/EpdgSelector.java213
-rw-r--r--src/com/google/android/iwlan/epdg/EpdgTunnelManager.java311
-rw-r--r--src/com/google/android/iwlan/epdg/SrvDnsResolver.java3
-rw-r--r--src/com/google/android/iwlan/epdg/TunnelSetupRequest.java4
-rw-r--r--src/com/google/android/iwlan/proto/MetricsAtom.java40
-rw-r--r--test/com/google/android/iwlan/ErrorPolicyManagerTest.java28
-rw-r--r--test/com/google/android/iwlan/IwlanDataServiceTest.java477
-rw-r--r--test/com/google/android/iwlan/epdg/EpdgSelectorTest.java409
-rw-r--r--test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java409
16 files changed, 1557 insertions, 708 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d4f541f..e0b0b3a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
coreApp="true"
+ android:sharedUserId="android.uid.system"
package="com.google.android.iwlan">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
diff --git a/assets/defaultiwlanerrorconfig.json b/assets/defaultiwlanerrorconfig.json
index 212f611..2d2be95 100644
--- a/assets/defaultiwlanerrorconfig.json
+++ b/assets/defaultiwlanerrorconfig.json
@@ -68,20 +68,27 @@
{
"ErrorType": "*",
"ErrorDetails": ["*"],
- "RetryArray": ["5", "10", "-1"],
+ "RetryArray": ["1", "2", "2", "10", "20", "40", "80", "160", "320", "640", "1280", "1800", "3600", "-1"],
"UnthrottlingEvents": ["APM_ENABLE_EVENT", "APM_DISABLE_EVENT", "WIFI_DISABLE_EVENT", "WIFI_AP_CHANGED_EVENT"]
},
{
"ErrorType": "GENERIC_ERROR_TYPE",
"ErrorDetails": ["IO_EXCEPTION"],
- "RetryArray": ["0", "0", "0", "60+r15", "120", "-1"],
+ "RetryArray": ["0", "0", "0", "30", "60+r15", "120", "-1"],
"UnthrottlingEvents": ["APM_ENABLE_EVENT", "APM_DISABLE_EVENT", "WIFI_DISABLE_EVENT", "WIFI_AP_CHANGED_EVENT"]
},
{
"ErrorType": "IKE_PROTOCOL_ERROR_TYPE",
- "ErrorDetails": ["24", "9002"],
- "RetryArray": ["10", "20", "40", "80", "160"],
+ "ErrorDetails": ["*"],
+ "RetryArray": ["5", "10", "10", "20", "40", "80", "160", "320", "640", "1280", "1800", "3600", "-1"],
"UnthrottlingEvents": ["APM_ENABLE_EVENT", "WIFI_DISABLE_EVENT", "WIFI_CALLING_DISABLE_EVENT"]
+ },
+ {
+ "ErrorType": "IKE_PROTOCOL_ERROR_TYPE",
+ "ErrorDetails": ["36"],
+ "RetryArray": ["0", "0", "0", "10", "20", "40", "80", "160", "320", "640", "1280", "1800", "3600", "-1"],
+ "UnthrottlingEvents": ["APM_ENABLE_EVENT", "WIFI_DISABLE_EVENT", "WIFI_CALLING_DISABLE_EVENT"],
+ "HandoverAttemptCount": 3
}
]
}
diff --git a/com.google.android.iwlan.xml b/com.google.android.iwlan.xml
index f37b7c8..f91bb8a 100644
--- a/com.google.android.iwlan.xml
+++ b/com.google.android.iwlan.xml
@@ -3,5 +3,6 @@
<privapp-permissions package="com.google.android.iwlan">
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
+ <permission name="android.permission.SCHEDULE_EXACT_ALARM"/>
</privapp-permissions>
</permissions>
diff --git a/src/com/google/android/iwlan/ErrorPolicyManager.java b/src/com/google/android/iwlan/ErrorPolicyManager.java
index 7fa422e..88e9a7f 100644
--- a/src/com/google/android/iwlan/ErrorPolicyManager.java
+++ b/src/com/google/android/iwlan/ErrorPolicyManager.java
@@ -313,16 +313,19 @@ public class ErrorPolicyManager {
ret = DataFailCause.SIM_CARD_CHANGED;
} else if (error.getErrorType()
== IwlanError.IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED) {
- // TODO(b/265215821): Add new DataFailCause to match with IwlanError when possible.
- ret = DataFailCause.NETWORK_FAILURE;
+ ret = DataFailCause.IWLAN_IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED;
} else if (error.getErrorType() == IwlanError.TUNNEL_NOT_FOUND) {
ret = DataFailCause.IWLAN_TUNNEL_NOT_FOUND;
} else if (error.getErrorType() == IwlanError.IKE_INIT_TIMEOUT) {
- ret = DataFailCause.IWLAN_IKEV2_MSG_TIMEOUT;
+ ret = DataFailCause.IWLAN_IKE_INIT_TIMEOUT;
} else if (error.getErrorType() == IwlanError.IKE_MOBILITY_TIMEOUT) {
- ret = DataFailCause.IWLAN_IKEV2_MSG_TIMEOUT;
+ ret = DataFailCause.IWLAN_IKE_MOBILITY_TIMEOUT;
} else if (error.getErrorType() == IwlanError.IKE_DPD_TIMEOUT) {
- ret = DataFailCause.IWLAN_IKEV2_MSG_TIMEOUT;
+ ret = DataFailCause.IWLAN_IKE_DPD_TIMEOUT;
+ } else if (error.getErrorType() == IwlanError.TUNNEL_TRANSFORM_FAILED) {
+ ret = DataFailCause.IWLAN_TUNNEL_TRANSFORM_FAILED;
+ } else if (error.getErrorType() == IwlanError.IKE_NETWORK_LOST_EXCEPTION) {
+ ret = DataFailCause.IWLAN_IKE_NETWORK_LOST_EXCEPTION;
} else if (error.getErrorType() == IwlanError.IKE_PROTOCOL_EXCEPTION) {
Exception exception = error.getException();
if (exception instanceof IkeProtocolException) {
@@ -331,6 +334,9 @@ public class ErrorPolicyManager {
case IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED:
ret = DataFailCause.IWLAN_IKEV2_AUTH_FAILURE;
break;
+ case IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE:
+ ret = DataFailCause.IWLAN_EPDG_INTERNAL_ADDRESS_FAILURE;
+ break;
case IKE_PROTOCOL_ERROR_PDN_CONNECTION_REJECTION:
ret = DataFailCause.IWLAN_PDN_CONNECTION_REJECTION;
break;
@@ -383,7 +389,7 @@ public class ErrorPolicyManager {
ret = DataFailCause.IWLAN_CONGESTION;
break;
default:
- ret = DataFailCause.IWLAN_NETWORK_FAILURE;
+ ret = DataFailCause.IWLAN_IKE_PRIVATE_PROTOCOL_ERROR;
break;
}
}
diff --git a/src/com/google/android/iwlan/IwlanDataService.java b/src/com/google/android/iwlan/IwlanDataService.java
index 0eb3f33..0d564ab 100644
--- a/src/com/google/android/iwlan/IwlanDataService.java
+++ b/src/com/google/android/iwlan/IwlanDataService.java
@@ -60,13 +60,13 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.google.android.iwlan.TunnelMetricsInterface.OnClosedMetrics;
+import com.google.android.iwlan.TunnelMetricsInterface.OnOpenedMetrics;
import com.google.android.iwlan.epdg.EpdgSelector;
import com.google.android.iwlan.epdg.EpdgTunnelManager;
import com.google.android.iwlan.epdg.TunnelLinkProperties;
import com.google.android.iwlan.epdg.TunnelSetupRequest;
import com.google.android.iwlan.proto.MetricsAtom;
-import com.google.android.iwlan.TunnelMetricsInterface.OnOpenedMetrics;
-import com.google.android.iwlan.TunnelMetricsInterface.OnClosedMetrics;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -81,15 +81,19 @@ import java.util.HashMap;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class IwlanDataService extends DataService {
private static final String TAG = IwlanDataService.class.getSimpleName();
+
+ private static final String CONTEXT_ATTRIBUTION_TAG = "IWLAN";
private static Context mContext;
private IwlanNetworkMonitorCallback mNetworkMonitorCallback;
private static boolean sNetworkConnected = false;
private static Network sNetwork = null;
+ private static LinkProperties sLinkProperties = null;
@VisibleForTesting Handler mIwlanDataServiceHandler;
private HandlerThread mIwlanDataServiceHandlerThread;
private static final Map<Integer, IwlanDataServiceProvider> sIwlanDataServiceProviders =
@@ -121,15 +125,6 @@ public class IwlanDataService extends DataService {
private static Transport sDefaultDataTransport = Transport.UNSPECIFIED_NETWORK;
- enum LinkProtocolType {
- UNKNOWN,
- IPV4,
- IPV6,
- IPV4V6
- }
-
- private static LinkProtocolType sLinkProtocolType = LinkProtocolType.UNKNOWN;
-
// TODO: see if network monitor callback impl can be shared between dataservice and
// networkservice
// This callback runs in the same thread as IwlanDataServiceHandler
@@ -137,7 +132,7 @@ public class IwlanDataService extends DataService {
/** Called when the framework connects and has declared a new network ready for use. */
@Override
- public void onAvailable(Network network) {
+ public void onAvailable(@NonNull Network network) {
Log.d(TAG, "onAvailable: " + network);
}
@@ -149,7 +144,7 @@ public class IwlanDataService extends DataService {
* is suddenly disconnected.
*/
@Override
- public void onLosing(Network network, int maxMsToLive) {
+ public void onLosing(@NonNull Network network, int maxMsToLive) {
Log.d(TAG, "onLosing: maxMsToLive: " + maxMsToLive + " network: " + network);
}
@@ -158,7 +153,7 @@ public class IwlanDataService extends DataService {
* callback.
*/
@Override
- public void onLost(Network network) {
+ public void onLost(@NonNull Network network) {
Log.d(TAG, "onLost: " + network);
IwlanDataService.setConnectedDataSub(INVALID_SUB_ID);
IwlanDataService.setNetworkConnected(false, network, Transport.UNSPECIFIED_NETWORK);
@@ -166,25 +161,34 @@ public class IwlanDataService extends DataService {
/** Called when the network corresponding to this request changes {@link LinkProperties}. */
@Override
- public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
+ public void onLinkPropertiesChanged(
+ @NonNull Network network, @NonNull LinkProperties linkProperties) {
Log.d(TAG, "onLinkPropertiesChanged: " + linkProperties);
- if (isLinkProtocolTypeChanged(linkProperties)) {
+
+ if (!sNetwork.equals(network)) {
+ Log.d(TAG, "Ignore LinkProperties changes for unused Network.");
+ return;
+ }
+
+ if (!sLinkProperties.equals(linkProperties)) {
for (IwlanDataServiceProvider dp : sIwlanDataServiceProviders.values()) {
dp.dnsPrefetchCheck();
+ sLinkProperties = linkProperties;
+ dp.updateNetwork(network, linkProperties);
}
}
}
/** Called when access to the specified network is blocked or unblocked. */
@Override
- public void onBlockedStatusChanged(Network network, boolean blocked) {
+ public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {
// TODO: check if we need to handle this
Log.d(TAG, "onBlockedStatusChanged: " + network + " BLOCKED:" + blocked);
}
@Override
public void onCapabilitiesChanged(
- Network network, NetworkCapabilities networkCapabilities) {
+ @NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
// onCapabilitiesChanged is guaranteed to be called immediately after onAvailable per
// API
Log.d(TAG, "onCapabilitiesChanged: " + network + " " + networkCapabilities);
@@ -401,21 +405,30 @@ public class IwlanDataService extends DataService {
Log.d(
SUB_TAG,
"Tunnel opened!. APN: " + apnName + "linkproperties: " + linkProperties);
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(
- EVENT_TUNNEL_OPENED,
- new TunnelOpenedData(
- apnName, linkProperties, mIwlanDataServiceProvider)));
+ getIwlanDataServiceHandler()
+ .sendMessage(
+ getIwlanDataServiceHandler()
+ .obtainMessage(
+ EVENT_TUNNEL_OPENED,
+ new TunnelOpenedData(
+ apnName,
+ linkProperties,
+ mIwlanDataServiceProvider)));
}
public void onClosed(String apnName, IwlanError error) {
Log.d(SUB_TAG, "Tunnel closed!. APN: " + apnName + " Error: " + error);
// this is called, when a tunnel that is up, is closed.
// the expectation is error==NO_ERROR for user initiated/normal close.
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(
- EVENT_TUNNEL_CLOSED,
- new TunnelClosedData(apnName, error, mIwlanDataServiceProvider)));
+ getIwlanDataServiceHandler()
+ .sendMessage(
+ getIwlanDataServiceHandler()
+ .obtainMessage(
+ EVENT_TUNNEL_CLOSED,
+ new TunnelClosedData(
+ apnName,
+ error,
+ mIwlanDataServiceProvider)));
}
}
@@ -571,7 +584,7 @@ public class IwlanDataService extends DataService {
// get reference to resolver
mIwlanDataService = iwlanDataService;
mIwlanTunnelCallback = new IwlanTunnelCallback(this);
- mIwlanTunnelMetrics = new IwlanTunnelMetricsImpl(this, mIwlanDataServiceHandler);
+ mIwlanTunnelMetrics = new IwlanTunnelMetricsImpl(this, getIwlanDataServiceHandler());
mEpdgSelector = EpdgSelector.getSelectorInstance(mContext, slotIndex);
mCalendar = Calendar.getInstance();
mTunnelStats = new IwlanDataTunnelStats();
@@ -582,14 +595,14 @@ public class IwlanDataService extends DataService {
events.add(IwlanEventListener.CARRIER_CONFIG_UNKNOWN_CARRIER_EVENT);
events.add(IwlanEventListener.WIFI_CALLING_ENABLE_EVENT);
events.add(IwlanEventListener.WIFI_CALLING_DISABLE_EVENT);
+ events.add(IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT);
events.add(IwlanEventListener.CELLINFO_CHANGED_EVENT);
events.add(IwlanEventListener.CALL_STATE_CHANGED_EVENT);
IwlanEventListener.getInstance(mContext, slotIndex)
- .addEventListener(events, mIwlanDataServiceHandler);
+ .addEventListener(events, getIwlanDataServiceHandler());
}
- @VisibleForTesting
- EpdgTunnelManager getTunnelManager() {
+ private EpdgTunnelManager getTunnelManager() {
return EpdgTunnelManager.getInstance(mContext, getSlotIndex());
}
@@ -803,9 +816,10 @@ public class IwlanDataService extends DataService {
networkTransport);
}
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(
- EVENT_SETUP_DATA_CALL, setupDataCallData));
+ getIwlanDataServiceHandler()
+ .sendMessage(
+ getIwlanDataServiceHandler()
+ .obtainMessage(EVENT_SETUP_DATA_CALL, setupDataCallData));
}
/**
@@ -835,9 +849,11 @@ public class IwlanDataService extends DataService {
DeactivateDataCallData deactivateDataCallData =
new DeactivateDataCallData(cid, reason, callback, this);
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(
- EVENT_DEACTIVATE_DATA_CALL, deactivateDataCallData));
+ getIwlanDataServiceHandler()
+ .sendMessage(
+ getIwlanDataServiceHandler()
+ .obtainMessage(
+ EVENT_DEACTIVATE_DATA_CALL, deactivateDataCallData));
}
public void forceCloseTunnelsInDeactivatingState() {
@@ -872,10 +888,13 @@ public class IwlanDataService extends DataService {
*/
@Override
public void requestDataCallList(DataServiceCallback callback) {
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(
- EVENT_DATA_CALL_LIST_REQUEST,
- new DataCallRequestData(callback, IwlanDataServiceProvider.this)));
+ getIwlanDataServiceHandler()
+ .sendMessage(
+ getIwlanDataServiceHandler()
+ .obtainMessage(
+ EVENT_DATA_CALL_LIST_REQUEST,
+ new DataCallRequestData(
+ callback, IwlanDataServiceProvider.this)));
}
@VisibleForTesting
@@ -917,6 +936,12 @@ public class IwlanDataService extends DataService {
}
@VisibleForTesting
+ @Nullable
+ public MetricsAtom getMetricsAtomByApn(String apnName) {
+ return mMetricsAtomForApn.get(apnName);
+ }
+
+ @VisibleForTesting
public IwlanTunnelCallback getIwlanTunnelCallback() {
return mIwlanTunnelCallback;
}
@@ -931,29 +956,31 @@ public class IwlanDataService extends DataService {
return mTunnelStats;
}
- private void updateNetwork(Network network) {
- if (network != null) {
- for (Map.Entry<String, TunnelState> entry : mTunnelStateForApn.entrySet()) {
- TunnelState tunnelState = entry.getValue();
- if (tunnelState.getState() == TunnelState.TUNNEL_IN_BRINGUP) {
- // force close tunnels in bringup since IKE lib only supports
- // updating network for tunnels that are already up.
- // This may not result in actual closing of Ike Session since
- // epdg selection may not be complete yet.
- tunnelState.setState(TunnelState.TUNNEL_IN_FORCE_CLEAN_WAS_IN_BRINGUP);
+ private void updateNetwork(
+ @Nullable Network network, @Nullable LinkProperties linkProperties) {
+ if (mIwlanDataService.isNetworkConnected(
+ isActiveDataOnOtherSub(getSlotIndex()),
+ IwlanHelper.isCrossSimCallingEnabled(mContext, getSlotIndex()))) {
+ getTunnelManager().updateNetwork(network, linkProperties);
+ }
+
+ if (Objects.equals(network, sNetwork)) {
+ return;
+ }
+ for (Map.Entry<String, TunnelState> entry : mTunnelStateForApn.entrySet()) {
+ TunnelState tunnelState = entry.getValue();
+ if (tunnelState.getState() == TunnelState.TUNNEL_IN_BRINGUP) {
+ // force close tunnels in bringup since IKE lib only supports
+ // updating network for tunnels that are already up.
+ // This may not result in actual closing of Ike Session since
+ // epdg selection may not be complete yet.
+ tunnelState.setState(TunnelState.TUNNEL_IN_FORCE_CLEAN_WAS_IN_BRINGUP);
getTunnelManager()
.closeTunnel(
entry.getKey(),
true /* forceClose */,
getIwlanTunnelCallback(),
getIwlanTunnelMetrics());
- } else {
- if (mIwlanDataService.isNetworkConnected(
- isActiveDataOnOtherSub(getSlotIndex()),
- IwlanHelper.isCrossSimCallingEnabled(mContext, getSlotIndex()))) {
- getTunnelManager().updateNetwork(network, entry.getKey());
- }
- }
}
}
}
@@ -1073,7 +1100,7 @@ public class IwlanDataService extends DataService {
mIwlanDataService.removeDataServiceProvider(this);
IwlanEventListener iwlanEventListener =
IwlanEventListener.getInstance(mContext, getSlotIndex());
- iwlanEventListener.removeEventListener(mIwlanDataServiceHandler);
+ iwlanEventListener.removeEventListener(getIwlanDataServiceHandler());
iwlanEventListener.unregisterContentObserver();
}
@@ -1235,6 +1262,9 @@ public class IwlanDataService extends DataService {
// Record setup result for the Metrics
metricsAtom.setSetupRequestResult(DataServiceCallback.RESULT_SUCCESS);
metricsAtom.setIwlanError(iwlanError.getErrorType());
+
+ metricsAtom.setIwlanErrorWrappedClassnameAndStack(iwlanError);
+
metricsAtom.setTunnelState(tunnelState.getState());
metricsAtom.setMessageId(
IwlanStatsLog.IWLAN_SETUP_DATA_CALL_RESULT_REPORTED);
@@ -1329,6 +1359,12 @@ public class IwlanDataService extends DataService {
iwlanDataServiceProvider.mWfcEnabled = false;
break;
+ case IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT:
+ iwlanDataServiceProvider =
+ (IwlanDataServiceProvider) getDataServiceProvider(msg.arg1);
+ iwlanDataServiceProvider.updateNetwork(sNetwork, sLinkProperties);
+ break;
+
case IwlanEventListener.CELLINFO_CHANGED_EVENT:
List<CellInfo> cellInfolist = (List<CellInfo>) msg.obj;
iwlanDataServiceProvider =
@@ -1457,7 +1493,6 @@ public class IwlanDataService extends DataService {
TunnelSetupRequest.Builder tunnelReqBuilder =
TunnelSetupRequest.builder()
.setApnName(dataProfile.getApnSetting().getApnName())
- .setNetwork(sNetwork)
.setIsRoaming(isRoaming)
.setPduSessionId(pduSessionId)
.setApnIpProtocol(
@@ -1803,10 +1838,9 @@ public class IwlanDataService extends DataService {
}
}
- @VisibleForTesting
/* Note: this api should have valid transport if networkConnected==true */
static void setNetworkConnected(
- boolean networkConnected, Network network, Transport transport) {
+ boolean networkConnected, @NonNull Network network, Transport transport) {
boolean hasNetworkChanged = false;
boolean hasTransportChanged = false;
@@ -1853,10 +1887,6 @@ public class IwlanDataService extends DataService {
sNetworkConnected = networkConnected;
sDefaultDataTransport = transport;
sNetwork = network;
- if (!networkConnected) {
- // reset link protocol type
- sLinkProtocolType = LinkProtocolType.UNKNOWN;
- }
if (networkConnected) {
if (hasTransportChanged) {
@@ -1872,9 +1902,13 @@ public class IwlanDataService extends DataService {
}
// only prefetch dns and updateNetwork if Network has changed
if (hasNetworkChanged) {
+ ConnectivityManager connectivityManager =
+ mContext.getSystemService(ConnectivityManager.class);
+ LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
+ sLinkProperties = linkProperties;
for (IwlanDataServiceProvider dp : sIwlanDataServiceProviders.values()) {
dp.dnsPrefetchCheck();
- dp.updateNetwork(sNetwork);
+ dp.updateNetwork(sNetwork, linkProperties);
}
IwlanHelper.updateCountryCodeWhenNetworkConnected();
}
@@ -1889,48 +1923,6 @@ public class IwlanDataService extends DataService {
}
}
- static boolean isLinkProtocolTypeChanged(LinkProperties linkProperties) {
- boolean hasIPV4 = false;
- boolean hasIPV6 = false;
-
- LinkProtocolType linkProtocolType = null;
- if (linkProperties != null) {
- for (LinkAddress linkAddress : linkProperties.getLinkAddresses()) {
- InetAddress inetaddr = linkAddress.getAddress();
- // skip linklocal and loopback addresses
- if (!inetaddr.isLoopbackAddress() && !inetaddr.isLinkLocalAddress()) {
- if (inetaddr instanceof Inet4Address) {
- hasIPV4 = true;
- } else if (inetaddr instanceof Inet6Address) {
- hasIPV6 = true;
- }
- }
- }
-
- if (hasIPV4 && hasIPV6) {
- linkProtocolType = LinkProtocolType.IPV4V6;
- } else if (hasIPV4) {
- linkProtocolType = LinkProtocolType.IPV4;
- } else if (hasIPV6) {
- linkProtocolType = LinkProtocolType.IPV6;
- }
-
- if (sLinkProtocolType != linkProtocolType) {
- Log.d(
- TAG,
- "LinkProtocolType was changed from "
- + sLinkProtocolType
- + " to "
- + linkProtocolType);
- sLinkProtocolType = linkProtocolType;
- return true;
- }
- return false;
- }
- Log.w(TAG, "linkProperties is NULL.");
- return false;
- }
-
/**
* Get the DataServiceProvider associated with the slotId
*
@@ -1950,10 +1942,6 @@ public class IwlanDataService extends DataService {
// TODO: validity check on slot index
Log.d(TAG, "Creating provider for " + slotIndex);
- if (mIwlanDataServiceHandler == null) {
- initHandler();
- }
-
if (mNetworkMonitorCallback == null) {
// start monitoring network and register for default network callback
ConnectivityManager connectivityManager =
@@ -1961,21 +1949,25 @@ public class IwlanDataService extends DataService {
mNetworkMonitorCallback = new IwlanNetworkMonitorCallback();
if (connectivityManager != null) {
connectivityManager.registerSystemDefaultNetworkCallback(
- mNetworkMonitorCallback, mIwlanDataServiceHandler);
+ mNetworkMonitorCallback, getIwlanDataServiceHandler());
}
Log.d(TAG, "Registered with Connectivity Service");
}
IwlanDataServiceProvider dp = new IwlanDataServiceProvider(slotIndex, this);
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(EVENT_ADD_DATA_SERVICE_PROVIDER, dp));
+ getIwlanDataServiceHandler()
+ .sendMessage(
+ getIwlanDataServiceHandler()
+ .obtainMessage(EVENT_ADD_DATA_SERVICE_PROVIDER, dp));
return dp;
}
public void removeDataServiceProvider(IwlanDataServiceProvider dp) {
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(EVENT_REMOVE_DATA_SERVICE_PROVIDER, dp));
+ getIwlanDataServiceHandler()
+ .sendMessage(
+ getIwlanDataServiceHandler()
+ .obtainMessage(EVENT_REMOVE_DATA_SERVICE_PROVIDER, dp));
}
@VisibleForTesting
@@ -2013,8 +2005,12 @@ public class IwlanDataService extends DataService {
}
@VisibleForTesting
- void initHandler() {
- mIwlanDataServiceHandler = new IwlanDataServiceHandler(getLooper());
+ @NonNull
+ Handler getIwlanDataServiceHandler() {
+ if (mIwlanDataServiceHandler == null) {
+ mIwlanDataServiceHandler = new IwlanDataServiceHandler(getLooper());
+ }
+ return mIwlanDataServiceHandler;
}
@VisibleForTesting
@@ -2050,6 +2046,8 @@ public class IwlanDataService extends DataService {
return "WIFI_CALLING_ENABLE_EVENT";
case IwlanEventListener.WIFI_CALLING_DISABLE_EVENT:
return "WIFI_CALLING_DISABLE_EVENT";
+ case IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT:
+ return "CROSS_SIM_CALLING_ENABLE_EVENT";
case IwlanEventListener.CELLINFO_CHANGED_EVENT:
return "CELLINFO_CHANGED_EVENT";
case EVENT_TUNNEL_OPENED_METRICS:
@@ -2065,7 +2063,8 @@ public class IwlanDataService extends DataService {
@Override
public void onCreate() {
- setAppContext(getApplicationContext());
+ Context context = getApplicationContext().createAttributionContext(CONTEXT_ATTRIBUTION_TAG);
+ setAppContext(context);
IwlanBroadcastReceiver.startListening(mContext);
IwlanHelper.startCountryDetector(mContext);
}
@@ -2077,15 +2076,15 @@ public class IwlanDataService extends DataService {
@Override
public IBinder onBind(Intent intent) {
- Log.d(TAG, "Iwlanservice onBind");
+ Log.d(TAG, "IwlanDataService onBind");
return super.onBind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
- Log.d(TAG, "IwlanService onUnbind");
- mIwlanDataServiceHandler.sendMessage(
- mIwlanDataServiceHandler.obtainMessage(EVENT_FORCE_CLOSE_TUNNEL));
+ Log.d(TAG, "IwlanDataService onUnbind");
+ getIwlanDataServiceHandler()
+ .sendMessage(getIwlanDataServiceHandler().obtainMessage(EVENT_FORCE_CLOSE_TUNNEL));
return super.onUnbind(intent);
}
diff --git a/src/com/google/android/iwlan/IwlanHelper.java b/src/com/google/android/iwlan/IwlanHelper.java
index efda5b7..ade7189 100644
--- a/src/com/google/android/iwlan/IwlanHelper.java
+++ b/src/com/google/android/iwlan/IwlanHelper.java
@@ -110,14 +110,15 @@ public class IwlanHelper {
return info;
}
- public static List<InetAddress> getAddressesForNetwork(Network network, Context context) {
+ // Retrieves all IP addresses for this Network, including stacked IPv4 link addresses.
+ public static List<InetAddress> getAllAddressesForNetwork(Network network, Context context) {
ConnectivityManager connectivityManager =
context.getSystemService(ConnectivityManager.class);
List<InetAddress> gatewayList = new ArrayList<>();
if (network != null) {
LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
if (linkProperties != null) {
- for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
+ for (LinkAddress linkAddr : linkProperties.getAllLinkAddresses()) {
InetAddress inetAddr = linkAddr.getAddress();
// skip linklocal and loopback addresses
if (!inetAddr.isLoopbackAddress() && !inetAddr.isLinkLocalAddress()) {
@@ -132,25 +133,6 @@ public class IwlanHelper {
return gatewayList;
}
- public static List<InetAddress> getStackedAddressesForNetwork(
- Network network, Context context) {
- ConnectivityManager connectivityManager =
- context.getSystemService(ConnectivityManager.class);
- List<InetAddress> gatewayList = new ArrayList<>();
- if (network != null) {
- LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
- if (linkProperties != null) {
- for (LinkAddress linkAddr : linkProperties.getAllLinkAddresses()) {
- InetAddress inetAddr = linkAddr.getAddress();
- if ((inetAddr instanceof Inet4Address)) {
- gatewayList.add(inetAddr);
- }
- }
- }
- }
- return gatewayList;
- }
-
/**
* The method is to check if this IP address is an IPv4-embedded IPv6 address(Pref64::/n).
*
@@ -162,22 +144,24 @@ public class IwlanHelper {
}
public static boolean hasIpv6Address(List<InetAddress> localAddresses) {
- for (InetAddress address : localAddresses) {
- if (address instanceof Inet6Address) {
- return true;
+ if (localAddresses != null) {
+ for (InetAddress address : localAddresses) {
+ if (address instanceof Inet6Address) {
+ return true;
+ }
}
}
-
return false;
}
public static boolean hasIpv4Address(List<InetAddress> localAddresses) {
- for (InetAddress address : localAddresses) {
- if (address instanceof Inet4Address) {
- return true;
+ if (localAddresses != null) {
+ for (InetAddress address : localAddresses) {
+ if (address instanceof Inet4Address) {
+ return true;
+ }
}
}
-
return false;
}
diff --git a/src/com/google/android/iwlan/IwlanNetworkService.java b/src/com/google/android/iwlan/IwlanNetworkService.java
index d76c883..00f0907 100644
--- a/src/com/google/android/iwlan/IwlanNetworkService.java
+++ b/src/com/google/android/iwlan/IwlanNetworkService.java
@@ -185,15 +185,18 @@ public class IwlanNetworkService extends NetworkService {
events.add(IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT);
events.add(IwlanEventListener.CROSS_SIM_CALLING_DISABLE_EVENT);
IwlanEventListener.getInstance(mContext, slotIndex)
- .addEventListener(events, mIwlanNetworkServiceHandler);
+ .addEventListener(events, getIwlanNetworkServiceHandler());
}
@Override
public void requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback) {
- mIwlanNetworkServiceHandler.sendMessage(
- mIwlanNetworkServiceHandler.obtainMessage(
- EVENT_NETWORK_REGISTRATION_INFO_REQUEST,
- new NetworkRegistrationInfoRequestData(domain, callback, this)));
+ getIwlanNetworkServiceHandler()
+ .sendMessage(
+ getIwlanNetworkServiceHandler()
+ .obtainMessage(
+ EVENT_NETWORK_REGISTRATION_INFO_REQUEST,
+ new NetworkRegistrationInfoRequestData(
+ domain, callback, this)));
}
/**
@@ -205,7 +208,7 @@ public class IwlanNetworkService extends NetworkService {
public void close() {
mIwlanNetworkService.removeNetworkServiceProvider(this);
IwlanEventListener.getInstance(mContext, getSlotIndex())
- .removeEventListener(mIwlanNetworkServiceHandler);
+ .removeEventListener(getIwlanNetworkServiceHandler());
}
@VisibleForTesting
@@ -359,14 +362,11 @@ public class IwlanNetworkService extends NetworkService {
// TODO: validity check slot index
- if (mIwlanNetworkServiceHandler == null) {
- initHandler();
- }
-
IwlanNetworkServiceProvider np = new IwlanNetworkServiceProvider(slotIndex, this);
- mIwlanNetworkServiceHandler.sendMessage(
- mIwlanNetworkServiceHandler.obtainMessage(
- EVENT_CREATE_NETWORK_SERVICE_PROVIDER, np));
+ getIwlanNetworkServiceHandler()
+ .sendMessage(
+ getIwlanNetworkServiceHandler()
+ .obtainMessage(EVENT_CREATE_NETWORK_SERVICE_PROVIDER, np));
return np;
}
@@ -431,9 +431,10 @@ public class IwlanNetworkService extends NetworkService {
}
public void removeNetworkServiceProvider(IwlanNetworkServiceProvider np) {
- mIwlanNetworkServiceHandler.sendMessage(
- mIwlanNetworkServiceHandler.obtainMessage(
- EVENT_REMOVE_NETWORK_SERVICE_PROVIDER, np));
+ getIwlanNetworkServiceHandler()
+ .sendMessage(
+ getIwlanNetworkServiceHandler()
+ .obtainMessage(EVENT_REMOVE_NETWORK_SERVICE_PROVIDER, np));
}
void initCallback() {
@@ -441,14 +442,14 @@ public class IwlanNetworkService extends NetworkService {
mNetworkMonitorCallback = new IwlanNetworkMonitorCallback();
getConnectivityManager()
.registerSystemDefaultNetworkCallback(
- mNetworkMonitorCallback, mIwlanNetworkServiceHandler);
+ mNetworkMonitorCallback, getIwlanNetworkServiceHandler());
Log.d(TAG, "Registered with Connectivity Service");
/* register with subscription manager */
mSubsChangeListener = new IwlanOnSubscriptionsChangedListener();
getSubscriptionManager()
.addOnSubscriptionsChangedListener(
- new HandlerExecutor(mIwlanNetworkServiceHandler), mSubsChangeListener);
+ new HandlerExecutor(getIwlanNetworkServiceHandler()), mSubsChangeListener);
Log.d(TAG, "Registered with Subscription Service");
}
@@ -483,8 +484,12 @@ public class IwlanNetworkService extends NetworkService {
}
@VisibleForTesting
- void initHandler() {
- mIwlanNetworkServiceHandler = new IwlanNetworkServiceHandler(getLooper());
+ @NonNull
+ Handler getIwlanNetworkServiceHandler() {
+ if (mIwlanNetworkServiceHandler == null) {
+ mIwlanNetworkServiceHandler = new IwlanNetworkServiceHandler(getLooper());
+ }
+ return mIwlanNetworkServiceHandler;
}
@VisibleForTesting
diff --git a/src/com/google/android/iwlan/epdg/EpdgSelector.java b/src/com/google/android/iwlan/epdg/EpdgSelector.java
index d6bc103..4534b81 100644
--- a/src/com/google/android/iwlan/epdg/EpdgSelector.java
+++ b/src/com/google/android/iwlan/epdg/EpdgSelector.java
@@ -80,12 +80,16 @@ public class EpdgSelector {
private byte[] mV6PcoData = null;
@NonNull private final ErrorPolicyManager mErrorPolicyManager;
- private static final long DNS_RESOLVER_TIMEOUT_DURATION_SEC = 5L;
+ // The default DNS timeout in the DNS module is set to 5 seconds. To account for IPC overhead,
+ // IWLAN applies an internal timeout of 6 seconds, slightly longer than the default timeout
+ private static final long DNS_RESOLVER_TIMEOUT_DURATION_SEC = 6L;
- private static final long PARALLEL_DNS_RESOLVER_TIMEOUT_DURATION_SEC = 20L;
+ private static final long PARALLEL_STATIC_RESOLUTION_TIMEOUT_DURATION_SEC = 6L;
+ private static final long PARALLEL_PLMN_RESOLUTION_TIMEOUT_DURATION_SEC = 20L;
private static final int NUM_EPDG_SELECTION_EXECUTORS = 2; // 1 each for normal selection, SOS.
private static final int MAX_EPDG_SELECTION_THREADS = 2; // 1 each for prefetch, tunnel bringup.
private static final int MAX_DNS_RESOLVER_THREADS = 25; // Do not expect > 25 FQDNs per carrier.
+ private static final String NO_DOMAIN = "NO_DOMAIN";
BlockingQueue<Runnable> dnsResolutionQueue =
new ArrayBlockingQueue<>(
@@ -142,7 +146,7 @@ public class EpdgSelector {
public interface EpdgSelectorCallback {
/*gives priority ordered list of addresses*/
- void onServerListChanged(int transactionId, ArrayList<InetAddress> validIPList);
+ void onServerListChanged(int transactionId, List<InetAddress> validIPList);
void onError(int transactionId, IwlanError error);
}
@@ -204,7 +208,7 @@ public class EpdgSelector {
}
private CompletableFuture<Map.Entry<String, List<InetAddress>>> submitDnsResolverQuery(
- String domainName, Network network, Executor executor) {
+ String domainName, Network network, int queryType, Executor executor) {
CompletableFuture<Map.Entry<String, List<InetAddress>>> result = new CompletableFuture();
final DnsResolver.Callback<List<InetAddress>> cb =
@@ -232,7 +236,7 @@ public class EpdgSelector {
}
};
DnsResolver.getInstance()
- .query(network, domainName, DnsResolver.FLAG_EMPTY, executor, null, cb);
+ .query(network, domainName, queryType, DnsResolver.FLAG_EMPTY, executor, null, cb);
return result;
}
@@ -278,6 +282,22 @@ public class EpdgSelector {
.collect(Collectors.<T>toList()));
}
+ @VisibleForTesting
+ protected boolean hasIpv4Address(Network network) {
+ return IwlanHelper.hasIpv4Address(IwlanHelper.getAllAddressesForNetwork(network, mContext));
+ }
+
+ @VisibleForTesting
+ protected boolean hasIpv6Address(Network network) {
+ return IwlanHelper.hasIpv6Address(IwlanHelper.getAllAddressesForNetwork(network, mContext));
+ }
+
+ private void printParallelDnsResult(Map<String, List<InetAddress>> domainNameToIpAddresses) {
+ Log.d(TAG, "Parallel DNS resolution result:");
+ for (String domain : domainNameToIpAddresses.keySet()) {
+ Log.d(TAG, domain + ": " + domainNameToIpAddresses.get(domain));
+ }
+ }
/**
* Returns a list of unique IP addresses corresponding to the given domain names, in the same
* order of the input. Runs DNS resolution across parallel threads.
@@ -285,27 +305,46 @@ public class EpdgSelector {
* @param domainNames Domain names for which DNS resolution needs to be performed.
* @param filter Selects for IPv4, IPv6 (or both) addresses from the resulting DNS records
* @param network {@link Network} Network on which to run the DNS query.
+ * @param timeout timeout in seconds.
* @return List of unique IP addresses corresponding to the domainNames.
*/
private LinkedHashMap<String, List<InetAddress>> getIP(
- List<String> domainNames, int filter, Network network) {
+ List<String> domainNames, int filter, Network network, long timeout) {
// LinkedHashMap preserves insertion order (and hence priority) of domain names passed in.
LinkedHashMap<String, List<InetAddress>> domainNameToIpAddr = new LinkedHashMap<>();
List<CompletableFuture<Map.Entry<String, List<InetAddress>>>> futuresList =
new ArrayList<>();
for (String domainName : domainNames) {
+ if (InetAddresses.isNumericAddress(domainName)) {
+ Log.d(TAG, domainName + " is a numeric IP address!");
+ InetAddress inetAddr = InetAddresses.parseNumericAddress(domainName);
+ domainNameToIpAddr.put(NO_DOMAIN, new ArrayList<>(List.of(inetAddr)));
+ continue;
+ }
+
domainNameToIpAddr.put(domainName, new ArrayList<>());
- futuresList.add(submitDnsResolverQuery(domainName, network, mDnsResolutionExecutor));
+ // Dispatches separate IPv4 and IPv6 queries to avoid being blocked on either result.
+ if (hasIpv4Address(network)) {
+ futuresList.add(
+ submitDnsResolverQuery(
+ domainName, network, DnsResolver.TYPE_A, mDnsResolutionExecutor));
+ }
+ if (hasIpv6Address(network)) {
+ futuresList.add(
+ submitDnsResolverQuery(
+ domainName,
+ network,
+ DnsResolver.TYPE_AAAA,
+ mDnsResolutionExecutor));
+ }
}
CompletableFuture<List<Map.Entry<String, List<InetAddress>>>> allFuturesResult =
allOf(futuresList);
List<Map.Entry<String, List<InetAddress>>> resultList = null;
try {
- resultList =
- allFuturesResult.get(
- PARALLEL_DNS_RESOLVER_TIMEOUT_DURATION_SEC, TimeUnit.SECONDS);
+ resultList = allFuturesResult.get(timeout, TimeUnit.SECONDS);
} catch (ExecutionException e) {
Log.e(TAG, "Cause of ExecutionException: ", e.getCause());
} catch (InterruptedException e) {
@@ -318,8 +357,17 @@ public class EpdgSelector {
Log.w(TAG, "No IP addresses in parallel DNS query!");
} else {
for (Map.Entry<String, List<InetAddress>> entry : resultList) {
- domainNameToIpAddr.put(
- entry.getKey(), v4v6ProtocolFilter(entry.getValue(), filter));
+ String resultDomainName = entry.getKey();
+ List<InetAddress> resultIpAddr = v4v6ProtocolFilter(entry.getValue(), filter);
+
+ if (!domainNameToIpAddr.containsKey(resultDomainName)) {
+ Log.w(
+ TAG,
+ "Unexpected domain name in DnsResolver result: "
+ + resultDomainName);
+ continue;
+ }
+ domainNameToIpAddr.get(resultDomainName).addAll(resultIpAddr);
}
}
}
@@ -343,12 +391,8 @@ public class EpdgSelector {
Log.d(TAG, "Input domainName : " + domainName);
if (InetAddresses.isNumericAddress(domainName)) {
- try {
- Log.d(TAG, domainName + " is a numeric ip address");
- ipList.add(InetAddress.getByName(domainName));
- } catch (UnknownHostException e) {
- Log.e(TAG, "Exception when resolving domainName : " + domainName + ".", e);
- }
+ Log.d(TAG, domainName + " is a numeric IP address!");
+ ipList.add(InetAddresses.parseNumericAddress(domainName));
} else {
try {
CompletableFuture<List<InetAddress>> result = new CompletableFuture();
@@ -398,15 +442,7 @@ public class EpdgSelector {
}
private String[] getPlmnList() {
- List<String> plmnsFromSubInfo = new ArrayList<>();
-
- List<String> plmnsFromCarrierConfig =
- new ArrayList<>(
- Arrays.asList(
- IwlanHelper.getConfig(
- CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY,
- mContext,
- mSlotId)));
+ List<String> plmnsFromCarrierConfig = getPlmnsFromCarrierConfig();
Log.d(TAG, "plmnsFromCarrierConfig:" + plmnsFromCarrierConfig);
// Get Ehplmns & mccmnc from SubscriptionManager
@@ -424,48 +460,68 @@ public class EpdgSelector {
return plmnsFromCarrierConfig.toArray(new String[plmnsFromCarrierConfig.size()]);
}
- // There are three sources of plmns - sim plmn, plmn list from carrier config and
- // Ehplmn list from subscription info.
- // The plmns are prioritized as follows:
- // 1. Sim plmn
- // 2. Plmns common to both lists.
- // 3. Remaining plmns in the lists.
- List<String> combinedList = new ArrayList<>();
// Get MCCMNC from IMSI
- String plmnFromImsi = subInfo.getMccString() + "-" + subInfo.getMncString();
- combinedList.add(plmnFromImsi);
-
- // Get Ehplmns from TelephonyManager
- for (String ehplmn : getEhplmns()) {
- if (ehplmn.length() == 5 || ehplmn.length() == 6) {
- StringBuilder str = new StringBuilder(ehplmn);
- str.insert(3, "-");
- plmnsFromSubInfo.add(str.toString());
- }
- }
+ String plmnFromImsi = subInfo.getMccString() + subInfo.getMncString();
- Log.d(TAG, "plmnsFromSubInfo:" + plmnsFromSubInfo);
+ int[] prioritizedPlmnTypes =
+ IwlanHelper.getConfig(
+ CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ mContext,
+ mSlotId);
- // To avoid double adding plmn from imsi
- plmnsFromCarrierConfig.removeIf(i -> i.equals(plmnFromImsi));
- plmnsFromSubInfo.removeIf(i -> i.equals(plmnFromImsi));
+ List<String> ehplmns = getEhplmns();
+ String registeredPlmn = getRegisteredPlmn();
- for (Iterator<String> iterator = plmnsFromCarrierConfig.iterator(); iterator.hasNext(); ) {
- String plmn = iterator.next();
- if (plmnsFromSubInfo.contains(plmn)) {
- combinedList.add(plmn);
- plmnsFromSubInfo.remove(plmn);
- iterator.remove();
+ List<String> combinedList = new ArrayList<>();
+ for (int plmnType : prioritizedPlmnTypes) {
+ switch (plmnType) {
+ case CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN:
+ if (isInEpdgSelectionInfo(registeredPlmn)) {
+ combinedList.add(registeredPlmn);
+ }
+ break;
+ case CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN:
+ combinedList.add(plmnFromImsi);
+ break;
+ case CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL:
+ combinedList.addAll(getEhplmns());
+ break;
+ case CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_FIRST:
+ if (!ehplmns.isEmpty()) {
+ combinedList.add(ehplmns.get(0));
+ }
+ break;
+ default:
+ Log.e(TAG, "Unknown PLMN type: " + plmnType);
+ break;
}
}
- combinedList.addAll(plmnsFromSubInfo);
- combinedList.addAll(plmnsFromCarrierConfig);
+ combinedList =
+ combinedList.stream()
+ .distinct()
+ .filter(EpdgSelector::isValidPlmn)
+ .map(plmn -> new StringBuilder(plmn).insert(3, "-").toString())
+ .toList();
Log.d(TAG, "Final plmn list:" + combinedList);
return combinedList.toArray(new String[combinedList.size()]);
}
+ private List<String> getPlmnsFromCarrierConfig() {
+ return Arrays.asList(
+ IwlanHelper.getConfig(
+ CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY, mContext, mSlotId));
+ }
+
+ private boolean isInEpdgSelectionInfo(String plmn) {
+ if (!isValidPlmn(plmn)) {
+ return false;
+ }
+ List<String> plmnsFromCarrierConfig = getPlmnsFromCarrierConfig();
+ return plmnsFromCarrierConfig.contains(new StringBuilder(plmn).insert(3, "-").toString());
+ }
+
private ArrayList<InetAddress> removeDuplicateIp(List<InetAddress> validIpList) {
ArrayList<InetAddress> resultIpList = new ArrayList<InetAddress>();
@@ -499,6 +555,25 @@ public class EpdgSelector {
return mccmnc;
}
+ /**
+ * @return the registered PLMN, null if not registered with 3gpp or failed to get telephony
+ * manager
+ */
+ @Nullable
+ private String getRegisteredPlmn() {
+ TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+ if (telephonyManager == null) {
+ Log.e(TAG, "TelephonyManager is NULL");
+ return null;
+ }
+
+ telephonyManager =
+ telephonyManager.createForSubscriptionId(IwlanHelper.getSubId(mContext, mSlotId));
+
+ String registeredPlmn = telephonyManager.getNetworkOperator();
+ return registeredPlmn.isEmpty() ? null : registeredPlmn;
+ }
+
private List<String> getEhplmns() {
TelephonyManager mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
mTelephonyManager =
@@ -537,9 +612,14 @@ public class EpdgSelector {
}
Log.d(TAG, "Static Domain Names: " + Arrays.toString(domainNames));
- for (String domainName : domainNames) {
- getIP(domainName, filter, validIpList, network);
- }
+ LinkedHashMap<String, List<InetAddress>> domainNameToIpAddr =
+ getIP(
+ Arrays.asList(domainNames),
+ filter,
+ network,
+ PARALLEL_STATIC_RESOLUTION_TIMEOUT_DURATION_SEC);
+ printParallelDnsResult(domainNameToIpAddr);
+ domainNameToIpAddr.values().forEach(validIpList::addAll);
}
private String[] getDomainNames(String key) {
@@ -614,7 +694,8 @@ public class EpdgSelector {
}
LinkedHashMap<String, List<InetAddress>> domainNameToIpAddr =
- getIP(domainNames, filter, network);
+ getIP(domainNames, filter, network, PARALLEL_PLMN_RESOLUTION_TIMEOUT_DURATION_SEC);
+ printParallelDnsResult(domainNameToIpAddr);
domainNameToIpAddr.values().forEach(validIpList::addAll);
return domainNameToIpAddr;
}
@@ -1180,4 +1261,14 @@ public class EpdgSelector {
return new IwlanError(IwlanError.NO_ERROR);
}
+
+ /**
+ * Validates a PLMN (Public Land Mobile Network) identifier string.
+ *
+ * @param plmn The PLMN identifier string to validate.
+ * @return True if the PLMN identifier is valid, false otherwise.
+ */
+ private static boolean isValidPlmn(String plmn) {
+ return plmn != null && plmn.matches("\\d{5,6}");
+ }
}
diff --git a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
index 2cf0797..b8b70e4 100644
--- a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
+++ b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
@@ -28,6 +28,7 @@ import android.net.IpPrefix;
import android.net.IpSecManager;
import android.net.IpSecTransform;
import android.net.LinkAddress;
+import android.net.LinkProperties;
import android.net.Network;
import android.net.eap.EapAkaInfo;
import android.net.eap.EapInfo;
@@ -76,10 +77,10 @@ import com.google.android.iwlan.ErrorPolicyManager;
import com.google.android.iwlan.IwlanError;
import com.google.android.iwlan.IwlanHelper;
import com.google.android.iwlan.IwlanTunnelMetricsImpl;
-import com.google.android.iwlan.exceptions.IwlanSimNotReadyException;
import com.google.android.iwlan.TunnelMetricsInterface;
-import com.google.android.iwlan.TunnelMetricsInterface.OnOpenedMetrics;
import com.google.android.iwlan.TunnelMetricsInterface.OnClosedMetrics;
+import com.google.android.iwlan.TunnelMetricsInterface.OnOpenedMetrics;
+import com.google.android.iwlan.exceptions.IwlanSimNotReadyException;
import java.io.IOException;
import java.io.PrintWriter;
@@ -146,14 +147,22 @@ public class EpdgTunnelManager {
private static final String TRAFFIC_SELECTOR_IPV6_END_ADDR =
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
+ // "192.0.2.0" is selected from RFC5737, "IPv4 Address Blocks Reserved for Documentation"
+ private static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0");
+
private static final Map<Integer, EpdgTunnelManager> mTunnelManagerInstances =
new ConcurrentHashMap<>();
private Queue<TunnelRequestWrapper> mPendingBringUpRequests = new LinkedList<>();
private final EpdgInfo mValidEpdgInfo = new EpdgInfo();
- private InetAddress mEpdgAddress;
- private Network mNetwork;
+ @Nullable private InetAddress mEpdgAddress;
+
+ // The most recently updated system default network as seen by IwlanDataService.
+ @Nullable private Network mDefaultNetwork;
+ // The latest Network provided to the IKE session. Only for debugging purposes.
+ @Nullable private Network mIkeSessionNetwork;
+
private int mTransactionId = 0;
private boolean mHasConnectedToEpdg;
private final IkeSessionCreator mIkeSessionCreator;
@@ -163,8 +172,6 @@ public class EpdgTunnelManager {
private final String TAG;
- private List<InetAddress> mLocalAddresses;
-
@Nullable private byte[] mNextReauthId = null;
private long mEpdgServerSelectionDuration = 0;
private long mEpdgServerSelectionStartTime = 0;
@@ -216,13 +223,10 @@ public class EpdgTunnelManager {
SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512);
}
- private IkeSessionState mIkeSessionState;
-
private final EpdgSelector.EpdgSelectorCallback mSelectorCallback =
new EpdgSelector.EpdgSelectorCallback() {
@Override
- public void onServerListChanged(
- int transactionId, ArrayList<InetAddress> validIPList) {
+ public void onServerListChanged(int transactionId, List<InetAddress> validIPList) {
sendSelectionRequestComplete(
validIPList, new IwlanError(IwlanError.NO_ERROR), transactionId);
}
@@ -248,6 +252,16 @@ public class EpdgTunnelManager {
private boolean mIsBackoffTimeValid = false;
private long mBackoffTime;
+ private IkeSessionState mIkeSessionState;
+
+ public IkeSessionState getIkeSessionState() {
+ return mIkeSessionState;
+ }
+
+ public void setIkeSessionState(IkeSessionState ikeSessionState) {
+ mIkeSessionState = ikeSessionState;
+ }
+
public NetworkSliceInfo getSliceInfo() {
return mSliceInfo;
}
@@ -285,6 +299,8 @@ public class EpdgTunnelManager {
mError = new IwlanError(IwlanError.NO_ERROR);
mSrcIpv6Address = srcIpv6Addr;
mSrcIpv6AddressPrefixLen = srcIpv6PrefixLength;
+
+ setIkeSessionState(IkeSessionState.IKE_SESSION_INIT_IN_PROGRESS);
}
@NonNull
@@ -427,8 +443,7 @@ public class EpdgTunnelManager {
mHandler.sendMessage(
mHandler.obtainMessage(
EVENT_IKE_SESSION_CLOSED,
- new SessionClosedData(
- mApnName, mToken, new IwlanError(IwlanError.NO_ERROR))));
+ new SessionClosedData(mApnName, mToken, null /* ikeException */)));
}
@Override
@@ -520,8 +535,7 @@ public class EpdgTunnelManager {
mHandler.sendMessage(
mHandler.obtainMessage(
EVENT_CHILD_SESSION_CLOSED,
- new SessionClosedData(
- mApnName, mToken, new IwlanError(IwlanError.NO_ERROR))));
+ new SessionClosedData(mApnName, mToken, null /* ikeException */)));
}
@Override
@@ -665,13 +679,12 @@ public class EpdgTunnelManager {
* Update the local Network. This will trigger a revaluation for every tunnel for which tunnel
* manager has state.
*
- * <p>Tunnels in bringup state will be for closed since IKE currently keeps retrying.
- *
- * <p>For rest of the tunnels, update IKE session wth new network. This will either result in
- * MOBIKE callflow or just a rekey over new Network
+ * @param network the network to be updated
+ * @param network the linkProperties to be updated
*/
- public void updateNetwork(@NonNull Network network, String apnName) {
- UpdateNetworkWrapper updateNetworkWrapper = new UpdateNetworkWrapper(network, apnName);
+ public void updateNetwork(Network network, LinkProperties linkProperties) {
+ UpdateNetworkWrapper updateNetworkWrapper =
+ new UpdateNetworkWrapper(network, linkProperties);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UPDATE_NETWORK, updateNetworkWrapper));
}
/**
@@ -713,8 +726,6 @@ public class EpdgTunnelManager {
TunnelRequestWrapper tunnelRequestWrapper =
new TunnelRequestWrapper(setupRequest, tunnelCallback, tunnelMetrics);
- mIkeSessionState = IkeSessionState.NO_IKE_SESSION;
-
mHandler.sendMessage(
mHandler.obtainMessage(EVENT_TUNNEL_BRINGUP_REQUEST, tunnelRequestWrapper));
@@ -732,7 +743,7 @@ public class EpdgTunnelManager {
TAG,
"Bringing up tunnel for apn: "
+ apnName
- + "ePDG : "
+ + " ePDG: "
+ mEpdgAddress.getHostAddress());
final int token = incrementAndGetCurrentTokenForApn(apnName);
@@ -757,7 +768,7 @@ public class EpdgTunnelManager {
Executors.newSingleThreadExecutor(),
getTmIkeSessionCallback(apnName, token),
new TmChildSessionCallback(apnName, token));
- mIkeSessionState = IkeSessionState.IKE_SESSION_INIT_IN_PROGRESS;
+
boolean isSrcIpv6Present = setupRequest.srcIpv6Address().isPresent();
putApnNameToTunnelConfig(
apnName,
@@ -954,7 +965,7 @@ public class EpdgTunnelManager {
.setRemoteIdentification(getId(setupRequest.apnName(), false))
.setAuthEap(null, getEapConfig())
.addIkeSaProposal(buildIkeSaProposal())
- .setNetwork(mNetwork)
+ .setNetwork(mDefaultNetwork)
.addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
.addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
.addIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY)
@@ -982,6 +993,12 @@ public class EpdgTunnelManager {
}
}
+ // If MOBIKE is configured, ePDGs may force IPv6 UDP encapsulation- as specified by
+ // RFC 4555- which Android connectivity stack presently does not support.
+ if (mEpdgAddress instanceof Inet6Address) {
+ builder.removeIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE);
+ }
+
Ike3gppParams.Builder builder3gppParams = null;
// TODO(b/239753287): Telus carrier requests DEVICE_IDENTITY, but errors out when parsing
@@ -997,9 +1014,13 @@ public class EpdgTunnelManager {
}
}
- if (setupRequest.pduSessionId() != 0) {
- builder3gppParams = new Ike3gppParams.Builder();
- builder3gppParams.setPduSessionId((byte) setupRequest.pduSessionId());
+ if (isN1ModeSupported()) {
+ if (setupRequest.pduSessionId() != 0) {
+ // Configures the PduSession ID in N1_MODE_CAPABILITY payload
+ // to notify the server that UE supports N1_MODE
+ builder3gppParams = new Ike3gppParams.Builder();
+ builder3gppParams.setPduSessionId((byte) setupRequest.pduSessionId());
+ }
}
if (builder3gppParams != null) {
@@ -1234,12 +1255,6 @@ public class EpdgTunnelManager {
private void onSessionClosedWithException(
IkeException exception, String apnName, int token, int sessionType) {
- IwlanError error;
- if (exception instanceof IkeIOException) {
- error = new IwlanError(mIkeSessionState.getErrorType(), exception);
- } else {
- error = new IwlanError(exception);
- }
Log.e(
TAG,
"Closing tunnel with exception for apn: "
@@ -1247,15 +1262,12 @@ public class EpdgTunnelManager {
+ " with token: "
+ token
+ " sessionType:"
- + sessionType
- + " error: "
- + error
- + " state: "
- + mIkeSessionState);
+ + sessionType);
exception.printStackTrace();
mHandler.sendMessage(
- mHandler.obtainMessage(sessionType, new SessionClosedData(apnName, token, error)));
+ mHandler.obtainMessage(
+ sessionType, new SessionClosedData(apnName, token, exception)));
}
private boolean isEpdgSelectionOrFirstTunnelBringUpInProgress() {
@@ -1267,8 +1279,19 @@ public class EpdgTunnelManager {
|| !mPendingBringUpRequests.isEmpty();
}
+ private IwlanError getErrorFromIkeException(
+ IkeException ikeException, IkeSessionState ikeSessionState) {
+ IwlanError error;
+ if (ikeException instanceof IkeIOException) {
+ error = new IwlanError(ikeSessionState.getErrorType(), ikeException);
+ } else {
+ error = new IwlanError(ikeException);
+ }
+ Log.e(TAG, "Closing tunnel: error: " + error + " state: " + ikeSessionState);
+ return error;
+ }
+
private final class TmHandler extends Handler {
- private final String TAG = TmHandler.class.getSimpleName();
@Override
public void handleMessage(Message msg) {
@@ -1302,6 +1325,7 @@ public class EpdgTunnelManager {
case EVENT_TUNNEL_BRINGUP_REQUEST:
TunnelRequestWrapper tunnelRequestWrapper = (TunnelRequestWrapper) msg.obj;
TunnelSetupRequest setupRequest = tunnelRequestWrapper.getSetupRequest();
+ IwlanError bringUpError = null;
onClosedMetricsBuilder =
new OnClosedMetrics.Builder().setApnName(setupRequest.apnName());
@@ -1309,24 +1333,21 @@ public class EpdgTunnelManager {
if (IwlanHelper.getSubId(mContext, mSlotId)
== SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
Log.e(TAG, "SIM isn't ready");
- IwlanError iwlanError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
- reportIwlanError(setupRequest.apnName(), iwlanError);
- tunnelRequestWrapper
- .getTunnelCallback()
- .onClosed(setupRequest.apnName(), iwlanError);
- tunnelRequestWrapper
- .getTunnelMetrics()
- .onClosed(onClosedMetricsBuilder.build());
- return;
+ bringUpError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
+ reportIwlanError(setupRequest.apnName(), bringUpError);
+ } else if (Objects.isNull(mDefaultNetwork)) {
+ Log.e(TAG, "The default network is not ready");
+ bringUpError = new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION);
+ reportIwlanError(setupRequest.apnName(), bringUpError);
+ } else if (!canBringUpTunnel(setupRequest.apnName())) {
+ Log.d(TAG, "Cannot bring up tunnel as retry time has not passed");
+ bringUpError = getLastError(setupRequest.apnName());
}
- if (!canBringUpTunnel(setupRequest.apnName())) {
- Log.d(TAG, "Cannot bring up tunnel as retry time has not passed");
+ if (Objects.nonNull(bringUpError)) {
tunnelRequestWrapper
.getTunnelCallback()
- .onClosed(
- setupRequest.apnName(),
- getLastError(setupRequest.apnName()));
+ .onClosed(setupRequest.apnName(), bringUpError);
tunnelRequestWrapper
.getTunnelMetrics()
.onClosed(onClosedMetricsBuilder.build());
@@ -1344,7 +1365,6 @@ public class EpdgTunnelManager {
if (!isEpdgSelectionOrFirstTunnelBringUpInProgress()) {
// No tunnel bring-up in progress. Select the ePDG address first
- mNetwork = setupRequest.network();
selectEpdgAddress(setupRequest);
}
@@ -1431,11 +1451,11 @@ public class EpdgTunnelManager {
(int) mIkeTunnelEstablishmentDuration)
.build());
- setHasConnectedToEpdg(true);
+ onConnectedToEpdg(true);
mValidEpdgInfo.resetIndex();
printRequestQueue("EVENT_CHILD_SESSION_OPENED");
serviceAllPendingRequests();
- mIkeSessionState = IkeSessionState.CHILD_SESSION_OPENED;
+ tunnelConfig.setIkeSessionState(IkeSessionState.CHILD_SESSION_OPENED);
break;
case EVENT_IKE_SESSION_CLOSED:
@@ -1455,8 +1475,11 @@ public class EpdgTunnelManager {
// the Child session closed exceptionally; in which case, we attempt to retrieve
// the stored error (if any) from TunnelConfig.
IwlanError iwlanError;
- if (sessionClosedData.mIwlanError.getErrorType() != IwlanError.NO_ERROR) {
- iwlanError = sessionClosedData.mIwlanError;
+ if (sessionClosedData.mIkeException != null) {
+ iwlanError =
+ getErrorFromIkeException(
+ sessionClosedData.mIkeException,
+ tunnelConfig.getIkeSessionState());
} else {
// If IKE session opened, then closed before child session (and IWLAN
// tunnel) opened.
@@ -1484,6 +1507,7 @@ public class EpdgTunnelManager {
}
Log.d(TAG, "Tunnel Closed: " + iwlanError);
+ tunnelConfig.setIkeSessionState(IkeSessionState.NO_IKE_SESSION);
tunnelConfig.getTunnelCallback().onClosed(apnName, iwlanError);
onClosedMetricsBuilder = new OnClosedMetrics.Builder().setApnName(apnName);
@@ -1508,31 +1532,54 @@ public class EpdgTunnelManager {
mApnNameToTunnelConfig.remove(apnName);
if (mApnNameToTunnelConfig.size() == 0 && mPendingBringUpRequests.isEmpty()) {
- resetTunnelManagerState();
+ onConnectedToEpdg(false);
}
- mIkeSessionState = IkeSessionState.NO_IKE_SESSION;
-
break;
case EVENT_UPDATE_NETWORK:
UpdateNetworkWrapper updatedNetwork = (UpdateNetworkWrapper) msg.obj;
- apnName = updatedNetwork.getApnName();
- Network network = updatedNetwork.getNetwork();
- tunnelConfig = mApnNameToTunnelConfig.get(apnName);
+ mDefaultNetwork = updatedNetwork.getNetwork();
+ LinkProperties defaultLinkProperties = updatedNetwork.getLinkProperties();
+ String paraString = "Network: " + mDefaultNetwork;
- // Update the global cache if they aren't equal
- if (mNetwork == null || !mNetwork.equals(network)) {
- Log.d(TAG, "Updating mNetwork to " + network);
- mNetwork = network;
- }
-
- if (tunnelConfig == null) {
- Log.d(TAG, "Update Network request: No tunnel exists for apn: " + apnName);
- } else {
- Log.d(TAG, "Updating Network for apn: " + apnName + " Network: " + network);
- tunnelConfig.getIkeSession().setNetwork(network);
- mIkeSessionState = IkeSessionState.IKE_MOBILITY_IN_PROGRESS;
+ if (mHasConnectedToEpdg) {
+ if (Objects.isNull(mDefaultNetwork)) {
+ Log.w(TAG, "The default network has been removed.");
+ } else if (Objects.isNull(defaultLinkProperties)) {
+ Log.w(
+ TAG,
+ "The default network's LinkProperties is not ready ."
+ + paraString);
+ } else if (!defaultLinkProperties.isReachable(mEpdgAddress)) {
+ Log.w(
+ TAG,
+ "The default network link "
+ + defaultLinkProperties
+ + " doesn't have a route to the ePDG "
+ + mEpdgAddress
+ + paraString);
+ } else if (Objects.equals(mDefaultNetwork, mIkeSessionNetwork)) {
+ Log.w(
+ TAG,
+ "The default network has not changed from the IKE session"
+ + " network. "
+ + paraString);
+ } else {
+ mApnNameToTunnelConfig.forEach(
+ (apn, config) -> {
+ Log.d(
+ TAG,
+ "The Underlying Network is updating for APN (+"
+ + apn
+ + "). "
+ + paraString);
+ config.getIkeSession().setNetwork(mDefaultNetwork);
+ config.setIkeSessionState(
+ IkeSessionState.IKE_MOBILITY_IN_PROGRESS);
+ });
+ mIkeSessionNetwork = mDefaultNetwork;
+ }
}
break;
@@ -1577,30 +1624,12 @@ public class EpdgTunnelManager {
tunnelConfig = mApnNameToTunnelConfig.get(apnName);
if (tunnelConfig.getIface() == null) {
- if (mLocalAddresses == null
- || mLocalAddresses.size() == 0
- || ipSecManager == null) {
- Log.e(TAG, "No local addresses found.");
- closeIkeSession(
- apnName, new IwlanError(IwlanError.TUNNEL_TRANSFORM_FAILED));
- return;
- }
-
try {
- if (mEpdgAddress instanceof Inet4Address
- && !IwlanHelper.hasIpv4Address(mLocalAddresses)) {
- mLocalAddresses =
- IwlanHelper.getStackedAddressesForNetwork(
- mNetwork, mContext);
- }
- InetAddress localAddress =
- (mEpdgAddress instanceof Inet4Address)
- ? IwlanHelper.getIpv4Address(mLocalAddresses)
- : IwlanHelper.getIpv6Address(mLocalAddresses);
- Log.d(TAG, "Local address = " + localAddress);
tunnelConfig.setIface(
ipSecManager.createIpSecTunnelInterface(
- localAddress, mEpdgAddress, mNetwork));
+ DUMMY_ADDR /* unused */,
+ DUMMY_ADDR /* unused */,
+ mDefaultNetwork));
} catch (IpSecManager.ResourceUnavailableException | IOException e) {
Log.e(TAG, "Failed to create tunnel interface. " + e);
closeIkeSession(
@@ -1622,8 +1651,9 @@ public class EpdgTunnelManager {
closeIkeSession(
apnName, new IwlanError(IwlanError.TUNNEL_TRANSFORM_FAILED));
}
- if (mIkeSessionState == IkeSessionState.IKE_MOBILITY_IN_PROGRESS) {
- mIkeSessionState = IkeSessionState.CHILD_SESSION_OPENED;
+ if (tunnelConfig.getIkeSessionState()
+ == IkeSessionState.IKE_MOBILITY_IN_PROGRESS) {
+ tunnelConfig.setIkeSessionState(IkeSessionState.CHILD_SESSION_OPENED);
}
break;
@@ -1642,7 +1672,12 @@ public class EpdgTunnelManager {
Log.d(TAG, "No tunnel callback for apn: " + apnName);
return;
}
- tunnelConfig.setError(sessionClosedData.mIwlanError);
+ if (sessionClosedData.mIkeException != null) {
+ tunnelConfig.setError(
+ getErrorFromIkeException(
+ sessionClosedData.mIkeException,
+ tunnelConfig.getIkeSessionState()));
+ }
tunnelConfig.getIkeSession().close();
break;
@@ -1678,7 +1713,8 @@ public class EpdgTunnelManager {
case EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED:
IkeSessionConnectionInfoData ikeSessionConnectionInfoData =
(IkeSessionConnectionInfoData) msg.obj;
- network = ikeSessionConnectionInfoData.mIkeSessionConnectionInfo.getNetwork();
+ Network network =
+ ikeSessionConnectionInfoData.mIkeSessionConnectionInfo.getNetwork();
apnName = ikeSessionConnectionInfoData.mApnName;
ConnectivityManager connectivityManager =
@@ -1798,7 +1834,7 @@ public class EpdgTunnelManager {
epdgAddressOrder,
setupRequest.isRoaming(),
setupRequest.isEmergency(),
- mNetwork,
+ mDefaultNetwork,
mSelectorCallback);
if (epdgError.getErrorType() != IwlanError.NO_ERROR) {
@@ -1862,17 +1898,6 @@ public class EpdgTunnelManager {
mValidEpdgInfo.incrementIndex();
}
- @VisibleForTesting
- void resetTunnelManagerState() {
- Log.d(TAG, "resetTunnelManagerState");
- mEpdgAddress = null;
- setHasConnectedToEpdg(false);
- mNetwork = null;
- mPendingBringUpRequests = new LinkedList<>();
- mApnNameToTunnelConfig = new ConcurrentHashMap<>();
- mLocalAddresses = null;
- }
-
private void serviceAllPendingRequests() {
while (!mPendingBringUpRequests.isEmpty()) {
Log.d(TAG, "serviceAllPendingRequests");
@@ -1911,20 +1936,20 @@ public class EpdgTunnelManager {
// Update Network wrapper
private static final class UpdateNetworkWrapper {
private final Network mNetwork;
- private final String mApnName;
+ private final LinkProperties mLinkProperties;
- private UpdateNetworkWrapper(Network network, String apnName) {
+ private UpdateNetworkWrapper(Network network, LinkProperties linkProperties) {
mNetwork = network;
- mApnName = apnName;
- }
-
- public String getApnName() {
- return mApnName;
+ mLinkProperties = linkProperties;
}
public Network getNetwork() {
return mNetwork;
}
+
+ public LinkProperties getLinkProperties() {
+ return mLinkProperties;
+ }
}
// Tunnel request + tunnel callback
@@ -2049,11 +2074,11 @@ public class EpdgTunnelManager {
// Data received from IkeSessionStateMachine if either IKE session or Child session have been
// closed, normally or exceptionally.
private static final class SessionClosedData extends IkeEventData {
- final IwlanError mIwlanError;
+ final IkeException mIkeException;
- private SessionClosedData(String apnName, int token, IwlanError iwlanError) {
+ private SessionClosedData(String apnName, int token, IkeException ikeException) {
super(apnName, token);
- mIwlanError = iwlanError;
+ mIkeException = ikeException;
}
}
@@ -2241,13 +2266,24 @@ public class EpdgTunnelManager {
}
@VisibleForTesting
+ boolean isN1ModeSupported() {
+ int[] nrCarrierCaps =
+ getConfig(CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
+ Log.d(TAG, "KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY : " + Arrays.toString(nrCarrierCaps));
+ if (Arrays.stream(nrCarrierCaps)
+ .anyMatch(cap -> cap == CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA)) {
+ return true;
+ } else return false;
+ }
+
+ @VisibleForTesting
boolean isTunnelConfigContainExistApn(String apnName) {
return mApnNameToTunnelConfig.containsKey(apnName);
}
@VisibleForTesting
List<InetAddress> getAddressForNetwork(Network network, Context context) {
- return IwlanHelper.getAddressesForNetwork(network, context);
+ return IwlanHelper.getAllAddressesForNetwork(network, context);
}
@VisibleForTesting
@@ -2257,7 +2293,7 @@ public class EpdgTunnelManager {
@VisibleForTesting
void sendSelectionRequestComplete(
- ArrayList<InetAddress> validIPList, IwlanError result, int transactionId) {
+ List<InetAddress> validIPList, IwlanError result, int transactionId) {
mEpdgServerSelectionDuration = System.currentTimeMillis() - mEpdgServerSelectionStartTime;
mEpdgServerSelectionStartTime = 0;
EpdgSelectorResult epdgSelectorResult =
@@ -2317,8 +2353,14 @@ public class EpdgTunnelManager {
}
@VisibleForTesting
- void setHasConnectedToEpdg(boolean value) {
- mHasConnectedToEpdg = value;
+ void onConnectedToEpdg(boolean hasConnected) {
+ mHasConnectedToEpdg = hasConnected;
+ if (mHasConnectedToEpdg) {
+ mIkeSessionNetwork = mDefaultNetwork;
+ } else {
+ mIkeSessionNetwork = null;
+ mEpdgAddress = null;
+ }
}
@VisibleForTesting
@@ -2363,11 +2405,11 @@ public class EpdgTunnelManager {
@VisibleForTesting
IpPreferenceConflict isIpPreferenceConflictsWithNetwork(
@CarrierConfigManager.Iwlan.EpdgAddressIpPreference int ipPreference) {
- mLocalAddresses = getAddressForNetwork(mNetwork, mContext);
- if (mLocalAddresses == null || mLocalAddresses.size() == 0) {
- Log.e(TAG, "No local addresses available.");
+ List<InetAddress> localAddresses = getAddressForNetwork(mDefaultNetwork, mContext);
+ if (localAddresses == null || localAddresses.size() == 0) {
+ Log.e(TAG, "No local addresses available for Network " + mDefaultNetwork);
return new IpPreferenceConflict(true, IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
- } else if (!IwlanHelper.hasIpv6Address(mLocalAddresses)
+ } else if (!IwlanHelper.hasIpv6Address(localAddresses)
&& ipPreference == CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_ONLY) {
Log.e(
TAG,
@@ -2376,7 +2418,7 @@ public class EpdgTunnelManager {
+ " conflicts with source IP type: "
+ EpdgSelector.PROTO_FILTER_IPV4);
return new IpPreferenceConflict(true, IwlanError.EPDG_ADDRESS_ONLY_IPV6_ALLOWED);
- } else if (!IwlanHelper.hasIpv4Address(mLocalAddresses)
+ } else if (!IwlanHelper.hasIpv4Address(localAddresses)
&& ipPreference == CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_ONLY) {
// b/209938719 allows Iwlan to support VoWiFi for IPv4 ePDG server while on IPv6 WiFi.
// Iwlan will receive a IPv4 address which is embedded in stacked IPv6 address. By using
@@ -2397,6 +2439,7 @@ public class EpdgTunnelManager {
public void dump(PrintWriter pw) {
pw.println("---- EpdgTunnelManager ----");
pw.println("mHasConnectedToEpdg: " + mHasConnectedToEpdg);
+ pw.println("mIkeSessionNetwork: " + mIkeSessionNetwork);
if (mEpdgAddress != null) {
pw.println("mEpdgAddress: " + mEpdgAddress);
}
diff --git a/src/com/google/android/iwlan/epdg/SrvDnsResolver.java b/src/com/google/android/iwlan/epdg/SrvDnsResolver.java
index 1ae9cba..192fbb8 100644
--- a/src/com/google/android/iwlan/epdg/SrvDnsResolver.java
+++ b/src/com/google/android/iwlan/epdg/SrvDnsResolver.java
@@ -36,6 +36,7 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -146,7 +147,7 @@ final class SrvDnsResolver {
// Parses the Answers section of a DnsPacket to construct and return a mapping
// of Domain Name strings to their corresponding SRV record.
public @NonNull Map<String, SrvRecord> parseSrvRecords() throws ParseException {
- final HashMap<String, SrvRecord> targetNameToSrvRecord = new HashMap<>();
+ final HashMap<String, SrvRecord> targetNameToSrvRecord = new LinkedHashMap<>();
if (mHeader.getRecordCount(ANSECTION) == 0) return targetNameToSrvRecord;
for (final DnsRecord ansSec : mRecords[ANSECTION]) {
diff --git a/src/com/google/android/iwlan/epdg/TunnelSetupRequest.java b/src/com/google/android/iwlan/epdg/TunnelSetupRequest.java
index 4086c22..d1ed9dd 100644
--- a/src/com/google/android/iwlan/epdg/TunnelSetupRequest.java
+++ b/src/com/google/android/iwlan/epdg/TunnelSetupRequest.java
@@ -29,8 +29,6 @@ public abstract class TunnelSetupRequest {
abstract int apnIpProtocol();
- abstract Network network();
-
abstract Optional<InetAddress> srcIpv4Address();
abstract Optional<InetAddress> srcIpv6Address();
@@ -58,8 +56,6 @@ public abstract class TunnelSetupRequest {
public abstract Builder setApnIpProtocol(int protocol);
- public abstract Builder setNetwork(Network network);
-
public Builder setSrcIpv4Address(InetAddress srcIpv4Address) {
return setSrcIpv4Address(Optional.ofNullable(srcIpv4Address));
}
diff --git a/src/com/google/android/iwlan/proto/MetricsAtom.java b/src/com/google/android/iwlan/proto/MetricsAtom.java
index 33b0fcd..7ecf464 100644
--- a/src/com/google/android/iwlan/proto/MetricsAtom.java
+++ b/src/com/google/android/iwlan/proto/MetricsAtom.java
@@ -16,6 +16,10 @@
package com.google.android.iwlan.proto;
+import android.net.ipsec.ike.exceptions.IkeIOException;
+import android.net.ipsec.ike.exceptions.IkeInternalException;
+
+import com.google.android.iwlan.IwlanError;
import com.google.android.iwlan.IwlanStatsLog;
public class MetricsAtom {
@@ -37,6 +41,8 @@ public class MetricsAtom {
private int mHandoverFailureMode;
private int mRetryDurationMillis;
private int mWifiSignalValue;
+ private String mIwlanErrorWrappedClassname;
+ private String mIwlanErrorWrappedStackFirstFrame;
public void setMessageId(int messageId) {
this.mMessageId = messageId;
@@ -110,6 +116,36 @@ public class MetricsAtom {
this.mWifiSignalValue = wifiSignalValue;
}
+ public void setIwlanErrorWrappedClassnameAndStack(IwlanError iwlanError) {
+ Throwable iwlanErrorWrapped = iwlanError.getException();
+ if (iwlanErrorWrapped instanceof IkeInternalException
+ || iwlanErrorWrapped instanceof IkeIOException) {
+ iwlanErrorWrapped = iwlanErrorWrapped.getCause();
+ }
+
+ if (iwlanErrorWrapped == null) {
+ this.mIwlanErrorWrappedClassname = null;
+ this.mIwlanErrorWrappedStackFirstFrame = null;
+ return;
+ }
+
+ this.mIwlanErrorWrappedClassname = iwlanErrorWrapped.getClass().getCanonicalName();
+
+ StackTraceElement[] iwlanErrorWrappedStackTraceElements = iwlanErrorWrapped.getStackTrace();
+ this.mIwlanErrorWrappedStackFirstFrame =
+ iwlanErrorWrappedStackTraceElements.length != 0
+ ? iwlanErrorWrappedStackTraceElements[0].toString()
+ : null;
+ }
+
+ public String getIwlanErrorWrappedClassname() {
+ return mIwlanErrorWrappedClassname;
+ }
+
+ public String getIwlanErrorWrappedStackFirstFrame() {
+ return mIwlanErrorWrappedStackFirstFrame;
+ }
+
public void sendMetricsData() {
if (mMessageId == IwlanStatsLog.IWLAN_SETUP_DATA_CALL_RESULT_REPORTED) {
IwlanStatsLog.write(
@@ -129,7 +165,9 @@ public class MetricsAtom {
mIkeTunnelEstablishmentDurationMillis,
mTunnelState,
mHandoverFailureMode,
- mRetryDurationMillis);
+ mRetryDurationMillis,
+ mIwlanErrorWrappedClassname,
+ mIwlanErrorWrappedStackFirstFrame);
return;
} else if (mMessageId == IwlanStatsLog.IWLAN_PDN_DISCONNECTED_REASON_REPORTED) {
IwlanStatsLog.write(
diff --git a/test/com/google/android/iwlan/ErrorPolicyManagerTest.java b/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
index 0895f09..1c15e41 100644
--- a/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
+++ b/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
@@ -197,6 +197,10 @@ public class ErrorPolicyManagerTest {
return buildIwlanIkeProtocolError(IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND);
}
+ private static IwlanError buildIwlanIkeInternalAddressFailure() {
+ return buildIwlanIkeProtocolError(IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE);
+ }
+
@Test
public void testValidCarrierConfig() throws Exception {
String apn = "ims";
@@ -275,7 +279,7 @@ public class ErrorPolicyManagerTest {
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(10, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(10, time);
+ assertEquals(20, time);
}
@Test
@@ -311,6 +315,10 @@ public class ErrorPolicyManagerTest {
// parsing (or lack of explicit carrier-defined policy).
IwlanError iwlanError = buildIwlanIkeAuthFailedError();
long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(5, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(10, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(10, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(20, time);
@@ -318,13 +326,13 @@ public class ErrorPolicyManagerTest {
assertEquals(40, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(80, time);
- time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(160, time);
- time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(86400, time);
iwlanError = buildIwlanIkeProtocolError(9002);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(5, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(10, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(10, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(20, time);
@@ -332,10 +340,16 @@ public class ErrorPolicyManagerTest {
assertEquals(40, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(80, time);
+
+ iwlanError = buildIwlanIkeInternalAddressFailure();
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(160, time);
+ assertEquals(0, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(86400, time);
+ assertEquals(0, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(0, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(10, time);
}
@Test
diff --git a/test/com/google/android/iwlan/IwlanDataServiceTest.java b/test/com/google/android/iwlan/IwlanDataServiceTest.java
index 2646c16..c4549df 100644
--- a/test/com/google/android/iwlan/IwlanDataServiceTest.java
+++ b/test/com/google/android/iwlan/IwlanDataServiceTest.java
@@ -17,12 +17,14 @@
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 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
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;
@@ -31,9 +33,12 @@ 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;
@@ -43,11 +48,13 @@ 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.test.TestLooper;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
@@ -67,12 +74,12 @@ 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.IwlanDataService.IwlanNetworkMonitorCallback;
import com.google.android.iwlan.epdg.EpdgSelector;
import com.google.android.iwlan.epdg.EpdgTunnelManager;
import com.google.android.iwlan.epdg.TunnelLinkProperties;
import com.google.android.iwlan.epdg.TunnelLinkPropertiesTest;
import com.google.android.iwlan.epdg.TunnelSetupRequest;
+import com.google.android.iwlan.proto.MetricsAtom;
import org.junit.After;
import org.junit.Before;
@@ -83,11 +90,13 @@ 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;
@@ -97,6 +106,7 @@ import java.util.concurrent.TimeUnit;
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";
@@ -120,21 +130,23 @@ public class IwlanDataServiceTest {
@Mock private ImsMmTelManager mMockImsMmTelManager;
@Mock private TelephonyManager mMockTelephonyManager;
@Mock private EpdgSelector mMockEpdgSelector;
- @Mock private LinkProperties mMockLinkProperties;
@Mock private LinkAddress mMockIPv4LinkAddress;
@Mock private LinkAddress mMockIPv6LinkAddress;
@Mock private Inet4Address mMockInet4Address;
@Mock private Inet6Address mMockInet6Address;
+
MockitoSession mStaticMockSession;
+ private LinkProperties mLinkProperties;
private List<DataCallResponse> mResultDataCallList;
private @DataServiceCallback.ResultCode int mResultCode;
private CountDownLatch latch;
private IwlanDataService mIwlanDataService;
- private IwlanDataServiceProvider mIwlanDataServiceProvider;
private IwlanDataServiceProvider mSpyIwlanDataServiceProvider;
private TestLooper mTestLooper = new TestLooper();
- private long mMockedCalendarTime = 0L;
+ private long mMockedCalendarTime;
+ private ArgumentCaptor<NetworkCallback> mNetworkCallbackCaptor =
+ ArgumentCaptor.forClass(NetworkCallback.class);
private final class IwlanDataServiceCallback extends IDataServiceCallback.Stub {
@@ -189,6 +201,7 @@ public class IwlanDataServiceTest {
mStaticMockSession =
mockitoSession()
.mockStatic(EpdgSelector.class)
+ .mockStatic(EpdgTunnelManager.class)
.mockStatic(ErrorPolicyManager.class)
.mockStatic(IwlanBroadcastReceiver.class)
.mockStatic(SubscriptionManager.class)
@@ -201,6 +214,12 @@ public class IwlanDataServiceTest {
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);
@@ -234,45 +253,73 @@ public class IwlanDataServiceTest {
when(mMockIPv6LinkAddress.getAddress()).thenReturn(mMockInet6Address);
mIwlanDataService = spy(new IwlanDataService());
+ // Injects the test looper into the IwlanDataServiceHandler
doReturn(mTestLooper.getLooper()).when(mIwlanDataService).getLooper();
mIwlanDataService.setAppContext(mMockContext);
- mIwlanDataServiceProvider =
- (IwlanDataServiceProvider)
- mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX);
+ mSpyIwlanDataServiceProvider =
+ spy(
+ (IwlanDataServiceProvider)
+ mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX));
mTestLooper.dispatchAll();
- mSpyIwlanDataServiceProvider = spy(mIwlanDataServiceProvider);
+
+ when(Calendar.getInstance().getTime()).thenAnswer(i -> mMockedCalendarTime);
+
+ mLinkProperties = new LinkProperties();
+ mLinkProperties.setInterfaceName("wlan0");
+ mLinkProperties.addLinkAddress(mMockIPv4LinkAddress);
+
+ when(mMockConnectivityManager.getLinkProperties(eq(mMockNetwork)))
+ .thenReturn(mLinkProperties);
}
@After
public void cleanUp() throws Exception {
mStaticMockSession.finishMocking();
- mIwlanDataServiceProvider.close();
+ mSpyIwlanDataServiceProvider.close();
mTestLooper.dispatchAll();
if (mIwlanDataService != null) {
mIwlanDataService.onDestroy();
}
}
- private void verifyNetworkConnected(int transportType) {
- NetworkCapabilities mockNetworkCapabilities = mock(NetworkCapabilities.class);
+ 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();
+ }
- when(mockNetworkCapabilities.hasTransport(anyInt())).thenReturn(false);
- when(mockNetworkCapabilities.hasTransport(eq(transportType))).thenReturn(true);
+ 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();
+ }
- IwlanNetworkMonitorCallback networkMonitorCallback =
- mIwlanDataService.getNetworkMonitorCallback();
- networkMonitorCallback.onCapabilitiesChanged(mMockNetwork, mockNetworkCapabilities);
+ private void onSystemDefaultNetworkConnected(int transportType) {
+ Network newNetwork = createMockNetwork(mLinkProperties);
+ onSystemDefaultNetworkConnected(
+ newNetwork, mLinkProperties, transportType, DEFAULT_SUB_INDEX);
}
- private void verifyNetworkLost() {
- IwlanNetworkMonitorCallback networkMonitorCallback =
- mIwlanDataService.getNetworkMonitorCallback();
+ private void onSystemDefaultNetworkLost() {
+ NetworkCallback networkMonitorCallback = getNetworkMonitorCallback();
networkMonitorCallback.onLost(mMockNetwork);
+ mTestLooper.dispatchAll();
}
@Test
- public void testWifionConnected() {
- verifyNetworkConnected(TRANSPORT_WIFI);
+ public void testWifiOnConnected() {
+ onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
assertTrue(
mIwlanDataService.isNetworkConnected(
false /* isActiveDataOnOtherSub */, false /* isCstEnabled */));
@@ -283,7 +330,7 @@ public class IwlanDataServiceTest {
when(mMockIwlanDataServiceProvider.getSlotIndex()).thenReturn(DEFAULT_SLOT_INDEX + 1);
mIwlanDataService.addIwlanDataServiceProvider(mMockIwlanDataServiceProvider);
- verifyNetworkLost();
+ onSystemDefaultNetworkLost();
assertFalse(
mIwlanDataService.isNetworkConnected(
false /* isActiveDataOnOtherSub */, false /* isCstEnabled */));
@@ -293,12 +340,115 @@ public class IwlanDataServiceTest {
}
@Test
- public void testNetworkNotConnectedWithCellularAndCrossSimDisabled()
+ 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 */);
+
+ 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());
+ }
+
+ @Test
+ public void testNetworkNotConnectedWithCellularOnSameSubAndCrossSimEnabled()
throws InterruptedException {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
- mIwlanDataService.getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
+ getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
boolean isActiveDataOnOtherSub =
mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
@@ -310,11 +460,12 @@ public class IwlanDataServiceTest {
}
@Test
- public void testCrossSimNetworkConnectedWithTelephonyNetwork() throws InterruptedException {
+ public void testCrossSimNetworkConnectedWithCellularOnDifferentSub()
+ throws InterruptedException {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, false /* isVcn */);
- mIwlanDataService.getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
+ getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
boolean isActiveDataOnOtherSub =
mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
@@ -326,11 +477,12 @@ public class IwlanDataServiceTest {
}
@Test
- public void testCrossSimNetworkConnectedWithVcn() throws InterruptedException {
+ public void testCrossSimNetworkConnectedWithVcnCellularOnDifferentSub()
+ throws InterruptedException {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, true /* isVcn */);
- mIwlanDataService.getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
+ getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
boolean isActiveDataOnOtherSub =
mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
@@ -342,6 +494,72 @@ public class IwlanDataServiceTest {
}
@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);
+ 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(
@@ -371,7 +589,7 @@ public class IwlanDataServiceTest {
IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
TunnelLinkProperties mLinkProperties =
TunnelLinkPropertiesTest.createTestTunnelLinkProperties();
- mIwlanDataServiceProvider.setTunnelState(
+ mSpyIwlanDataServiceProvider.setTunnelState(
dp,
new DataServiceCallback(callback),
TunnelState.TUNNEL_UP,
@@ -379,7 +597,7 @@ public class IwlanDataServiceTest {
false, /* isHandover */
1, /* pduSessionId */
true /* isImsOrEmergency */);
- mIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
+ mSpyIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
mTestLooper.dispatchAll();
latch.await(1, TimeUnit.SECONDS);
@@ -424,7 +642,7 @@ public class IwlanDataServiceTest {
public void testRequestDataCallListEmpty() throws Exception {
latch = new CountDownLatch(1);
IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
- mIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
+ mSpyIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
mTestLooper.dispatchAll();
latch.await(1, TimeUnit.SECONDS);
@@ -434,7 +652,7 @@ public class IwlanDataServiceTest {
@Test
public void testIwlanSetupDataCallWithInvalidArg() {
- mIwlanDataServiceProvider.setupDataCall(
+ mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.UNKNOWN, /* AccessNetworkType */
null, /* dataProfile */
false, /* isRoaming */
@@ -458,10 +676,9 @@ public class IwlanDataServiceTest {
DataProfile dp = buildImsDataProfile();
/* Wifi is not connected */
- mIwlanDataService.setNetworkConnected(
- false, mMockNetwork, IwlanDataService.Transport.UNSPECIFIED_NETWORK);
+ onSystemDefaultNetworkLost();
- mIwlanDataServiceProvider.setupDataCall(
+ mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
@@ -483,7 +700,7 @@ public class IwlanDataServiceTest {
@Test
public void testIwlanDeactivateDataCallWithInvalidArg() {
- mIwlanDataServiceProvider.deactivateDataCall(
+ mSpyIwlanDataServiceProvider.deactivateDataCall(
0, /* cid */
DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
mMockDataServiceCallback);
@@ -498,9 +715,8 @@ public class IwlanDataServiceTest {
DataProfile dp = buildImsDataProfile();
/* Wifi is connected */
- mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
-
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
+ onSystemDefaultNetworkConnected(
+ mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
@@ -538,9 +754,8 @@ public class IwlanDataServiceTest {
DataProfile dp = buildImsDataProfile();
/* Wifi is connected */
- mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
-
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
+ onSystemDefaultNetworkConnected(
+ mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
@@ -585,9 +800,7 @@ public class IwlanDataServiceTest {
public void testIwlanDeactivateDataCallWithCloseTunnel() {
DataProfile dp = buildImsDataProfile();
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
-
- verifyNetworkConnected(TRANSPORT_WIFI);
+ onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
@@ -624,9 +837,7 @@ public class IwlanDataServiceTest {
public void testIwlanDeactivateDataCallAfterSuccessHandover() {
DataProfile dp = buildImsDataProfile();
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
-
- verifyNetworkConnected(TRANSPORT_WIFI);
+ onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
@@ -995,16 +1206,11 @@ public class IwlanDataServiceTest {
@Test
public void testDnsPrefetching() throws Exception {
- IwlanNetworkMonitorCallback mNetworkMonitorCallback =
- mIwlanDataService.getNetworkMonitorCallback();
+ NetworkCallback networkCallback = getNetworkMonitorCallback();
/* Wifi is connected */
- mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
-
- List<LinkAddress> linkAddresses = new ArrayList<>();
- linkAddresses.add(mMockIPv4LinkAddress);
-
- when(mMockLinkProperties.getLinkAddresses()).thenReturn(linkAddresses);
- mNetworkMonitorCallback.onLinkPropertiesChanged(mMockNetwork, mMockLinkProperties);
+ onSystemDefaultNetworkConnected(
+ mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
+ networkCallback.onLinkPropertiesChanged(mMockNetwork, mLinkProperties);
mIwlanDataService
.mIwlanDataServiceHandler
@@ -1023,10 +1229,12 @@ public class IwlanDataServiceTest {
.sendToTarget();
mTestLooper.dispatchAll();
- linkAddresses.add(mMockIPv6LinkAddress);
+ LinkProperties newLinkProperties = new LinkProperties();
+ newLinkProperties.setInterfaceName("wlan0");
+ newLinkProperties.addLinkAddress(mMockIPv4LinkAddress);
+ newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
- when(mMockLinkProperties.getLinkAddresses()).thenReturn(linkAddresses);
- mNetworkMonitorCallback.onLinkPropertiesChanged(mMockNetwork, mMockLinkProperties);
+ networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
/* Prefetching will be triggered twice.
1. Network connected, CarrierConfig ready, WifiCallingSetting enabled
@@ -1108,9 +1316,9 @@ public class IwlanDataServiceTest {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
- mIwlanDataService.getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
+ getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
- mIwlanDataServiceProvider.setupDataCall(
+ mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
dp, /* dataProfile */
false, /* isRoaming */
@@ -1140,7 +1348,7 @@ public class IwlanDataServiceTest {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
- mIwlanDataService.getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
+ getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
@@ -1173,9 +1381,7 @@ public class IwlanDataServiceTest {
NetworkCapabilities nc =
prepareNetworkCapabilitiesForTest(
TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, false /* isVcn */);
- mIwlanDataService.getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
-
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
+ getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
@@ -1212,8 +1418,9 @@ public class IwlanDataServiceTest {
public void testIwlanTunnelStatsFailureCounts() {
DataProfile dp = buildImsDataProfile();
- mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
+ onSystemDefaultNetworkConnected(
+ mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
+
when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
.thenReturn(mMockErrorPolicyManager);
@@ -1238,8 +1445,8 @@ public class IwlanDataServiceTest {
when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
.thenReturn(DataFailCause.ERROR_UNSPECIFIED);
- mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
+ onSystemDefaultNetworkConnected(
+ mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
long count = 3L;
for (int i = 0; i < count; i++) {
@@ -1260,8 +1467,8 @@ public class IwlanDataServiceTest {
when(calendar.getTime()).thenAnswer(i -> new Date(mMockedCalendarTime));
mSpyIwlanDataServiceProvider.setCalendar(calendar);
- mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
+ onSystemDefaultNetworkConnected(
+ mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
LongSummaryStatistics tunnelSetupSuccessStats = new LongSummaryStatistics();
LongSummaryStatistics tunnelUpStats = new LongSummaryStatistics();
@@ -1312,7 +1519,7 @@ public class IwlanDataServiceTest {
@Test
public void testIwlanDataServiceHandlerOnUnbind() {
DataProfile dp = buildImsDataProfile();
- doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
+
mSpyIwlanDataServiceProvider.setTunnelState(
dp,
mMockDataServiceCallback,
@@ -1357,6 +1564,122 @@ public class IwlanDataServiceTest {
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 */);
+
+ 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 */);
+
+ 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());
+ }
+
private void mockTunnelSetupFail(DataProfile dp) {
mSpyIwlanDataServiceProvider.setupDataCall(
AccessNetworkType.IWLAN, /* AccessNetworkType */
@@ -1447,4 +1770,12 @@ public class IwlanDataServiceTest {
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);
+ }
}
diff --git a/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java b/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java
index 4a9d5a4..3f23dab 100644
--- a/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java
+++ b/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java
@@ -80,6 +80,8 @@ public class EpdgSelectorTest {
private static final String TEST_IP_ADDRESS_3 = "127.0.0.4";
private static final String TEST_IP_ADDRESS_4 = "127.0.0.5";
private static final String TEST_IP_ADDRESS_5 = "127.0.0.6";
+ private static final String TEST_IP_ADDRESS_6 = "127.0.0.7";
+ private static final String TEST_IP_ADDRESS_7 = "127.0.0.8";
private static final String TEST_IPV6_ADDRESS = "0000:0000:0000:0000:0000:0000:0000:0001";
private static int testPcoIdIPv6 = 0xFF01;
@@ -122,7 +124,7 @@ public class EpdgSelectorTest {
when(ErrorPolicyManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX))
.thenReturn(mMockErrorPolicyManager);
- mEpdgSelector = new EpdgSelector(mMockContext, DEFAULT_SLOT_INDEX);
+ mEpdgSelector = spy(new EpdgSelector(mMockContext, DEFAULT_SLOT_INDEX));
when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
.thenReturn(mMockSubscriptionManager);
@@ -134,6 +136,8 @@ public class EpdgSelectorTest {
when(mMockSubscriptionInfo.getMncString()).thenReturn("120");
+ when(mMockTelephonyManager.getNetworkOperator()).thenReturn("311120");
+
when(mMockContext.getSystemService(eq(TelephonyManager.class)))
.thenReturn(mMockTelephonyManager);
@@ -159,8 +163,6 @@ public class EpdgSelectorTest {
.thenReturn(mMockCarrierConfigManager);
when(mMockCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mTestBundle);
- lenient().when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
-
mFakeDns = new FakeDns();
mFakeDns.startMocking();
}
@@ -173,6 +175,10 @@ public class EpdgSelectorTest {
@Test
public void testStaticMethodPass() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
// Set DnsResolver query mock
final String testStaticAddress = "epdg.epc.mnc088.mcc888.pub.3gppnetwork.org";
mFakeDns.setAnswer(testStaticAddress, new String[] {TEST_IP_ADDRESS}, TYPE_A);
@@ -189,12 +195,32 @@ public class EpdgSelectorTest {
InetAddress expectedAddress = InetAddress.getByName(TEST_IP_ADDRESS);
- assertEquals(testInetAddresses.size(), 1);
- assertEquals(testInetAddresses.get(0), expectedAddress);
+ assertEquals(1, testInetAddresses.size());
+ assertEquals(expectedAddress, testInetAddresses.get(0));
+ }
+
+ @Test
+ public void testStaticMethodDirectIpAddress_noDnsResolution() throws Exception {
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
+ // Carrier config directly contains the ePDG IP address.
+ mTestBundle.putString(
+ CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, TEST_IP_ADDRESS);
+
+ ArrayList<InetAddress> testInetAddresses =
+ getValidatedServerListWithDefaultParams(false /*isEmergency*/);
+
+ assertEquals(1, testInetAddresses.size());
+ assertEquals(InetAddresses.parseNumericAddress(TEST_IP_ADDRESS), testInetAddresses.get(0));
}
@Test
public void testRoamStaticMethodPass() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
// Set DnsResolver query mock
final String testRoamStaticAddress = "epdg.epc.mnc088.mcc888.pub.3gppnetwork.org";
mFakeDns.setAnswer(testRoamStaticAddress, new String[] {TEST_IP_ADDRESS}, TYPE_A);
@@ -212,8 +238,8 @@ public class EpdgSelectorTest {
InetAddress expectedAddress = InetAddress.getByName(TEST_IP_ADDRESS);
- assertEquals(testInetAddresses.size(), 1);
- assertEquals(testInetAddresses.get(0), expectedAddress);
+ assertEquals(1, testInetAddresses.size());
+ assertEquals(expectedAddress, testInetAddresses.get(0));
}
@Test
@@ -228,65 +254,275 @@ public class EpdgSelectorTest {
@Test
public void testPlmnResolutionMethodWithNoPlmnInCarrierConfig() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
// setUp() fills default values for mcc-mnc
- String expectedFqdn1 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
- String expectedFqdn2 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
+ String expectedFqdnFromImsi = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
+ String expectedFqdnFromEhplmn = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
- mFakeDns.setAnswer(expectedFqdn1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
- mFakeDns.setAnswer(expectedFqdn2, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
+ mFakeDns.setAnswer(expectedFqdnFromImsi, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
+ mFakeDns.setAnswer(expectedFqdnFromEhplmn, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
ArrayList<InetAddress> testInetAddresses =
getValidatedServerListWithDefaultParams(false /*isEmergency*/);
- assertEquals(testInetAddresses.size(), 2);
+ assertEquals(2, testInetAddresses.size());
assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS_1)));
assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS_2)));
}
private void testPlmnResolutionMethod(boolean isEmergency) throws Exception {
- String expectedFqdnFromHplmn = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
- String expectedFqdnFromEHplmn = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
- String expectedFqdnFromConfig = "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ String expectedFqdnFromImsi = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
+ String expectedFqdnFromRplmn = "epdg.epc.mnc121.mcc311.pub.3gppnetwork.org";
+ String expectedFqdnFromEhplmn = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
+ String excludedFqdnFromConfig = "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
+
+ when(mMockTelephonyManager.getNetworkOperator()).thenReturn("311121");
mTestBundle.putIntArray(
CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
mTestBundle.putStringArray(
CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY,
- new String[] {"310-480", "300-120", "311-120"});
+ new String[] {"310-480", "300-120", "311-120", "311-121"});
- mFakeDns.setAnswer(expectedFqdnFromHplmn, new String[] {TEST_IP_ADDRESS}, TYPE_A);
- mFakeDns.setAnswer(expectedFqdnFromEHplmn, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
- mFakeDns.setAnswer(expectedFqdnFromConfig, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
+ mFakeDns.setAnswer(expectedFqdnFromImsi, new String[] {TEST_IP_ADDRESS}, TYPE_A);
+ mFakeDns.setAnswer(expectedFqdnFromEhplmn, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
+ mFakeDns.setAnswer(excludedFqdnFromConfig, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
+ mFakeDns.setAnswer("sos." + expectedFqdnFromImsi, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
mFakeDns.setAnswer(
- "sos." + expectedFqdnFromHplmn, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
+ "sos." + expectedFqdnFromEhplmn, new String[] {TEST_IP_ADDRESS_4}, TYPE_A);
mFakeDns.setAnswer(
- "sos." + expectedFqdnFromEHplmn, new String[] {TEST_IP_ADDRESS_4}, TYPE_A);
+ "sos." + excludedFqdnFromConfig, new String[] {TEST_IP_ADDRESS_5}, TYPE_A);
+ mFakeDns.setAnswer(expectedFqdnFromRplmn, new String[] {TEST_IP_ADDRESS_6}, TYPE_A);
mFakeDns.setAnswer(
- "sos." + expectedFqdnFromConfig, new String[] {TEST_IP_ADDRESS_5}, TYPE_A);
+ "sos." + expectedFqdnFromRplmn, new String[] {TEST_IP_ADDRESS_7}, TYPE_A);
ArrayList<InetAddress> testInetAddresses =
getValidatedServerListWithDefaultParams(isEmergency);
if (isEmergency) {
assertEquals(6, testInetAddresses.size());
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_3), testInetAddresses.get(0));
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(1));
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_4), testInetAddresses.get(2));
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(3));
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_5), testInetAddresses.get(4));
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(5));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_7), testInetAddresses.get(0));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_6), testInetAddresses.get(1));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_3), testInetAddresses.get(2));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(3));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_4), testInetAddresses.get(4));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(5));
} else {
assertEquals(3, testInetAddresses.size());
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(0));
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(1));
- assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(2));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_6), testInetAddresses.get(0));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(1));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(2));
}
}
@Test
+ public void testPlmnResolutionMethodWithDuplicatedImsiAndEhplmn() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ String fqdnFromEhplmn1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
+ String fqdnFromEhplmn2AndImsi = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
+ String fqdnFromEhplmn3 = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
+ String fqdnFromEhplmn4 = "epdg.epc.mnc123.mcc300.pub.3gppnetwork.org";
+
+ when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300121");
+ ehplmnList.add("300122");
+ ehplmnList.add("300123");
+
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ new int[] {
+ CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
+ CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
+ });
+
+ mFakeDns.setAnswer(fqdnFromEhplmn1, new String[] {TEST_IP_ADDRESS}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn2AndImsi, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn3, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn4, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
+
+ ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
+
+ assertEquals(4, testInetAddresses.size());
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(1));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(2));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_3), testInetAddresses.get(3));
+ }
+
+ @Test
+ public void testPlmnResolutionMethodWithInvalidLengthPlmns() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ when(mMockSubscriptionInfo.getMccString()).thenReturn("31");
+ when(mMockSubscriptionInfo.getMncString()).thenReturn("12");
+
+ when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300");
+ ehplmnList.add("3001");
+ ehplmnList.add("3");
+
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ new int[] {
+ CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN,
+ CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
+ CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
+ });
+
+ ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
+
+ assertEquals(0, testInetAddresses.size());
+ }
+
+ @Test
+ public void testPlmnResolutionMethodWithInvalidCharacterPlmns() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ when(mMockSubscriptionInfo.getMccString()).thenReturn("a b");
+ when(mMockSubscriptionInfo.getMncString()).thenReturn("!@#");
+
+ when(mMockTelephonyManager.getNetworkOperator()).thenReturn("a cde#");
+ ehplmnList.add("abcdef");
+ ehplmnList.add("1 23456");
+ ehplmnList.add("1 2345");
+
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ new int[] {
+ CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN,
+ CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
+ CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
+ });
+
+ ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
+
+ assertEquals(0, testInetAddresses.size());
+ }
+
+ @Test
+ public void testPlmnResolutionMethodWithEmptyPlmns() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ when(mMockSubscriptionInfo.getMccString()).thenReturn(null);
+ when(mMockSubscriptionInfo.getMncString()).thenReturn(null);
+
+ when(mMockTelephonyManager.getNetworkOperator()).thenReturn("");
+ ehplmnList.add("");
+
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ new int[] {
+ CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN,
+ CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
+ CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
+ });
+
+ ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
+
+ assertEquals(0, testInetAddresses.size());
+ }
+
+ @Test
+ public void testPlmnResolutionMethodWithFirstEhplmn() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ String fqdnFromEhplmn1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
+ String fqdnFromEhplmn2 = "epdg.epc.mnc121.mcc300.pub.3gppnetwork.org";
+ String fqdnFromEhplmn3 = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
+ String fqdnFromEhplmn4 = "epdg.epc.mnc123.mcc300.pub.3gppnetwork.org";
+
+ ehplmnList.add("300121");
+ ehplmnList.add("300122");
+ ehplmnList.add("300123");
+
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_FIRST});
+
+ mFakeDns.setAnswer(fqdnFromEhplmn1, new String[] {TEST_IP_ADDRESS}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn2, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn3, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn4, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
+
+ ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
+
+ assertEquals(1, testInetAddresses.size());
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(0));
+ }
+
+ @Test
+ public void testPlmnResolutionMethodWithRplmn() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ String fqdnFromRplmn = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
+ String fqdnFromEhplmn1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
+ String fqdnFromEhplmn2 = "epdg.epc.mnc121.mcc300.pub.3gppnetwork.org";
+
+ when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300122");
+ ehplmnList.add("300121");
+
+ mTestBundle.putStringArray(
+ CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY,
+ new String[] {"310-480", "300-122", "300-121"});
+
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
+ mTestBundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ new int[] {CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN});
+
+ mFakeDns.setAnswer(fqdnFromRplmn, new String[] {TEST_IP_ADDRESS}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
+ mFakeDns.setAnswer(fqdnFromEhplmn2, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
+
+ ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
+
+ assertEquals(1, testInetAddresses.size());
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(0));
+ }
+
+ @Test
public void testCarrierConfigStaticAddressList() throws Exception {
- // Set Network.getAllByName mock
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
+ // Set DnsResolver query mock
final String addr1 = "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
final String addr2 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
final String addr3 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
@@ -306,10 +542,10 @@ public class EpdgSelectorTest {
ArrayList<InetAddress> testInetAddresses =
getValidatedServerListWithDefaultParams(false /*isEmergency*/);
- assertEquals(testInetAddresses.size(), 3);
- assertEquals(testInetAddresses.get(0), InetAddress.getByName(TEST_IP_ADDRESS_1));
- assertEquals(testInetAddresses.get(1), InetAddress.getByName(TEST_IP_ADDRESS_2));
- assertEquals(testInetAddresses.get(2), InetAddress.getByName(TEST_IP_ADDRESS));
+ assertEquals(3, testInetAddresses.size());
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(1));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(2));
}
private ArrayList<InetAddress> getValidatedServerListWithDefaultParams(boolean isEmergency)
@@ -336,7 +572,7 @@ public class EpdgSelectorTest {
new EpdgSelector.EpdgSelectorCallback() {
@Override
public void onServerListChanged(
- int transactionId, ArrayList<InetAddress> validIPList) {
+ int transactionId, List<InetAddress> validIPList) {
assertEquals(transactionId, 1234);
for (InetAddress mInetAddress : validIPList) {
@@ -389,7 +625,7 @@ public class EpdgSelectorTest {
ArrayList<InetAddress> testInetAddresses =
getValidatedServerListWithDefaultParams(false /* isEmergency */);
- assertEquals(testInetAddresses.size(), 2);
+ assertEquals(2, testInetAddresses.size());
assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS)));
assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IPV6_ADDRESS)));
}
@@ -410,6 +646,8 @@ public class EpdgSelectorTest {
}
private void testCellularResolutionMethod(boolean isEmergency) throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+
int testMcc = 311;
int testMnc = 120;
String testMccString = "311";
@@ -461,10 +699,10 @@ public class EpdgSelectorTest {
ArrayList<InetAddress> testInetAddresses =
getValidatedServerListWithDefaultParams(isEmergency);
- assertEquals(testInetAddresses.size(), 3);
- assertEquals(testInetAddresses.get(0), InetAddress.getByName(TEST_IP_ADDRESS));
- assertEquals(testInetAddresses.get(1), InetAddress.getByName(TEST_IP_ADDRESS_1));
- assertEquals(testInetAddresses.get(2), InetAddress.getByName(TEST_IP_ADDRESS_2));
+ assertEquals(3, testInetAddresses.size());
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(0));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(1));
+ assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(2));
}
private void setAnswerForCellularMethod(boolean isEmergency, int mcc, int mnc)
@@ -505,6 +743,10 @@ public class EpdgSelectorTest {
@Test
public void testGetValidatedServerListIpv4Preferred() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
final String testStaticAddress = addr1 + "," + addr2;
@@ -532,6 +774,10 @@ public class EpdgSelectorTest {
@Test
public void testGetValidatedServerListIpv6Preferred() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
final String testStaticAddress = addr1 + "," + addr2;
@@ -559,6 +805,10 @@ public class EpdgSelectorTest {
@Test
public void testGetValidatedServerListIpv4Only() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
final String testStaticAddress = addr1 + "," + addr2;
@@ -585,6 +835,10 @@ public class EpdgSelectorTest {
@Test
public void testGetValidatedServerListIpv4OnlyCongestion() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
when(mMockErrorPolicyManager.getMostRecentDataFailCause())
.thenReturn(DataFailCause.IWLAN_CONGESTION);
when(mMockErrorPolicyManager.getCurrentFqdnIndex(anyInt())).thenReturn(0);
@@ -616,6 +870,10 @@ public class EpdgSelectorTest {
@Test
public void testGetValidatedServerListIpv6Only() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
final String testStaticAddress = addr1 + "," + addr2;
@@ -642,6 +900,10 @@ public class EpdgSelectorTest {
@Test
public void testGetValidatedServerListSystemPreferred() throws Exception {
+ when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
+ doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
+ doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
+
final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
final String addr3 = "epdg.epc.mnc120.mcc312.pub.3gppnetwork.org";
@@ -695,20 +957,20 @@ public class EpdgSelectorTest {
}
}
- private final ArrayList<DnsEntry> mAnswers = new ArrayList<DnsEntry>();
+ private final List<DnsEntry> mAnswers = new ArrayList<>();
/** Clears all DNS entries. */
private synchronized void clearAll() {
mAnswers.clear();
}
- /** Returns the answer for a given name and type on the given mock network. */
- private synchronized List<InetAddress> getAnswer(Object mock, String hostname, int type) {
+ /** Returns the answer for a given name and type. */
+ private synchronized List<InetAddress> getAnswer(String hostname, int type) {
return mAnswers.stream()
.filter(e -> e.matches(hostname, type))
.map(answer -> answer.mAddresses)
.findFirst()
- .orElse(null);
+ .orElse(List.of());
}
/** Sets the answer for a given name and type. */
@@ -729,10 +991,20 @@ public class EpdgSelectorTest {
}
// Regardless of the type, depends on what the responses contained in the network.
- private List<InetAddress> queryAllTypes(Object mock, String hostname) {
+ private List<InetAddress> queryIpv4(String hostname) {
+ return getAnswer(hostname, TYPE_A);
+ }
+
+ // Regardless of the type, depends on what the responses contained in the network.
+ private List<InetAddress> queryIpv6(String hostname) {
+ return getAnswer(hostname, TYPE_AAAA);
+ }
+
+ // Regardless of the type, depends on what the responses contained in the network.
+ private List<InetAddress> queryAllTypes(String hostname) {
List<InetAddress> answer = new ArrayList<>();
- addAllIfNotNull(answer, getAnswer(mock, hostname, TYPE_A));
- addAllIfNotNull(answer, getAnswer(mock, hostname, TYPE_AAAA));
+ answer.addAll(queryIpv4(hostname));
+ answer.addAll(queryIpv6(hostname));
return answer;
}
@@ -744,32 +1016,55 @@ public class EpdgSelectorTest {
/** Starts mocking DNS queries. */
private void startMocking() throws UnknownHostException {
+ // 5-arg DnsResolver.query()
doAnswer(
invocation -> {
return mockQuery(
invocation,
1 /* posHostname */,
+ -1 /* posType */,
3 /* posExecutor */,
- 5 /* posCallback */,
- -1 /* posType */);
+ 5 /* posCallback */);
})
.when(mMockDnsResolver)
- .query(any(), any(), anyInt(), any(), any(), any());
+ .query(any(), anyString(), anyInt(), any(), any(), any());
+
+ // 6-arg DnsResolver.query() with explicit query type (IPv4 or v6).
+ doAnswer(
+ invocation -> {
+ return mockQuery(
+ invocation,
+ 1 /* posHostname */,
+ 2 /* posType */,
+ 4 /* posExecutor */,
+ 6 /* posCallback */);
+ })
+ .when(mMockDnsResolver)
+ .query(any(), anyString(), anyInt(), anyInt(), any(), any(), any());
}
// Mocking queries on DnsResolver#query.
private Answer mockQuery(
InvocationOnMock invocation,
int posHostname,
+ int posType,
int posExecutor,
- int posCallback,
- int posType) {
- String hostname = (String) invocation.getArgument(posHostname);
- Executor executor = (Executor) invocation.getArgument(posExecutor);
+ int posCallback) {
+ String hostname = invocation.getArgument(posHostname);
+ Executor executor = invocation.getArgument(posExecutor);
DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(posCallback);
List<InetAddress> answer;
- answer = queryAllTypes(invocation.getMock(), hostname);
+ switch (posType) {
+ case TYPE_A:
+ answer = queryIpv4(hostname);
+ break;
+ case TYPE_AAAA:
+ answer = queryIpv6(hostname);
+ break;
+ default:
+ answer = queryAllTypes(hostname);
+ }
if (answer != null && answer.size() > 0) {
new Handler(Looper.getMainLooper())
diff --git a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
index 8f14ff5..76ceec8 100644
--- a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
+++ b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
@@ -104,23 +105,23 @@ public class EpdgTunnelManagerTest {
public static final int DEFAULT_TOKEN = 0;
private static final String EPDG_ADDRESS = "127.0.0.1";
+ private static final String EPDG_ADDRESS_IPV6 = "2600:387:f:707::1";
private static final String TEST_APN_NAME = "www.xyz.com";
- private static final ArrayList<InetAddress> EXPECTED_LOCAL_ADDRESSES =
- new ArrayList<>(List.of(InetAddresses.parseNumericAddress("201.1.100.10")));
- private static final ArrayList<InetAddress> EXPECTED_IPV6_LOCAL_ADDRESSES =
- new ArrayList<>(List.of(InetAddresses.parseNumericAddress("2001:db8::1:2")));
- private static final ArrayList<InetAddress> EXPECTED_EPDG_ADDRESSES =
- new ArrayList<>(List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS)));
- private static final ArrayList<LinkAddress> EXPECTED_INTERNAL_ADDRESSES =
- new ArrayList<>(
- List.of(
- new LinkAddress(
- InetAddresses.parseNumericAddress("198.50.100.10"), 24)));
- private static final ArrayList<InetAddress> EXPECTED_PCSCF_ADDRESSES =
- new ArrayList<>(List.of(InetAddresses.parseNumericAddress("198.51.100.10")));
- private static final ArrayList<InetAddress> EXPECTED_DNS_ADDRESSES =
- new ArrayList<>(List.of(InetAddresses.parseNumericAddress("198.50.100.10")));
+ private static final List<InetAddress> EXPECTED_LOCAL_ADDRESSES =
+ List.of(InetAddresses.parseNumericAddress("201.1.100.10"));
+ private static final List<InetAddress> EXPECTED_IPV6_LOCAL_ADDRESSES =
+ List.of(InetAddresses.parseNumericAddress("2001:db8::1:2"));
+ private static final List<InetAddress> EXPECTED_EPDG_ADDRESSES =
+ List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS));
+ private static final List<InetAddress> EXPECTED_EPDG_ADDRESSES_IPV6 =
+ List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS_IPV6));
+ private static final List<LinkAddress> EXPECTED_INTERNAL_ADDRESSES =
+ List.of(new LinkAddress(InetAddresses.parseNumericAddress("198.50.100.10"), 24));
+ private static final List<InetAddress> EXPECTED_PCSCF_ADDRESSES =
+ List.of(InetAddresses.parseNumericAddress("198.51.100.10"));
+ private static final List<InetAddress> EXPECTED_DNS_ADDRESSES =
+ List.of(InetAddresses.parseNumericAddress("198.50.100.10"));
private EpdgTunnelManager mEpdgTunnelManager;
@@ -134,11 +135,11 @@ public class EpdgTunnelManagerTest {
private TestLooper mTestLooper = new TestLooper();
@Mock private Context mMockContext;
+ @Mock private Network mMockDefaultNetwork;
@Mock private IwlanTunnelCallback mMockIwlanTunnelCallback;
@Mock private IwlanTunnelMetricsImpl mMockIwlanTunnelMetrics;
@Mock private IkeSession mMockIkeSession;
@Mock private EpdgSelector mMockEpdgSelector;
- @Mock private Network mMockNetwork;
@Mock CarrierConfigManager mMockCarrierConfigManager;
@Mock ConnectivityManager mMockConnectivityManager;
@Mock SubscriptionManager mMockSubscriptionManager;
@@ -177,7 +178,6 @@ public class EpdgTunnelManagerTest {
doReturn(mTestLooper.getLooper()).when(mEpdgTunnelManager).getLooper();
setVariable(mEpdgTunnelManager, "mContext", mMockContext);
mEpdgTunnelManager.initHandler();
- mEpdgTunnelManager.resetTunnelManagerState();
doReturn(mMockEpdgSelector).when(mEpdgTunnelManager).getEpdgSelector();
when(mEpdgTunnelManager.getIkeSessionCreator()).thenReturn(mMockIkeSessionCreator);
@@ -187,7 +187,7 @@ public class EpdgTunnelManagerTest {
anyInt(),
anyBoolean(),
anyBoolean(),
- eq(mMockNetwork),
+ any(Network.class),
any(EpdgSelector.EpdgSelectorCallback.class)))
.thenReturn(new IwlanError(IwlanError.NO_ERROR));
@@ -202,16 +202,20 @@ public class EpdgTunnelManagerTest {
when(mMockChildSessionConfiguration.getInternalAddresses())
.thenReturn(EXPECTED_INTERNAL_ADDRESSES);
- when(mMockIpSecManager.createIpSecTunnelInterface(any(), any(), any()))
+ when(mMockIpSecManager.createIpSecTunnelInterface(
+ any(InetAddress.class), any(InetAddress.class), any(Network.class)))
.thenReturn(mMockIpSecTunnelInterface);
+ when(mMockIpSecTunnelInterface.getInterfaceName()).thenReturn("ipsec10");
- when(mMockIpSecTunnelInterface.getInterfaceName()).thenReturn("wlan0");
-
- when(mMockIkeSessionConnectionInfo.getNetwork()).thenReturn(mMockNetwork);
+ when(mMockIkeSessionConnectionInfo.getNetwork()).thenReturn(mMockDefaultNetwork);
doReturn(EXPECTED_LOCAL_ADDRESSES)
.when(mEpdgTunnelManager)
.getAddressForNetwork(any(), any());
+
+ when(mMockLinkProperties.isReachable(any())).thenReturn(true);
+ mEpdgTunnelManager.updateNetwork(mMockDefaultNetwork, mMockLinkProperties);
+ mTestLooper.dispatchAll();
}
@Test
@@ -346,11 +350,12 @@ public class EpdgTunnelManagerTest {
anyInt(),
eq(false),
eq(false),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any());
}
- private void setupTunnelBringup(String apnName, int transactionId) throws Exception {
+ private void setupTunnelBringup(
+ String apnName, List<InetAddress> epdgAddresses, int transactionId) throws Exception {
setupMockForGetConfig(null);
doReturn(null)
.when(mMockIkeSessionCreator)
@@ -373,12 +378,12 @@ public class EpdgTunnelManagerTest {
mTestLooper.dispatchAll();
mEpdgTunnelManager.sendSelectionRequestComplete(
- EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), transactionId);
+ epdgAddresses, new IwlanError(IwlanError.NO_ERROR), transactionId);
mTestLooper.dispatchAll();
}
private void setupTunnelBringup() throws Exception {
- setupTunnelBringup(TEST_APN_NAME, 1 /* transactionId */);
+ setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, 1 /* transactionId */);
}
@Test
@@ -472,30 +477,25 @@ public class EpdgTunnelManagerTest {
@Test
public void testBringUpTunnelWithMobilityOptions() throws Exception {
- doReturn(null)
- .when(mMockIkeSessionCreator)
+ setupTunnelBringup();
+ ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mMockIkeSessionCreator, atLeastOnce())
.createIkeSession(
eq(mMockContext),
- any(IkeSessionParams.class),
+ ikeSessionParamsCaptor.capture(),
any(ChildSessionParams.class),
any(Executor.class),
any(IkeSessionCallback.class),
any(ChildSessionCallback.class));
+ IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
+ assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE));
+ assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY));
+ }
- doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME));
-
- boolean ret =
- mEpdgTunnelManager.bringUpTunnel(
- getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
- mMockIwlanTunnelCallback,
- mMockIwlanTunnelMetrics);
- assertTrue(ret);
- mTestLooper.dispatchAll();
-
- mEpdgTunnelManager.sendSelectionRequestComplete(
- EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
- mTestLooper.dispatchAll();
-
+ @Test
+ public void testBringUpTunnelIpv6_verifyMobikeDisabled() throws Exception {
+ setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES_IPV6, 1);
ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
ArgumentCaptor.forClass(IkeSessionParams.class);
verify(mMockIkeSessionCreator, atLeastOnce())
@@ -507,8 +507,8 @@ public class EpdgTunnelManagerTest {
any(IkeSessionCallback.class),
any(ChildSessionCallback.class));
IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
- assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE));
assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY));
+ assertFalse(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE));
}
@Test
@@ -628,16 +628,6 @@ public class EpdgTunnelManagerTest {
setupMockForGetConfig(bundle);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
-
doReturn(null)
.when(mMockIkeSessionCreator)
.createIkeSession(
@@ -696,16 +686,6 @@ public class EpdgTunnelManagerTest {
setupMockForGetConfig(bundle);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
-
doReturn(null)
.when(mMockIkeSessionCreator)
.createIkeSession(
@@ -755,15 +735,6 @@ public class EpdgTunnelManagerTest {
bundle.putInt(CarrierConfigManager.Iwlan.KEY_DPD_TIMER_SEC_INT, testDpdDelay);
setupMockForGetConfig(bundle);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
doReturn(null)
.when(mMockIkeSessionCreator)
@@ -815,15 +786,6 @@ public class EpdgTunnelManagerTest {
doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
setupMockForGetConfig(null);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
doReturn(null)
.doReturn(null)
@@ -874,15 +836,6 @@ public class EpdgTunnelManagerTest {
doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
setupMockForGetConfig(null);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
doReturn(null)
.doReturn(null)
@@ -1000,15 +953,7 @@ public class EpdgTunnelManagerTest {
}
setupMockForGetConfig(null);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
+
doReturn(null)
.doReturn(null)
.when(mMockIkeSessionCreator)
@@ -1078,7 +1023,6 @@ public class EpdgTunnelManagerTest {
TunnelSetupRequest ret =
TunnelSetupRequest.builder()
.setApnName(apnName)
- .setNetwork(mMockNetwork)
.setIsRoaming(false /*isRoaming*/)
.setIsEmergency(false /*IsEmergency*/)
.setRequestPcscf(false /*requestPcscf*/)
@@ -1091,7 +1035,6 @@ public class EpdgTunnelManagerTest {
private TunnelSetupRequest getHandoverTunnelSetupRequest(String apnName, int apnIpProtocol) {
TunnelSetupRequest.Builder bld = TunnelSetupRequest.builder();
bld.setApnName(apnName)
- .setNetwork(mMockNetwork)
.setIsRoaming(false /*isRoaming*/)
.setIsEmergency(false /*IsEmergency*/)
.setRequestPcscf(false /*requestPcscf*/)
@@ -1171,14 +1114,13 @@ public class EpdgTunnelManagerTest {
0);
int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
- mEpdgTunnelManager.setHasConnectedToEpdg(true);
+ mEpdgTunnelManager.onConnectedToEpdg(true);
mEpdgTunnelManager.setEpdgAddress(InetAddresses.parseNumericAddress(EPDG_ADDRESS));
mEpdgTunnelManager.getTmIkeSessionCallback(testApnName, token).onClosed();
mTestLooper.dispatchAll();
verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
- verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
}
@@ -1206,13 +1148,12 @@ public class EpdgTunnelManagerTest {
EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
mTestLooper.dispatchAll();
- mEpdgTunnelManager.setHasConnectedToEpdg(false);
+ mEpdgTunnelManager.onConnectedToEpdg(false);
mEpdgTunnelManager.getTmIkeSessionCallback(testApnName, DEFAULT_TOKEN).onClosed();
mTestLooper.dispatchAll();
verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
- verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
}
@@ -1224,9 +1165,8 @@ public class EpdgTunnelManagerTest {
mMockIwlanTunnelMetrics,
null,
0);
- setVariable(mEpdgTunnelManager, "mLocalAddresses", EXPECTED_LOCAL_ADDRESSES);
mEpdgTunnelManager.validateAndSetEpdgAddress(EXPECTED_EPDG_ADDRESSES);
- mEpdgTunnelManager.setHasConnectedToEpdg(true);
+ mEpdgTunnelManager.onConnectedToEpdg(true);
}
private IkeSessionArgumentCaptors verifyBringUpTunnelWithDnsQuery(String apnName) {
@@ -1303,7 +1243,9 @@ public class EpdgTunnelManagerTest {
return ikeSessionArgumentCaptors;
}
- private void verifyTunnelOnOpened(String apnName, ChildSessionCallback childSessionCallback) {
+ private void verifyTunnelOnOpened(String apnName, ChildSessionCallback childSessionCallback)
+ throws Exception {
+ clearInvocations(mMockIpSecManager);
doReturn(0L)
.when(mEpdgTunnelManager)
.reportIwlanError(eq(apnName), eq(new IwlanError(IwlanError.NO_ERROR)));
@@ -1318,9 +1260,12 @@ public class EpdgTunnelManagerTest {
childSessionCallback.onIpSecTransformCreated(
mMockedIpSecTransformOut, IpSecManager.DIRECTION_OUT);
mTestLooper.dispatchAll();
+ verify(mMockIpSecManager, times(1))
+ .createIpSecTunnelInterface(
+ any(InetAddress.class), any(InetAddress.class), eq(mMockDefaultNetwork));
+
childSessionCallback.onOpened(mMockChildSessionConfiguration);
mTestLooper.dispatchAll();
-
verify(mEpdgTunnelManager, times(1))
.reportIwlanError(eq(apnName), eq(new IwlanError(IwlanError.NO_ERROR)));
verify(mMockIwlanTunnelCallback, times(1)).onOpened(eq(apnName), any());
@@ -1333,6 +1278,12 @@ public class EpdgTunnelManagerTest {
setOneTunnelOpened(openedApnName);
+ // FIXME: Since the network from bringUpTunnel() will only be stored for the first request,
+ // and we are skipping the first tunnel setup procedure in this test case, it is necessary
+ // to set the network instance directly.
+ mEpdgTunnelManager.updateNetwork(mMockDefaultNetwork, mMockLinkProperties);
+ mTestLooper.dispatchAll();
+
IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
verifyBringUpTunnel(toBeOpenedApnName, false /* needPendingBringUpReq */);
ChildSessionCallback childSessionCallback =
@@ -1375,7 +1326,7 @@ public class EpdgTunnelManagerTest {
0);
int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
- mEpdgTunnelManager.setHasConnectedToEpdg(true);
+ mEpdgTunnelManager.onConnectedToEpdg(true);
mEpdgTunnelManager.setEpdgAddress(InetAddresses.parseNumericAddress(EPDG_ADDRESS));
mEpdgTunnelManager
@@ -1384,7 +1335,6 @@ public class EpdgTunnelManagerTest {
mTestLooper.dispatchAll();
verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
- verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
}
@@ -1411,7 +1361,7 @@ public class EpdgTunnelManagerTest {
EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
mTestLooper.dispatchAll();
- mEpdgTunnelManager.setHasConnectedToEpdg(false);
+ mEpdgTunnelManager.onConnectedToEpdg(false);
mEpdgTunnelManager
.getTmIkeSessionCallback(testApnName, DEFAULT_TOKEN)
@@ -1419,7 +1369,6 @@ public class EpdgTunnelManagerTest {
mTestLooper.dispatchAll();
verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), any(IwlanError.class));
- verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
}
@@ -1485,7 +1434,7 @@ public class EpdgTunnelManagerTest {
.onIkeSessionConnectionInfoChanged(mMockIkeSessionConnectionInfo);
mTestLooper.dispatchAll();
- verify(mMockIpSecTunnelInterface, times(1)).setUnderlyingNetwork(mMockNetwork);
+ verify(mMockIpSecTunnelInterface, times(1)).setUnderlyingNetwork(mMockDefaultNetwork);
}
@Test
@@ -1545,16 +1494,6 @@ public class EpdgTunnelManagerTest {
PersistableBundle bundle = new PersistableBundle();
setupMockForGetConfig(bundle);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
-
doReturn(null)
.when(mMockIkeSessionCreator)
.createIkeSession(
@@ -1687,7 +1626,7 @@ public class EpdgTunnelManagerTest {
0);
int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
- mEpdgTunnelManager.setHasConnectedToEpdg(true);
+ mEpdgTunnelManager.onConnectedToEpdg(true);
mEpdgTunnelManager.setEpdgAddress(InetAddresses.parseNumericAddress(EPDG_ADDRESS));
mEpdgTunnelManager
@@ -1696,7 +1635,6 @@ public class EpdgTunnelManagerTest {
mTestLooper.dispatchAll();
verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
- verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
}
@@ -1722,7 +1660,7 @@ public class EpdgTunnelManagerTest {
mEpdgTunnelManager.sendSelectionRequestComplete(null, error, 1);
mTestLooper.dispatchAll();
- mEpdgTunnelManager.setHasConnectedToEpdg(false);
+ mEpdgTunnelManager.onConnectedToEpdg(false);
verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
}
@@ -1779,16 +1717,6 @@ public class EpdgTunnelManagerTest {
PersistableBundle bundle = new PersistableBundle();
setupMockForGetConfig(bundle);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
-
doReturn(null)
.when(mMockIkeSessionCreator)
.createIkeSession(
@@ -1851,15 +1779,6 @@ public class EpdgTunnelManagerTest {
bundle.putInt(CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT, nattTimer);
setupMockForGetConfig(bundle);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(false),
- eq(false),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
doReturn(null)
.when(mMockIkeSessionCreator)
@@ -1914,7 +1833,6 @@ public class EpdgTunnelManagerTest {
TunnelSetupRequest tsr =
TunnelSetupRequest.builder()
.setApnName(testApnName)
- .setNetwork(mMockNetwork)
.setApnIpProtocol(ApnSetting.PROTOCOL_IPV4V6)
.setSrcIpv6Address(testAddressV6)
.setSrcIpv6AddressPrefixLength(ipv6AddressLen)
@@ -1926,15 +1844,6 @@ public class EpdgTunnelManagerTest {
.build();
setupMockForGetConfig(null);
- when(mMockEpdgSelector.getValidatedServerList(
- anyInt(),
- anyInt(),
- anyInt(),
- eq(isRoaming),
- eq(isEmergency),
- eq(mMockNetwork),
- any(EpdgSelector.EpdgSelectorCallback.class)))
- .thenReturn(new IwlanError(IwlanError.NO_ERROR));
doReturn(null)
.when(mMockIkeSessionCreator)
@@ -1961,7 +1870,7 @@ public class EpdgTunnelManagerTest {
anyInt(),
eq(isRoaming),
eq(isEmergency),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any(EpdgSelector.EpdgSelectorCallback.class));
mEpdgTunnelManager.sendSelectionRequestComplete(
@@ -1991,7 +1900,7 @@ public class EpdgTunnelManagerTest {
assertEquals(ikeId.fqdn, testApnName);
// verify Network
- assertEquals(ikeSessionParams.getNetwork(), mMockNetwork);
+ assertEquals(ikeSessionParams.getNetwork(), mMockDefaultNetwork);
// verify requestPcscf (true) with Apn protocol IPV6
// it should add the pcscf config requests of type ConfigRequestIpv6PcscfServer and
@@ -2132,8 +2041,8 @@ public class EpdgTunnelManagerTest {
int transactionId = 0;
// testApnName with token 0
- setupTunnelBringup(TEST_APN_NAME, ++transactionId);
- mEpdgTunnelManager.setHasConnectedToEpdg(true);
+ setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, ++transactionId);
+ mEpdgTunnelManager.onConnectedToEpdg(true);
IwlanError error = new IwlanError(mMockIkeException);
doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(TEST_APN_NAME), eq(error));
@@ -2146,8 +2055,8 @@ public class EpdgTunnelManagerTest {
assertNull(mEpdgTunnelManager.getTunnelConfigForApn(TEST_APN_NAME));
// testApnName1 with token 1
- setupTunnelBringup(TEST_APN_NAME, ++transactionId);
- mEpdgTunnelManager.setHasConnectedToEpdg(true);
+ setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, ++transactionId);
+ mEpdgTunnelManager.onConnectedToEpdg(true);
// signal from obsolete callback (token 0), ignore it
reset(mMockIwlanTunnelCallback);
@@ -2191,7 +2100,7 @@ public class EpdgTunnelManagerTest {
eq(EpdgSelector.IPV4_PREFERRED),
eq(false),
eq(false),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any());
}
@@ -2219,7 +2128,7 @@ public class EpdgTunnelManagerTest {
eq(EpdgSelector.IPV6_PREFERRED),
eq(false),
eq(false),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any());
}
@@ -2247,7 +2156,7 @@ public class EpdgTunnelManagerTest {
eq(EpdgSelector.SYSTEM_PREFERRED),
eq(false),
eq(false),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any());
}
@@ -2279,7 +2188,7 @@ public class EpdgTunnelManagerTest {
eq(EpdgSelector.SYSTEM_PREFERRED),
eq(false),
eq(false),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any());
}
@@ -2310,7 +2219,7 @@ public class EpdgTunnelManagerTest {
anyInt(),
eq(false),
eq(false),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any());
verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(TEST_APN_NAME), eq(error));
verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(TEST_APN_NAME), eq(error));
@@ -2340,12 +2249,12 @@ public class EpdgTunnelManagerTest {
eq(EpdgSelector.SYSTEM_PREFERRED),
eq(false),
eq(false),
- eq(mMockNetwork),
+ eq(mMockDefaultNetwork),
any());
}
@Test
- public void testOnOpenedTunnelMetricsData() {
+ public void testOnOpenedTunnelMetricsData() throws Exception {
doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME));
mEpdgTunnelManager.bringUpTunnel(
getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
@@ -2370,7 +2279,7 @@ public class EpdgTunnelManagerTest {
IwlanError error = new IwlanError(IwlanError.IKE_INIT_TIMEOUT, mMockIkeIoException);
doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
- setupTunnelBringup(testApnName, 1);
+ setupTunnelBringup();
ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
@@ -2392,42 +2301,34 @@ public class EpdgTunnelManagerTest {
@Test
public void testCloseTunnelWithIkeDpdTimeout() throws Exception {
IwlanError error = new IwlanError(IwlanError.IKE_DPD_TIMEOUT, mMockIkeIoException);
- doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(TEST_APN_NAME), eq(error));
IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME);
ChildSessionCallback childSessionCallback =
ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
- setOneTunnelOpened(TEST_APN_NAME);
mEpdgTunnelManager
.getTmIkeSessionCallback(
TEST_APN_NAME, mEpdgTunnelManager.getCurrentTokenForApn(TEST_APN_NAME))
.onClosedWithException(mMockIkeIoException);
mTestLooper.dispatchAll();
- verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(TEST_APN_NAME), eq(error));
- verify(mMockIwlanTunnelCallback, atLeastOnce()).onClosed(eq(TEST_APN_NAME), eq(error));
+ verify(mEpdgTunnelManager, never()).reportIwlanError(eq(TEST_APN_NAME), eq(error));
+ verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(TEST_APN_NAME), eq(error));
}
@Test
public void testCloseTunnelWithIkeMobilityTimeout() throws Exception {
IwlanError error = new IwlanError(IwlanError.IKE_MOBILITY_TIMEOUT, mMockIkeIoException);
- doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(TEST_APN_NAME), eq(error));
IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
- verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME);
+ verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME, mMockIkeSession);
ChildSessionCallback childSessionCallback =
ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
- setOneTunnelOpened(TEST_APN_NAME);
-
- mEpdgTunnelManager.updateNetwork(mMockNetwork, TEST_APN_NAME);
- mTestLooper.dispatchAll();
- EpdgTunnelManager.TunnelConfig testApnTunnelConfig =
- mEpdgTunnelManager.getTunnelConfigForApn(TEST_APN_NAME);
- testApnTunnelConfig.getIkeSession().setNetwork(mMockNetwork);
+ Network newNetwork = mock(Network.class);
+ mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
mTestLooper.dispatchAll();
mEpdgTunnelManager
@@ -2436,7 +2337,143 @@ public class EpdgTunnelManagerTest {
.onClosedWithException(mMockIkeIoException);
mTestLooper.dispatchAll();
- verify(mEpdgTunnelManager, atLeastOnce()).reportIwlanError(eq(TEST_APN_NAME), eq(error));
- verify(mMockIwlanTunnelCallback, atLeastOnce()).onClosed(eq(TEST_APN_NAME), eq(error));
+ verify(mMockIkeSession, times(1)).setNetwork(eq(newNetwork));
+ verify(mEpdgTunnelManager, never()).reportIwlanError(eq(TEST_APN_NAME), eq(error));
+ verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(TEST_APN_NAME), eq(error));
+ }
+
+ private boolean testIsN1ModeSupported(int[] nrAvailability) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putIntArray(
+ CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, nrAvailability);
+
+ setupMockForGetConfig(bundle);
+
+ return mEpdgTunnelManager.isN1ModeSupported();
+ }
+
+ @Test
+ public void testIsN1ModeSupportedTrue() throws Exception {
+ assertTrue(
+ testIsN1ModeSupported(
+ new int[] {
+ CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA,
+ CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA
+ }));
+ }
+
+ @Test
+ public void testIsN1ModeSupportedFalse() throws Exception {
+ assertFalse(
+ testIsN1ModeSupported(
+ new int[] {CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA}));
+ }
+
+ @Test
+ public void testUpdateNetworkToOpenedTunnel() throws Exception {
+ String apnName = "ims";
+
+ IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
+ verifyBringUpTunnelWithDnsQuery(apnName, mMockIkeSession);
+ ChildSessionCallback childSessionCallback =
+ ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
+ childSessionCallback.onIpSecTransformCreated(
+ mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
+ mTestLooper.dispatchAll();
+
+ mEpdgTunnelManager.onConnectedToEpdg(true);
+ Network newNetwork = mock(Network.class);
+ mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
+ mTestLooper.dispatchAll();
+ verify(mMockIkeSession, times(1)).setNetwork(eq(newNetwork));
+ }
+
+ @Test
+ public void testUpdateNetworkForIncomingSetupRequest() throws Exception {
+ String apnName = "ims";
+ Network newNetwork = mock(Network.class);
+
+ mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
+ mTestLooper.dispatchAll();
+
+ IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
+ verifyBringUpTunnelWithDnsQuery(apnName, mMockIkeSession);
+ ChildSessionCallback childSessionCallback =
+ ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
+ childSessionCallback.onIpSecTransformCreated(
+ mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
+ mTestLooper.dispatchAll();
+
+ verify(mMockEpdgSelector, times(1))
+ .getValidatedServerList(
+ anyInt(), /* transactionId */
+ anyInt(), /* filter */
+ anyInt(), /* order */
+ eq(false), /* isRoaming */
+ eq(false), /* isEmergency */
+ eq(newNetwork),
+ any(EpdgSelector.EpdgSelectorCallback.class));
+ IkeSessionParams ikeSessionParams =
+ ikeSessionArgumentCaptors.mIkeSessionParamsCaptor.getValue();
+ assertEquals(ikeSessionParams.getNetwork(), newNetwork);
+ }
+
+ @Test
+ public void testUpdateNullNetworkToOpenedTunnel() throws Exception {
+ String apnName = "ims";
+
+ IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
+ verifyBringUpTunnelWithDnsQuery(apnName, mMockIkeSession);
+ ChildSessionCallback childSessionCallback =
+ ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
+ childSessionCallback.onIpSecTransformCreated(
+ mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
+ mTestLooper.dispatchAll();
+
+ mEpdgTunnelManager.updateNetwork(null, null);
+ mTestLooper.dispatchAll();
+ verify(mMockIkeSession, never()).setNetwork(any());
+ }
+
+ @Test
+ public void testUpdateNullNetworkAndRejectIncomingSetupRequest() throws Exception {
+ String apnName = "ims";
+
+ doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(apnName), any(IwlanError.class));
+
+ mEpdgTunnelManager.updateNetwork(null, null);
+ mTestLooper.dispatchAll();
+
+ mEpdgTunnelManager.bringUpTunnel(
+ getBasicTunnelSetupRequest(apnName, ApnSetting.PROTOCOL_IP),
+ mMockIwlanTunnelCallback,
+ mMockIwlanTunnelMetrics);
+ mTestLooper.dispatchAll();
+ verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(apnName), any(IwlanError.class));
+ }
+
+ @Test
+ public void testUpdateUnreachableLinkProperties() throws Exception {
+ String apnName = "ims";
+
+ IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
+ verifyBringUpTunnelWithDnsQuery(apnName, mMockIkeSession);
+ ChildSessionCallback childSessionCallback =
+ ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
+ childSessionCallback.onIpSecTransformCreated(
+ mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
+ mTestLooper.dispatchAll();
+
+ mEpdgTunnelManager.onConnectedToEpdg(true);
+ Network newNetwork = mock(Network.class);
+ LinkProperties mockUnreachableLinkProperties = mock(LinkProperties.class);
+ when(mockUnreachableLinkProperties.isReachable(any())).thenReturn(false);
+ mEpdgTunnelManager.updateNetwork(newNetwork, mockUnreachableLinkProperties);
+ mTestLooper.dispatchAll();
+ verify(mMockIkeSession, never()).setNetwork(eq(newNetwork));
+
+ mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
+ mTestLooper.dispatchAll();
+ verify(mMockIkeSession, times(1)).setNetwork(eq(newNetwork));
}
}