1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.iwlan.epdg;
18 
19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
20 
21 import static com.google.android.iwlan.epdg.EpdgTunnelManager.BRINGDOWN_REASON_UNKNOWN;
22 import static com.google.android.iwlan.proto.MetricsAtom.*;
23 
24 import static org.junit.Assert.assertArrayEquals;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertNotSame;
29 import static org.junit.Assert.assertNull;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.Mockito.any;
32 import static org.mockito.Mockito.anyBoolean;
33 import static org.mockito.Mockito.anyInt;
34 import static org.mockito.Mockito.anyLong;
35 import static org.mockito.Mockito.atLeastOnce;
36 import static org.mockito.Mockito.clearInvocations;
37 import static org.mockito.Mockito.doReturn;
38 import static org.mockito.Mockito.doThrow;
39 import static org.mockito.Mockito.eq;
40 import static org.mockito.Mockito.mock;
41 import static org.mockito.Mockito.never;
42 import static org.mockito.Mockito.reset;
43 import static org.mockito.Mockito.spy;
44 import static org.mockito.Mockito.times;
45 import static org.mockito.Mockito.verify;
46 import static org.mockito.Mockito.when;
47 
48 import android.content.Context;
49 import android.net.ConnectivityDiagnosticsManager;
50 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
51 import android.net.ConnectivityManager;
52 import android.net.InetAddresses;
53 import android.net.IpSecManager;
54 import android.net.IpSecTransform;
55 import android.net.LinkAddress;
56 import android.net.LinkProperties;
57 import android.net.Network;
58 import android.net.NetworkCapabilities;
59 import android.net.ipsec.ike.ChildSessionCallback;
60 import android.net.ipsec.ike.ChildSessionConfiguration;
61 import android.net.ipsec.ike.ChildSessionParams;
62 import android.net.ipsec.ike.IkeFqdnIdentification;
63 import android.net.ipsec.ike.IkeSession;
64 import android.net.ipsec.ike.IkeSessionCallback;
65 import android.net.ipsec.ike.IkeSessionConfiguration;
66 import android.net.ipsec.ike.IkeSessionConnectionInfo;
67 import android.net.ipsec.ike.IkeSessionParams;
68 import android.net.ipsec.ike.SaProposal;
69 import android.net.ipsec.ike.TunnelModeChildSessionParams;
70 import android.net.ipsec.ike.exceptions.IkeException;
71 import android.net.ipsec.ike.exceptions.IkeIOException;
72 import android.net.ipsec.ike.exceptions.IkeInternalException;
73 import android.net.ipsec.ike.exceptions.IkeNetworkLostException;
74 import android.net.ipsec.ike.exceptions.IkeProtocolException;
75 import android.net.ipsec.ike.ike3gpp.Ike3gppBackoffTimer;
76 import android.net.ipsec.ike.ike3gpp.Ike3gppData;
77 import android.net.ipsec.ike.ike3gpp.Ike3gppExtension;
78 import android.os.PersistableBundle;
79 import android.os.test.TestLooper;
80 import android.telephony.CarrierConfigManager;
81 import android.telephony.PreciseDataConnectionState;
82 import android.telephony.SubscriptionInfo;
83 import android.telephony.SubscriptionManager;
84 import android.telephony.TelephonyManager;
85 import android.telephony.data.ApnSetting;
86 import android.util.Pair;
87 
88 import com.google.android.iwlan.ErrorPolicyManager;
89 import com.google.android.iwlan.IwlanCarrierConfig;
90 import com.google.android.iwlan.IwlanError;
91 import com.google.android.iwlan.IwlanHelper;
92 import com.google.android.iwlan.IwlanStatsLog;
93 import com.google.android.iwlan.TunnelMetricsInterface.OnClosedMetrics;
94 import com.google.android.iwlan.TunnelMetricsInterface.OnOpenedMetrics;
95 import com.google.android.iwlan.flags.FeatureFlags;
96 import com.google.android.iwlan.proto.MetricsAtom;
97 
98 import org.junit.After;
99 import org.junit.Before;
100 import org.junit.Test;
101 import org.junit.runner.RunWith;
102 import org.junit.runners.JUnit4;
103 import org.mockito.ArgumentCaptor;
104 import org.mockito.Mock;
105 import org.mockito.MockitoAnnotations;
106 import org.mockito.MockitoSession;
107 import org.mockito.quality.Strictness;
108 
109 import java.io.IOException;
110 import java.net.Inet4Address;
111 import java.net.Inet6Address;
112 import java.net.InetAddress;
113 import java.util.ArrayList;
114 import java.util.List;
115 import java.util.concurrent.Executor;
116 
117 @RunWith(JUnit4.class)
118 public class EpdgTunnelManagerTest {
119     public static final int DEFAULT_SLOT_INDEX = 0;
120     public static final int DEFAULT_SUB_ID = 0;
121     public static final int DEFAULT_TOKEN = 0;
122 
123     private static final String EPDG_ADDRESS = "127.0.0.1";
124     private static final String SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY = "127.0.0.2";
125     private static final String EPDG_ADDRESS_IPV6 = "2600:387:f:707::1";
126     private static final String TEST_APN_NAME = "www.xyz.com";
127 
128     private static final List<InetAddress> EXPECTED_LOCAL_ADDRESSES =
129             List.of(InetAddresses.parseNumericAddress("201.1.100.10"));
130     private static final List<InetAddress> EXPECTED_IPV6_LOCAL_ADDRESSES =
131             List.of(InetAddresses.parseNumericAddress("2001:db8::1:2"));
132     private static final List<InetAddress> EXPECTED_EPDG_ADDRESSES =
133             List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS));
134     private static final List<InetAddress> EXPECTE_EPDG_ADDRESSES_FOR_EMERGENCY_SESSION =
135             List.of(
136                     InetAddresses.parseNumericAddress(EPDG_ADDRESS),
137                     InetAddresses.parseNumericAddress(SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY));
138     private static final List<InetAddress> EXPECTED_EPDG_ADDRESSES_IPV6 =
139             List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS_IPV6));
140     private static final List<LinkAddress> EXPECTED_INTERNAL_ADDRESSES =
141             List.of(new LinkAddress(InetAddresses.parseNumericAddress("198.50.100.10"), 24));
142     private static final List<InetAddress> EXPECTED_PCSCF_ADDRESSES =
143             List.of(InetAddresses.parseNumericAddress("198.51.100.10"));
144     private static final List<InetAddress> EXPECTED_DNS_ADDRESSES =
145             List.of(InetAddresses.parseNumericAddress("198.50.100.10"));
146 
147     private EpdgTunnelManager mEpdgTunnelManager;
148 
149     private static class IwlanTunnelCallback implements EpdgTunnelManager.TunnelCallback {
onOpened( String apnName, TunnelLinkProperties linkProperties, OnOpenedMetrics onOpenedMetrics)150         public void onOpened(
151                 String apnName,
152                 TunnelLinkProperties linkProperties,
153                 OnOpenedMetrics onOpenedMetrics) {}
154 
onClosed(String apnName, IwlanError error, OnClosedMetrics onClosedMetrics)155         public void onClosed(String apnName, IwlanError error, OnClosedMetrics onClosedMetrics) {}
156 
onNetworkValidationStatusChanged(String apnName, int status)157         public void onNetworkValidationStatusChanged(String apnName, int status) {}
158     }
159 
160     private final TestLooper mTestLooper = new TestLooper();
161 
162     @Mock private Context mMockContext;
163     @Mock private Network mMockDefaultNetwork;
164     @Mock private IwlanTunnelCallback mMockIwlanTunnelCallback;
165     @Mock private IkeSession mMockIkeSession;
166     @Mock private EpdgSelector mMockEpdgSelector;
167     @Mock private ErrorPolicyManager mMockErrorPolicyManager;
168     @Mock private FeatureFlags mFakeFeatureFlags;
169     @Mock ConnectivityManager mMockConnectivityManager;
170     @Mock ConnectivityDiagnosticsManager mMockConnectivityDiagnosticsManager;
171     @Mock SubscriptionManager mMockSubscriptionManager;
172     @Mock SubscriptionInfo mMockSubscriptionInfo;
173     @Mock TelephonyManager mMockTelephonyManager;
174     @Mock IpSecManager mMockIpSecManager;
175     @Mock EpdgTunnelManager.IkeSessionCreator mMockIkeSessionCreator;
176     @Mock IkeException mMockIkeException;
177     @Mock IkeIOException mMockIkeIoException;
178     @Mock IkeSessionConfiguration mMockIkeSessionConfiguration;
179     @Mock ChildSessionConfiguration mMockChildSessionConfiguration;
180     @Mock IpSecManager.IpSecTunnelInterface mMockIpSecTunnelInterface;
181     @Mock IkeSessionConnectionInfo mMockIkeSessionConnectionInfo;
182     @Mock IpSecTransform mMockedIpSecTransformIn;
183     @Mock IpSecTransform mMockedIpSecTransformOut;
184     @Mock LinkProperties mMockLinkProperties;
185     @Mock NetworkCapabilities mMockNetworkCapabilities;
186     private MockitoSession mMockitoSession;
187     private long mMockedClockTime = 0;
188     private final ArgumentCaptor<ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback>
189             mConnectivityDiagnosticsCallbackArgumentCaptor =
190                     ArgumentCaptor.forClass(
191                             ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback.class);
192 
193     static class IkeSessionArgumentCaptors {
194         ArgumentCaptor<IkeSessionParams> mIkeSessionParamsCaptor =
195                 ArgumentCaptor.forClass(IkeSessionParams.class);
196         ArgumentCaptor<ChildSessionParams> mChildSessionParamsCaptor =
197                 ArgumentCaptor.forClass(ChildSessionParams.class);
198         ArgumentCaptor<IkeSessionCallback> mIkeSessionCallbackCaptor =
199                 ArgumentCaptor.forClass(IkeSessionCallback.class);
200         ArgumentCaptor<ChildSessionCallback> mChildSessionCallbackCaptor =
201                 ArgumentCaptor.forClass(ChildSessionCallback.class);
202     }
203 
204     @Before
setUp()205     public void setUp() throws Exception {
206         // TODO: replace with ExtendedMockitoRule?
207         MockitoAnnotations.initMocks(this);
208         mMockitoSession =
209                 mockitoSession()
210                         .mockStatic(EpdgSelector.class)
211                         .mockStatic(ErrorPolicyManager.class)
212                         .mockStatic(IwlanStatsLog.class)
213                         .spyStatic(IwlanHelper.class)
214                         .strictness(Strictness.LENIENT)
215                         .startMocking();
216         mMockedClockTime = 0;
217         when(IwlanHelper.elapsedRealtime()).thenAnswer(i -> mMockedClockTime);
218 
219         EpdgTunnelManager.resetAllInstances();
220         ErrorPolicyManager.resetAllInstances();
221         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
222                 .thenReturn(mMockErrorPolicyManager);
223         when(mMockContext.getSystemService(eq(ConnectivityManager.class)))
224                 .thenReturn(mMockConnectivityManager);
225         when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
226                 .thenReturn(mMockSubscriptionManager);
227         when(mMockContext.getSystemService(eq(TelephonyManager.class)))
228                 .thenReturn(mMockTelephonyManager);
229         when(mMockContext.getSystemService(eq(ConnectivityDiagnosticsManager.class)))
230                 .thenReturn(mMockConnectivityDiagnosticsManager);
231         when(mMockTelephonyManager.createForSubscriptionId(DEFAULT_SUB_ID))
232                 .thenReturn(mMockTelephonyManager);
233         when(mMockTelephonyManager.getSimCarrierId()).thenReturn(0);
234         when(mMockContext.getSystemService(eq(IpSecManager.class))).thenReturn(mMockIpSecManager);
235         when(mFakeFeatureFlags.epdgSelectionExcludeFailedIpAddress()).thenReturn(false);
236         when(mMockConnectivityManager.getNetworkCapabilities(any(Network.class)))
237                 .thenReturn(mMockNetworkCapabilities);
238         when(mMockNetworkCapabilities.hasCapability(anyInt())).thenReturn(false);
239 
240         mEpdgTunnelManager =
241                 spy(
242                         new EpdgTunnelManager(
243                                 mMockContext,
244                                 DEFAULT_SLOT_INDEX,
245                                 mFakeFeatureFlags,
246                                 mMockIkeSessionCreator,
247                                 mMockEpdgSelector));
248         verify(mMockConnectivityDiagnosticsManager)
249                 .registerConnectivityDiagnosticsCallback(
250                         any(), any(), mConnectivityDiagnosticsCallbackArgumentCaptor.capture());
251         doReturn(mTestLooper.getLooper()).when(mEpdgTunnelManager).getLooper();
252         mEpdgTunnelManager.initHandler();
253 
254         when(mMockEpdgSelector.getValidatedServerList(
255                         anyInt(),
256                         anyInt(),
257                         anyInt(),
258                         anyBoolean(),
259                         anyBoolean(),
260                         any(Network.class),
261                         any(EpdgSelector.EpdgSelectorCallback.class)))
262                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
263 
264         when(mMockIkeSessionConfiguration.getPcscfServers()).thenReturn(EXPECTED_PCSCF_ADDRESSES);
265 
266         when(mMockChildSessionConfiguration.getInternalDnsServers())
267                 .thenReturn(EXPECTED_DNS_ADDRESSES);
268         when(mMockChildSessionConfiguration.getInternalAddresses())
269                 .thenReturn(EXPECTED_INTERNAL_ADDRESSES);
270 
271         when(mMockIpSecManager.createIpSecTunnelInterface(
272                         any(InetAddress.class), any(InetAddress.class), any(Network.class)))
273                 .thenReturn(mMockIpSecTunnelInterface);
274         when(mMockIpSecTunnelInterface.getInterfaceName()).thenReturn("ipsec10");
275 
276         when(mMockIkeSessionConnectionInfo.getNetwork()).thenReturn(mMockDefaultNetwork);
277 
278         doReturn(EXPECTED_LOCAL_ADDRESSES).when(mEpdgTunnelManager).getAddressForNetwork(any());
279 
280         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(DEFAULT_SLOT_INDEX))
281                 .thenReturn(mMockSubscriptionInfo);
282         when(mMockSubscriptionInfo.getSubscriptionId()).thenReturn(DEFAULT_SUB_ID);
283         when(mMockSubscriptionInfo.getMncString()).thenReturn("344");
284 
285         when(mMockLinkProperties.isReachable(any())).thenReturn(true);
286         mEpdgTunnelManager.updateNetwork(mMockDefaultNetwork, mMockLinkProperties);
287         mTestLooper.dispatchAll();
288     }
289 
290     @After
cleanUp()291     public void cleanUp() {
292         IwlanCarrierConfig.resetTestConfig();
293         mMockitoSession.finishMocking();
294     }
295 
296     @Test
testBringUpTunnelWithInvalidProtocol()297     public void testBringUpTunnelWithInvalidProtocol() {
298         boolean ret =
299                 mEpdgTunnelManager.bringUpTunnel(
300                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_PPP),
301                         mMockIwlanTunnelCallback);
302         assertFalse(ret);
303     }
304 
305     @Test
testBringUpTunnelWithInvalidPduSessionId()306     public void testBringUpTunnelWithInvalidPduSessionId() {
307         boolean ret =
308                 mEpdgTunnelManager.bringUpTunnel(
309                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6, 16),
310                         mMockIwlanTunnelCallback);
311         assertFalse(ret);
312 
313         ret =
314                 mEpdgTunnelManager.bringUpTunnel(
315                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6, -1),
316                         mMockIwlanTunnelCallback);
317         assertFalse(ret);
318     }
319 
320     @Test
testBringUpTunnelWithValidProtocols()321     public void testBringUpTunnelWithValidProtocols() {
322         String testApnName1 = "www.xyz.com1";
323         String testApnName2 = "www.xyz.com2";
324         String testApnName3 = "www.xyz.com3";
325 
326         TunnelSetupRequest TSR_v4 =
327                 getBasicTunnelSetupRequest(testApnName1, ApnSetting.PROTOCOL_IP);
328 
329         TunnelSetupRequest TSR_v6 =
330                 getBasicTunnelSetupRequest(testApnName2, ApnSetting.PROTOCOL_IPV6);
331 
332         TunnelSetupRequest TSR_v4v6 =
333                 getBasicTunnelSetupRequest(testApnName3, ApnSetting.PROTOCOL_IPV4V6);
334 
335         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR_v4, mMockIwlanTunnelCallback);
336         assertTrue(ret);
337 
338         ret = mEpdgTunnelManager.bringUpTunnel(TSR_v6, mMockIwlanTunnelCallback);
339         assertTrue(ret);
340 
341         ret = mEpdgTunnelManager.bringUpTunnel(TSR_v4v6, mMockIwlanTunnelCallback);
342         assertTrue(ret);
343     }
344 
345     @Test
testBringUpTunnelWithNullApn()346     public void testBringUpTunnelWithNullApn() {
347 
348         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
349 
350         when(mEpdgTunnelManager.getTunnelSetupRequestApnName(TSR)).thenReturn(null);
351 
352         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
353         assertFalse(ret);
354         verify(mEpdgTunnelManager).getTunnelSetupRequestApnName(TSR);
355     }
356 
357     @Test
testBringUpTunnelWithExistApn()358     public void testBringUpTunnelWithExistApn() {
359         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
360 
361         when(mEpdgTunnelManager.isTunnelConfigContainExistApn(TEST_APN_NAME)).thenReturn(true);
362 
363         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
364         assertFalse(ret);
365         verify(mEpdgTunnelManager).isTunnelConfigContainExistApn(TEST_APN_NAME);
366     }
367 
368     @Test
testBringUpTunnelWithNoBringUpInProcess()369     public void testBringUpTunnelWithNoBringUpInProcess() {
370         String testApnName2 = "www.abc.com";
371 
372         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
373 
374         mEpdgTunnelManager.putApnNameToTunnelConfig(
375                 testApnName2,
376                 mMockIkeSession,
377                 mMockIwlanTunnelCallback,
378                 mMockIpSecTunnelInterface,
379                 null /* srcIpv6Addr */,
380                 0 /* srcIPv6AddrPrefixLen */,
381                 false /* isEmergency */,
382                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
383 
384         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
385         assertTrue(ret);
386     }
387 
388     @Test
testBringUpTunnelSuccess()389     public void testBringUpTunnelSuccess() throws Exception {
390 
391         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
392 
393         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
394         assertTrue(ret);
395         mTestLooper.dispatchAll();
396 
397         verify(mMockEpdgSelector)
398                 .getValidatedServerList(
399                         anyInt(),
400                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
401                         anyInt(),
402                         eq(false),
403                         eq(false),
404                         eq(mMockDefaultNetwork),
405                         any());
406     }
407 
advanceClockByTimeMs(long time)408     private void advanceClockByTimeMs(long time) {
409         mMockedClockTime += time;
410         mTestLooper.dispatchAll();
411     }
412 
setupTunnelBringup( String apnName, List<InetAddress> epdgAddresses, int transactionId)413     private void setupTunnelBringup(
414             String apnName, List<InetAddress> epdgAddresses, int transactionId) throws Exception {
415         doReturn(null)
416                 .when(mMockIkeSessionCreator)
417                 .createIkeSession(
418                         eq(mMockContext),
419                         any(IkeSessionParams.class),
420                         any(ChildSessionParams.class),
421                         any(Executor.class),
422                         any(IkeSessionCallback.class),
423                         any(ChildSessionCallback.class));
424 
425         boolean ret =
426                 mEpdgTunnelManager.bringUpTunnel(
427                         getBasicTunnelSetupRequest(apnName, ApnSetting.PROTOCOL_IP),
428                         mMockIwlanTunnelCallback);
429         assertTrue(ret);
430         mTestLooper.dispatchAll();
431 
432         mEpdgTunnelManager.sendSelectionRequestComplete(
433                 epdgAddresses, new IwlanError(IwlanError.NO_ERROR), transactionId);
434         mTestLooper.dispatchAll();
435     }
436 
setupTunnelBringup()437     private void setupTunnelBringup() throws Exception {
438         setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, 1 /* transactionId */);
439     }
440 
441     @Test
testBringUpTunnelSetsDeviceIdentityImeiSv()442     public void testBringUpTunnelSetsDeviceIdentityImeiSv() throws Exception {
443         IwlanCarrierConfig.putTestConfigBoolean(
444                 IwlanCarrierConfig.KEY_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL, true);
445 
446         String TEST_IMEI = "012345678901234";
447         String TEST_IMEI_SUFFIX = "56";
448         String EXPECTED_IMEISV = TEST_IMEI.substring(0, TEST_IMEI.length() - 1) + TEST_IMEI_SUFFIX;
449         when(mMockTelephonyManager.getImei()).thenReturn(TEST_IMEI);
450         when(mMockTelephonyManager.getDeviceSoftwareVersion()).thenReturn(TEST_IMEI_SUFFIX);
451 
452         setupTunnelBringup();
453 
454         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
455                 ArgumentCaptor.forClass(IkeSessionParams.class);
456         verify(mMockIkeSessionCreator, atLeastOnce())
457                 .createIkeSession(
458                         eq(mMockContext),
459                         ikeSessionParamsCaptor.capture(),
460                         any(ChildSessionParams.class),
461                         any(Executor.class),
462                         any(IkeSessionCallback.class),
463                         any(ChildSessionCallback.class));
464         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
465         assertEquals(
466                 EXPECTED_IMEISV,
467                 ikeSessionParams
468                         .getIke3gppExtension()
469                         .getIke3gppParams()
470                         .getMobileDeviceIdentity());
471     }
472 
473     @Test
testBringUpTunnelSetsDeviceIdentityImei()474     public void testBringUpTunnelSetsDeviceIdentityImei() throws Exception {
475         IwlanCarrierConfig.putTestConfigBoolean(
476                 IwlanCarrierConfig.KEY_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL, true);
477 
478         String TEST_IMEI = "012345678901234";
479         when(mMockTelephonyManager.getImei()).thenReturn(TEST_IMEI);
480         when(mMockTelephonyManager.getDeviceSoftwareVersion()).thenReturn(null);
481 
482         setupTunnelBringup();
483 
484         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
485                 ArgumentCaptor.forClass(IkeSessionParams.class);
486         verify(mMockIkeSessionCreator, atLeastOnce())
487                 .createIkeSession(
488                         eq(mMockContext),
489                         ikeSessionParamsCaptor.capture(),
490                         any(ChildSessionParams.class),
491                         any(Executor.class),
492                         any(IkeSessionCallback.class),
493                         any(ChildSessionCallback.class));
494         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
495         assertEquals(
496                 TEST_IMEI,
497                 ikeSessionParams
498                         .getIke3gppExtension()
499                         .getIke3gppParams()
500                         .getMobileDeviceIdentity());
501     }
502 
503     @Test
testBringUpTunnelNoDeviceIdentityWhenImeiUnavailable()504     public void testBringUpTunnelNoDeviceIdentityWhenImeiUnavailable() throws Exception {
505         IwlanCarrierConfig.putTestConfigBoolean(
506                 IwlanCarrierConfig.KEY_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL, true);
507         when(mMockTelephonyManager.getImei()).thenReturn(null);
508 
509         setupTunnelBringup();
510 
511         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
512                 ArgumentCaptor.forClass(IkeSessionParams.class);
513         verify(mMockIkeSessionCreator, atLeastOnce())
514                 .createIkeSession(
515                         eq(mMockContext),
516                         ikeSessionParamsCaptor.capture(),
517                         any(ChildSessionParams.class),
518                         any(Executor.class),
519                         any(IkeSessionCallback.class),
520                         any(ChildSessionCallback.class));
521         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
522         assertNull(
523                 ikeSessionParams
524                         .getIke3gppExtension()
525                         .getIke3gppParams()
526                         .getMobileDeviceIdentity());
527     }
528 
529     @Test
testBringUpTunnelWithMobilityOptions()530     public void testBringUpTunnelWithMobilityOptions() throws Exception {
531         setupTunnelBringup();
532         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
533                 ArgumentCaptor.forClass(IkeSessionParams.class);
534         verify(mMockIkeSessionCreator, atLeastOnce())
535                 .createIkeSession(
536                         eq(mMockContext),
537                         ikeSessionParamsCaptor.capture(),
538                         any(ChildSessionParams.class),
539                         any(Executor.class),
540                         any(IkeSessionCallback.class),
541                         any(ChildSessionCallback.class));
542         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
543         assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE));
544         assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY));
545     }
546 
547     @Test
testBringUpTunnelIpv6_verifyMobikeDisabled()548     public void testBringUpTunnelIpv6_verifyMobikeDisabled() throws Exception {
549         setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES_IPV6, 1);
550         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
551                 ArgumentCaptor.forClass(IkeSessionParams.class);
552         verify(mMockIkeSessionCreator, atLeastOnce())
553                 .createIkeSession(
554                         eq(mMockContext),
555                         ikeSessionParamsCaptor.capture(),
556                         any(ChildSessionParams.class),
557                         any(Executor.class),
558                         any(IkeSessionCallback.class),
559                         any(ChildSessionCallback.class));
560         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
561         assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY));
562         assertFalse(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE));
563     }
564 
565     @Test
testInitialContactForFirstTunnelOnly()566     public void testInitialContactForFirstTunnelOnly() throws Exception {
567         final String firstApnName = "ims";
568         final String secondApnName = "mms";
569 
570         IkeSessionArgumentCaptors firstTunnelArgumentCaptors =
571                 verifyBringUpTunnelWithDnsQuery(firstApnName, mMockDefaultNetwork);
572         ChildSessionCallback firstCallback =
573                 firstTunnelArgumentCaptors.mChildSessionCallbackCaptor.getValue();
574 
575         IkeSessionArgumentCaptors secondTunnelArgumentCaptors =
576                 verifyBringUpTunnel(
577                         secondApnName, mMockDefaultNetwork, true /* needPendingBringUpReq */);
578         verifyTunnelOnOpened(firstApnName, firstCallback);
579 
580         ChildSessionCallback secondCallback =
581                 secondTunnelArgumentCaptors.mChildSessionCallbackCaptor.getValue();
582         verifyTunnelOnOpened(secondApnName, secondCallback);
583 
584         IkeSessionParams firstTunnelParams =
585                 firstTunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
586         IkeSessionParams secondTunnelParams =
587                 secondTunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
588         assertTrue(firstTunnelParams.hasIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT));
589         assertFalse(secondTunnelParams.hasIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT));
590     }
591 
592     @Test
testAeadSaProposals()593     public void testAeadSaProposals() throws Exception {
594         when(mFakeFeatureFlags.aeadAlgosEnabled()).thenReturn(true);
595         final String apnName = "ims";
596         int[] aeadAlgos = {
597             SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
598             SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
599             SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
600         };
601         int[] aeadAlgosKeyLens = {
602             SaProposal.KEY_LEN_AES_128, SaProposal.KEY_LEN_AES_192, SaProposal.KEY_LEN_AES_256,
603         };
604 
605         IwlanCarrierConfig.putTestConfigIntArray(
606                 CarrierConfigManager.Iwlan.KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
607                 aeadAlgos);
608         IwlanCarrierConfig.putTestConfigIntArray(
609                 CarrierConfigManager.Iwlan.KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
610                 aeadAlgosKeyLens);
611         IwlanCarrierConfig.putTestConfigIntArray(
612                 CarrierConfigManager.Iwlan.KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
613                 aeadAlgos);
614         IwlanCarrierConfig.putTestConfigIntArray(
615                 CarrierConfigManager.Iwlan.KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
616                 aeadAlgosKeyLens);
617 
618         IkeSessionArgumentCaptors tunnelArgumentCaptors =
619                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork);
620 
621         IkeSessionParams ikeTunnelParams = tunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
622 
623         List<Pair<Integer, Integer>> ikeEncrAlgos =
624                 ikeTunnelParams.getIkeSaProposals().get(0).getEncryptionAlgorithms();
625 
626         assertTrue(ikeEncrAlgos.contains(new Pair(aeadAlgos[0], aeadAlgosKeyLens[0])));
627         assertEquals(
628                 "IKE AEAD algorithms mismatch",
629                 (long) aeadAlgos.length * aeadAlgosKeyLens.length,
630                 ikeEncrAlgos.size());
631 
632         ChildSessionParams childTunnelParams =
633                 tunnelArgumentCaptors.mChildSessionParamsCaptor.getValue();
634 
635         List<Pair<Integer, Integer>> childEncrAlgos =
636                 childTunnelParams.getChildSaProposals().get(0).getEncryptionAlgorithms();
637 
638         assertTrue(childEncrAlgos.contains(new Pair(aeadAlgos[0], aeadAlgosKeyLens[0])));
639         assertEquals(
640                 "Child AEAD algorithms mismatch",
641                 (long) aeadAlgos.length * aeadAlgosKeyLens.length,
642                 childEncrAlgos.size());
643     }
644 
645     @Test
testMultipleSaProposals()646     public void testMultipleSaProposals() throws Exception {
647         when(mFakeFeatureFlags.aeadAlgosEnabled()).thenReturn(true);
648         when(mFakeFeatureFlags.multipleSaProposals()).thenReturn(true);
649         final String apnName = "ims";
650 
651         int[] aeadAlgos = {
652             SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
653         };
654         int[] aeadAlgosKeyLens = {
655             SaProposal.KEY_LEN_AES_192, SaProposal.KEY_LEN_AES_256,
656         };
657 
658         IwlanCarrierConfig.putTestConfigIntArray(
659                 CarrierConfigManager.Iwlan.KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
660                 aeadAlgos);
661         IwlanCarrierConfig.putTestConfigIntArray(
662                 CarrierConfigManager.Iwlan.KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
663                 aeadAlgosKeyLens);
664         IwlanCarrierConfig.putTestConfigIntArray(
665                 CarrierConfigManager.Iwlan.KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
666                 aeadAlgos);
667         IwlanCarrierConfig.putTestConfigIntArray(
668                 CarrierConfigManager.Iwlan.KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
669                 aeadAlgosKeyLens);
670 
671         IwlanCarrierConfig.putTestConfigBoolean(
672                 CarrierConfigManager.Iwlan.KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
673                 true);
674         IwlanCarrierConfig.putTestConfigBoolean(
675                 CarrierConfigManager.Iwlan.KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
676                 true);
677 
678         IkeSessionArgumentCaptors tunnelArgumentCaptors =
679                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork);
680 
681         IkeSessionParams ikeTunnelParams = tunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
682 
683         assertTrue(ikeTunnelParams.getIkeSaProposals().size() > 1);
684 
685         List<Pair<Integer, Integer>> ikeAeadAlgos =
686                 ikeTunnelParams.getIkeSaProposals().get(0).getEncryptionAlgorithms();
687         assertEquals(
688                 "Reorder higher AEAD in  IKE SA mismatch",
689                 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
690                 (long) ikeAeadAlgos.get(0).first);
691 
692         ChildSessionParams childTunnelParams =
693                 tunnelArgumentCaptors.mChildSessionParamsCaptor.getValue();
694 
695         assertTrue(childTunnelParams.getChildSaProposals().size() > 1);
696 
697         List<Pair<Integer, Integer>> childAeadAlgos =
698                 childTunnelParams.getChildSaProposals().get(0).getEncryptionAlgorithms();
699         assertEquals(
700                 "Reorder higher AEAD in  Child SA mismatch",
701                 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
702                 (long) childAeadAlgos.get(0).first);
703         assertEquals(0, childTunnelParams.getChildSaProposals().get(0).getDhGroups().size());
704     }
705 
706     @Test
testSaProposalsReorder()707     public void testSaProposalsReorder() throws Exception {
708         when(mFakeFeatureFlags.aeadAlgosEnabled()).thenReturn(true);
709         when(mFakeFeatureFlags.multipleSaProposals()).thenReturn(true);
710         when(mFakeFeatureFlags.highSecureTransformsPrioritized()).thenReturn(true);
711 
712         final String apnName = "ims";
713         int[] aeadAlgos = {
714             SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
715         };
716         int[] aeadAlgosKeyLens = {
717             SaProposal.KEY_LEN_AES_128, SaProposal.KEY_LEN_AES_192, SaProposal.KEY_LEN_AES_256,
718         };
719 
720         IwlanCarrierConfig.putTestConfigIntArray(
721                 CarrierConfigManager.Iwlan
722                         .KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY,
723                 aeadAlgos);
724         IwlanCarrierConfig.putTestConfigIntArray(
725                 CarrierConfigManager.Iwlan.KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY,
726                 aeadAlgosKeyLens);
727         IwlanCarrierConfig.putTestConfigIntArray(
728                 CarrierConfigManager.Iwlan
729                         .KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY,
730                 aeadAlgos);
731         IwlanCarrierConfig.putTestConfigIntArray(
732                 CarrierConfigManager.Iwlan.KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY,
733                 aeadAlgosKeyLens);
734 
735         IwlanCarrierConfig.putTestConfigBoolean(
736                 CarrierConfigManager.Iwlan.KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
737                 true);
738         IwlanCarrierConfig.putTestConfigBoolean(
739                 CarrierConfigManager.Iwlan.KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
740                 true);
741         IwlanCarrierConfig.putTestConfigBoolean(
742                 IwlanCarrierConfig.KEY_IKE_SA_TRANSFORMS_REORDER_BOOL, true);
743 
744         IkeSessionArgumentCaptors tunnelArgumentCaptors =
745                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork);
746 
747         IkeSessionParams ikeTunnelParams = tunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
748 
749         assertTrue(ikeTunnelParams.getIkeSaProposals().size() > 1);
750 
751         List<Pair<Integer, Integer>> ikeEncrAlgos =
752                 ikeTunnelParams.getIkeSaProposals().get(0).getEncryptionAlgorithms();
753 
754         assertEquals(
755                 "Reorder bigger key length in IKE SA mismatch",
756                 SaProposal.KEY_LEN_AES_256,
757                 (long) ikeEncrAlgos.get(0).second);
758 
759         List<Pair<Integer, Integer>> ikeAeadAlgos =
760                 ikeTunnelParams.getIkeSaProposals().get(1).getEncryptionAlgorithms();
761         assertEquals(
762                 "Reorder higher AEAD in  IKE SA mismatch",
763                 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
764                 (long) ikeAeadAlgos.get(0).first);
765 
766         ChildSessionParams childTunnelParams =
767                 tunnelArgumentCaptors.mChildSessionParamsCaptor.getValue();
768 
769         assertTrue(childTunnelParams.getChildSaProposals().size() > 1);
770 
771         List<Pair<Integer, Integer>> childEncrAlgos =
772                 childTunnelParams.getChildSaProposals().get(0).getEncryptionAlgorithms();
773 
774         assertEquals(
775                 "Reorder bigger key length in Child SA mismatch",
776                 SaProposal.KEY_LEN_AES_256,
777                 (long) childEncrAlgos.get(0).second);
778 
779         List<Pair<Integer, Integer>> childAeadAlgos =
780                 childTunnelParams.getChildSaProposals().get(1).getEncryptionAlgorithms();
781         assertEquals(
782                 "Reorder higher AEAD in  Child SA mismatch",
783                 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
784                 (long) childAeadAlgos.get(0).first);
785     }
786 
787     @Test
testAddDHGroupForKePayloadInChildSaParamsForRekey()788     public void testAddDHGroupForKePayloadInChildSaParamsForRekey() throws Exception {
789         when(mFakeFeatureFlags.multipleSaProposals()).thenReturn(true);
790         final String apnName = "ims";
791 
792         IwlanCarrierConfig.putTestConfigBoolean(
793                 CarrierConfigManager.Iwlan.KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
794                 true);
795         IwlanCarrierConfig.putTestConfigBoolean(
796                 CarrierConfigManager.Iwlan.KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL, true);
797 
798         IkeSessionArgumentCaptors tunnelArgumentCaptors =
799                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork);
800 
801         ChildSessionParams childTunnelParams =
802                 tunnelArgumentCaptors.mChildSessionParamsCaptor.getValue();
803 
804         assertTrue(childTunnelParams.getChildSaProposals().size() > 0);
805 
806         assertTrue(childTunnelParams.getChildSaProposals().get(0).getDhGroups().size() != 0);
807     }
808 
809     @Test
testCloseTunnelWithNoTunnelForApn()810     public void testCloseTunnelWithNoTunnelForApn() throws Exception {
811         String testApnName = "www.xyz.com";
812         doReturn(0L)
813                 .when(mEpdgTunnelManager)
814                 .reportIwlanError(eq(testApnName), eq(new IwlanError(IwlanError.TUNNEL_NOT_FOUND)));
815 
816         mEpdgTunnelManager.closeTunnel(
817                 testApnName,
818                 false /*forceClose*/,
819                 mMockIwlanTunnelCallback,
820                 BRINGDOWN_REASON_UNKNOWN);
821         mTestLooper.dispatchAll();
822 
823         verify(mEpdgTunnelManager).closePendingRequestsForApn(eq(testApnName));
824         ArgumentCaptor<OnClosedMetrics> metricsCaptor =
825                 ArgumentCaptor.forClass(OnClosedMetrics.class);
826         verify(mMockIwlanTunnelCallback)
827                 .onClosed(
828                         eq(testApnName),
829                         eq(new IwlanError(IwlanError.TUNNEL_NOT_FOUND)),
830                         metricsCaptor.capture());
831         assertEquals(testApnName, metricsCaptor.getValue().getApnName());
832     }
833 
834     @Test
testCloseTunnelWithForceClose()835     public void testCloseTunnelWithForceClose() throws Exception {
836         String testApnName = "www.xyz.com";
837 
838         mEpdgTunnelManager.putApnNameToTunnelConfig(
839                 testApnName,
840                 mMockIkeSession,
841                 mMockIwlanTunnelCallback,
842                 mMockIpSecTunnelInterface,
843                 null /* srcIpv6Addr */,
844                 0 /* srcIPv6AddrPrefixLen */,
845                 false /* isEmergency */,
846                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
847 
848         mEpdgTunnelManager.closeTunnel(
849                 testApnName,
850                 true /*forceClose*/,
851                 mMockIwlanTunnelCallback,
852                 BRINGDOWN_REASON_UNKNOWN);
853         mTestLooper.dispatchAll();
854 
855         verify(mMockIkeSession).kill();
856         verify(mEpdgTunnelManager).closePendingRequestsForApn(eq(testApnName));
857     }
858 
859     @Test
testCloseTunnelWithNonForceClose()860     public void testCloseTunnelWithNonForceClose() throws Exception {
861         String testApnName = "www.xyz.com";
862 
863         mEpdgTunnelManager.putApnNameToTunnelConfig(
864                 testApnName,
865                 mMockIkeSession,
866                 mMockIwlanTunnelCallback,
867                 mMockIpSecTunnelInterface,
868                 null /* srcIpv6Addr */,
869                 0 /* srcIPv6AddrPrefixLen */,
870                 false /* isEmergency */,
871                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
872 
873         mEpdgTunnelManager.closeTunnel(
874                 testApnName,
875                 false /*forceClose*/,
876                 mMockIwlanTunnelCallback,
877                 BRINGDOWN_REASON_UNKNOWN);
878         mTestLooper.dispatchAll();
879 
880         verify(mMockIkeSession).close();
881         verify(mEpdgTunnelManager).closePendingRequestsForApn(eq(testApnName));
882     }
883 
884     @Test
testRekeyAndNattTimerFromCarrierConfig()885     public void testRekeyAndNattTimerFromCarrierConfig() throws Exception {
886         // Test values
887         int hardTime = 50000;
888         int softTime = 20000;
889         int hardTimeChild = 10000;
890         int softTimeChild = 1000;
891         int nattTimer = 60;
892 
893         IwlanCarrierConfig.putTestConfigInt(
894                 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_HARD_TIMER_SEC_INT, hardTime);
895         IwlanCarrierConfig.putTestConfigInt(
896                 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_SOFT_TIMER_SEC_INT, softTime);
897         IwlanCarrierConfig.putTestConfigInt(
898                 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT, hardTimeChild);
899         IwlanCarrierConfig.putTestConfigInt(
900                 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT, softTimeChild);
901         IwlanCarrierConfig.putTestConfigInt(
902                 CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT, nattTimer);
903 
904         doReturn(null)
905                 .when(mMockIkeSessionCreator)
906                 .createIkeSession(
907                         eq(mMockContext),
908                         any(IkeSessionParams.class),
909                         any(ChildSessionParams.class),
910                         any(Executor.class),
911                         any(IkeSessionCallback.class),
912                         any(ChildSessionCallback.class));
913 
914         boolean ret =
915                 mEpdgTunnelManager.bringUpTunnel(
916                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
917                         mMockIwlanTunnelCallback);
918         assertTrue(ret);
919         mTestLooper.dispatchAll();
920 
921         mEpdgTunnelManager.sendSelectionRequestComplete(
922                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
923         mTestLooper.dispatchAll();
924 
925         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
926                 ArgumentCaptor.forClass(IkeSessionParams.class);
927         ArgumentCaptor<ChildSessionParams> childSessionParamsCaptor =
928                 ArgumentCaptor.forClass(ChildSessionParams.class);
929         verify(mMockIkeSessionCreator)
930                 .createIkeSession(
931                         eq(mMockContext),
932                         ikeSessionParamsCaptor.capture(),
933                         childSessionParamsCaptor.capture(),
934                         any(Executor.class),
935                         any(IkeSessionCallback.class),
936                         any(ChildSessionCallback.class));
937 
938         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
939         ChildSessionParams childSessionParams = childSessionParamsCaptor.getValue();
940 
941         assertEquals(hardTime, ikeSessionParams.getHardLifetimeSeconds());
942         assertEquals(softTime, ikeSessionParams.getSoftLifetimeSeconds());
943         assertEquals(hardTimeChild, childSessionParams.getHardLifetimeSeconds());
944         assertEquals(softTimeChild, childSessionParams.getSoftLifetimeSeconds());
945         assertEquals(nattTimer, ikeSessionParams.getNattKeepAliveDelaySeconds());
946     }
947 
948     @Test
testSetRetransmissionTimeoutsFromCarrierConfig()949     public void testSetRetransmissionTimeoutsFromCarrierConfig() throws Exception {
950         int[] testTimeouts = {1000, 1200, 1400, 1600, 2000, 4000};
951 
952         IwlanCarrierConfig.putTestConfigIntArray(
953                 CarrierConfigManager.Iwlan.KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY, testTimeouts);
954 
955         doReturn(null)
956                 .when(mMockIkeSessionCreator)
957                 .createIkeSession(
958                         eq(mMockContext),
959                         any(IkeSessionParams.class),
960                         any(ChildSessionParams.class),
961                         any(Executor.class),
962                         any(IkeSessionCallback.class),
963                         any(ChildSessionCallback.class));
964 
965         boolean ret =
966                 mEpdgTunnelManager.bringUpTunnel(
967                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
968                         mMockIwlanTunnelCallback);
969         assertTrue(ret);
970         mTestLooper.dispatchAll();
971 
972         mEpdgTunnelManager.sendSelectionRequestComplete(
973                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
974         mTestLooper.dispatchAll();
975 
976         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
977                 ArgumentCaptor.forClass(IkeSessionParams.class);
978         verify(mMockIkeSessionCreator)
979                 .createIkeSession(
980                         eq(mMockContext),
981                         ikeSessionParamsCaptor.capture(),
982                         any(ChildSessionParams.class),
983                         any(Executor.class),
984                         any(IkeSessionCallback.class),
985                         any(ChildSessionCallback.class));
986 
987         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
988         assertArrayEquals(ikeSessionParams.getRetransmissionTimeoutsMillis(), testTimeouts);
989     }
990 
991     @Test
testSetDpdDelayFromCarrierConfig()992     public void testSetDpdDelayFromCarrierConfig() throws Exception {
993         int testDpdDelay = 600;
994 
995         IwlanCarrierConfig.putTestConfigInt(
996                 CarrierConfigManager.Iwlan.KEY_DPD_TIMER_SEC_INT, testDpdDelay);
997 
998         doReturn(null)
999                 .when(mMockIkeSessionCreator)
1000                 .createIkeSession(
1001                         eq(mMockContext),
1002                         any(IkeSessionParams.class),
1003                         any(ChildSessionParams.class),
1004                         any(Executor.class),
1005                         any(IkeSessionCallback.class),
1006                         any(ChildSessionCallback.class));
1007 
1008         boolean ret =
1009                 mEpdgTunnelManager.bringUpTunnel(
1010                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1011                         mMockIwlanTunnelCallback);
1012         assertTrue(ret);
1013         mTestLooper.dispatchAll();
1014 
1015         mEpdgTunnelManager.sendSelectionRequestComplete(
1016                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
1017         mTestLooper.dispatchAll();
1018 
1019         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1020                 ArgumentCaptor.forClass(IkeSessionParams.class);
1021         verify(mMockIkeSessionCreator)
1022                 .createIkeSession(
1023                         eq(mMockContext),
1024                         ikeSessionParamsCaptor.capture(),
1025                         any(ChildSessionParams.class),
1026                         any(Executor.class),
1027                         any(IkeSessionCallback.class),
1028                         any(ChildSessionCallback.class));
1029 
1030         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
1031         assertEquals(testDpdDelay, ikeSessionParams.getDpdDelaySeconds());
1032     }
1033 
1034     @Test
testGetValidEpdgAddress_DiffAddr()1035     public void testGetValidEpdgAddress_DiffAddr() throws Exception {
1036         String testApnName = "www.xyz.com";
1037 
1038         List<InetAddress> ipList1 = new ArrayList<>();
1039         ipList1.add(InetAddress.getByName("1.1.1.1"));
1040         mEpdgTunnelManager.validateAndSetEpdgAddress(ipList1);
1041 
1042         IwlanError error = new IwlanError(new IkeInternalException(new IOException()));
1043 
1044         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1045 
1046         doReturn(null)
1047                 .doReturn(null)
1048                 .when(mMockIkeSessionCreator)
1049                 .createIkeSession(
1050                         eq(mMockContext),
1051                         any(IkeSessionParams.class),
1052                         any(ChildSessionParams.class),
1053                         any(Executor.class),
1054                         any(IkeSessionCallback.class),
1055                         any(ChildSessionCallback.class));
1056 
1057         boolean ret =
1058                 mEpdgTunnelManager.bringUpTunnel(
1059                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1060                         mMockIwlanTunnelCallback);
1061         assertTrue(ret);
1062         mTestLooper.dispatchAll();
1063 
1064         ArrayList<InetAddress> ipList2 = new ArrayList<>();
1065         ipList2.add(InetAddress.getByName("8.8.8.8"));
1066         mEpdgTunnelManager.sendSelectionRequestComplete(
1067                 ipList2, new IwlanError(IwlanError.NO_ERROR), 1);
1068         mTestLooper.dispatchAll();
1069 
1070         EpdgTunnelManager.TmIkeSessionCallback ikeSessionCallback =
1071                 verifyCreateIkeSession(ipList2.get(0));
1072         ikeSessionCallback.onClosedWithException(
1073                 new IkeInternalException(new IOException("Retransmitting failure")));
1074         mTestLooper.dispatchAll();
1075 
1076         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1077         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1078     }
1079 
1080     @Test
testGetValidEpdgAddress_NextAddr()1081     public void testGetValidEpdgAddress_NextAddr() throws Exception {
1082         String testApnName = "www.xyz.com";
1083 
1084         List<InetAddress> ipList1 = new ArrayList<>();
1085         ipList1.add(InetAddress.getByName("1.1.1.1"));
1086         ipList1.add(InetAddress.getByName("8.8.8.8"));
1087         mEpdgTunnelManager.validateAndSetEpdgAddress(ipList1);
1088 
1089         IwlanError error = new IwlanError(new IkeInternalException(new IOException()));
1090 
1091         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1092 
1093         doReturn(null)
1094                 .doReturn(null)
1095                 .when(mMockIkeSessionCreator)
1096                 .createIkeSession(
1097                         eq(mMockContext),
1098                         any(IkeSessionParams.class),
1099                         any(ChildSessionParams.class),
1100                         any(Executor.class),
1101                         any(IkeSessionCallback.class),
1102                         any(ChildSessionCallback.class));
1103 
1104         boolean ret =
1105                 mEpdgTunnelManager.bringUpTunnel(
1106                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1107                         mMockIwlanTunnelCallback);
1108         assertTrue(ret);
1109         mTestLooper.dispatchAll();
1110 
1111         ArrayList<InetAddress> ipList2 = new ArrayList<>();
1112         ipList2.add(InetAddress.getByName("1.1.1.1"));
1113         ipList2.add(InetAddress.getByName("8.8.8.8"));
1114         mEpdgTunnelManager.sendSelectionRequestComplete(
1115                 ipList2, new IwlanError(IwlanError.NO_ERROR), 1);
1116         mTestLooper.dispatchAll();
1117 
1118         EpdgTunnelManager.TmIkeSessionCallback ikeSessionCallback =
1119                 verifyCreateIkeSession(ipList2.get(1));
1120         ikeSessionCallback.onClosedWithException(
1121                 new IkeInternalException(new IOException("Retransmitting failure")));
1122         mTestLooper.dispatchAll();
1123 
1124         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1125         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1126     }
1127 
1128     @Test
testGetValidEpdgAddress_WhenExcludeFailedIpEnabled()1129     public void testGetValidEpdgAddress_WhenExcludeFailedIpEnabled() throws Exception {
1130         String testApnName = "www.xyz.com";
1131         when(mFakeFeatureFlags.epdgSelectionExcludeFailedIpAddress()).thenReturn(true);
1132 
1133         List<InetAddress> ipList1 =
1134                 List.of(InetAddress.getByName("1.1.1.1"), InetAddress.getByName("8.8.8.8"));
1135         mEpdgTunnelManager.validateAndSetEpdgAddress(ipList1);
1136 
1137         IwlanError error = new IwlanError(new IkeInternalException(new IOException()));
1138 
1139         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1140 
1141         doReturn(null)
1142                 .doReturn(null)
1143                 .when(mMockIkeSessionCreator)
1144                 .createIkeSession(
1145                         eq(mMockContext),
1146                         any(IkeSessionParams.class),
1147                         any(ChildSessionParams.class),
1148                         any(Executor.class),
1149                         any(IkeSessionCallback.class),
1150                         any(ChildSessionCallback.class));
1151 
1152         boolean ret =
1153                 mEpdgTunnelManager.bringUpTunnel(
1154                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1155                         mMockIwlanTunnelCallback);
1156         assertTrue(ret);
1157         mTestLooper.dispatchAll();
1158 
1159         List<InetAddress> ipList2 =
1160                 List.of(InetAddress.getByName("1.1.1.1"), InetAddress.getByName("8.8.8.8"));
1161         mEpdgTunnelManager.sendSelectionRequestComplete(
1162                 ipList2, new IwlanError(IwlanError.NO_ERROR), 1);
1163         mTestLooper.dispatchAll();
1164 
1165         // When exclude failed IP is enabled, EpdgSelector is responsible to excluding the failed
1166         // IP address from result. EpdgTunnelManager should always use the first IP address from
1167         // the ePDG selection result IP address list, regardless the list is same as prev or not
1168         EpdgTunnelManager.TmIkeSessionCallback ikeSessionCallback =
1169                 verifyCreateIkeSession(ipList2.get(0));
1170         ikeSessionCallback.onClosedWithException(
1171                 new IkeInternalException(new IOException("Retransmitting failure")));
1172         mTestLooper.dispatchAll();
1173 
1174         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1175         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1176     }
1177 
verifyCreateIkeSession(InetAddress ip)1178     private EpdgTunnelManager.TmIkeSessionCallback verifyCreateIkeSession(InetAddress ip)
1179             throws Exception {
1180         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1181                 ArgumentCaptor.forClass(IkeSessionParams.class);
1182         ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
1183                 ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
1184         verify(mMockIkeSessionCreator, atLeastOnce())
1185                 .createIkeSession(
1186                         eq(mMockContext),
1187                         ikeSessionParamsCaptor.capture(),
1188                         any(ChildSessionParams.class),
1189                         any(Executor.class),
1190                         ikeSessionCallbackCaptor.capture(),
1191                         any(ChildSessionCallback.class));
1192         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
1193         assertEquals(ip.getHostAddress(), ikeSessionParams.getServerHostname());
1194         return ikeSessionCallbackCaptor.getValue();
1195     }
1196 
1197     @Test
testIpv6PrefixMatching()1198     public void testIpv6PrefixMatching() throws Exception {
1199         InetAddress a1 = InetAddress.getByName("2600:381:4872:5d1e:ac45:69c7:bab2:639b");
1200         LinkAddress l1 = new LinkAddress(a1, 64);
1201         InetAddress src = InetAddress.getByName("2600:381:4872:5d1e:0:10:3582:a501");
1202         EpdgTunnelManager.TunnelConfig tf =
1203                 mEpdgTunnelManager
1204                 .new TunnelConfig(null, null, mMockIpSecTunnelInterface, src, 64, false, a1);
1205         assertTrue(tf.isPrefixSameAsSrcIP(l1));
1206 
1207         // different prefix length
1208         LinkAddress l2 = new LinkAddress(a1, 63);
1209         assertFalse(tf.isPrefixSameAsSrcIP(l2));
1210     }
1211 
1212     @Test
testBackOffTimeCalculation()1213     public void testBackOffTimeCalculation() throws Exception {
1214         int transactionId = 1;
1215 
1216         // unit: 10 mins value: 2 expectedTime: 1200 (10 * 60 * 2)
1217         verifyBackOffTimer("00000010", 1200, transactionId++);
1218         // unit: 1 hour value: 4 expectedTime: 14400 (1 * 60 * 60 * 4)
1219         verifyBackOffTimer("00100100", 14400, transactionId++);
1220         // unit: 10 hours value: 3 expectedTime: (10 * 60 * 60 * 3)
1221         verifyBackOffTimer("01000011", 108000, transactionId++);
1222         // unit: 2 secs value: 21 expectedTime: 42 (2 * 21)
1223         verifyBackOffTimer("01110101", 42, transactionId++);
1224         // unit: 30 secs value: 31 expectedTime: 930 (30 * 31)
1225         verifyBackOffTimer("10011111", 930, transactionId++);
1226         // unit: 1 min value: 25 expectedTime: 1500 (1 * 60 * 25)
1227         verifyBackOffTimer("10111001", 1500, transactionId++);
1228         // unit: 1 hour value: 12 expectedTime: 43200 (1 * 60 * 60 * 12)
1229         verifyBackOffTimer("11001100", 43200, transactionId++);
1230         // deactivate - Should not report backoff time.
1231         verifyBackOffTimer("11100100", -1, transactionId++);
1232     }
1233 
verifyBackOffTimer(String backoffByte, long expectedBackoffTime, int transactionId)1234     private void verifyBackOffTimer(String backoffByte, long expectedBackoffTime, int transactionId)
1235             throws Exception {
1236         String testApnName = "www.xyz.com";
1237         IwlanError error = new IwlanError(new IkeInternalException(new Exception()));
1238         Ike3gppBackoffTimer mockIke3gppBackoffTimer = mock(Ike3gppBackoffTimer.class);
1239         List<Ike3gppData> ike3gppInfoList = new ArrayList<>();
1240         ike3gppInfoList.add(mockIke3gppBackoffTimer);
1241         doReturn(Ike3gppData.DATA_TYPE_NOTIFY_BACKOFF_TIMER)
1242                 .when(mockIke3gppBackoffTimer)
1243                 .getDataType();
1244         doReturn((byte) Integer.parseInt(backoffByte, 2))
1245                 .when(mockIke3gppBackoffTimer)
1246                 .getBackoffTimer();
1247 
1248         // if back off time expected is negative normal reportIwlanError should be called.
1249         if (expectedBackoffTime < 0) {
1250             doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1251         } else {
1252             doReturn(0L)
1253                     .when(mEpdgTunnelManager)
1254                     .reportIwlanError(eq(testApnName), eq(error), anyLong());
1255         }
1256 
1257         doReturn(null)
1258                 .doReturn(null)
1259                 .when(mMockIkeSessionCreator)
1260                 .createIkeSession(
1261                         eq(mMockContext),
1262                         any(IkeSessionParams.class),
1263                         any(ChildSessionParams.class),
1264                         any(Executor.class),
1265                         any(IkeSessionCallback.class),
1266                         any(ChildSessionCallback.class));
1267 
1268         boolean ret =
1269                 mEpdgTunnelManager.bringUpTunnel(
1270                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1271                         mMockIwlanTunnelCallback);
1272         assertTrue(ret);
1273         mTestLooper.dispatchAll();
1274 
1275         mEpdgTunnelManager.sendSelectionRequestComplete(
1276                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), transactionId);
1277         mTestLooper.dispatchAll();
1278 
1279         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1280                 ArgumentCaptor.forClass(IkeSessionParams.class);
1281         ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
1282                 ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
1283         verify(mMockIkeSessionCreator, atLeastOnce())
1284                 .createIkeSession(
1285                         eq(mMockContext),
1286                         ikeSessionParamsCaptor.capture(),
1287                         any(ChildSessionParams.class),
1288                         any(Executor.class),
1289                         ikeSessionCallbackCaptor.capture(),
1290                         any(ChildSessionCallback.class));
1291         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
1292         assertEquals(
1293                 EXPECTED_EPDG_ADDRESSES.get(0).getHostAddress(),
1294                 ikeSessionParams.getServerHostname());
1295 
1296         Ike3gppExtension.Ike3gppDataListener ike3gppCallback =
1297                 ikeSessionParams.getIke3gppExtension().getIke3gppDataListener();
1298         ike3gppCallback.onIke3gppDataReceived(ike3gppInfoList);
1299         EpdgTunnelManager.TmIkeSessionCallback ikeSessionCallback =
1300                 ikeSessionCallbackCaptor.getValue();
1301         ikeSessionCallback.onClosedWithException(new IkeInternalException(new Exception()));
1302         mTestLooper.dispatchAll();
1303 
1304         // if expected backoff time is negative - verify that backoff time is not reported.
1305         if (expectedBackoffTime < 0) {
1306             verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1307         } else {
1308             // Else - Verify reportIwlanError with correct backoff time is being called.
1309             verify(mEpdgTunnelManager)
1310                     .reportIwlanError(eq(testApnName), eq(error), eq(expectedBackoffTime));
1311         }
1312         verify(mMockIwlanTunnelCallback, atLeastOnce()).onClosed(eq(testApnName), eq(error), any());
1313     }
1314 
getBasicTunnelSetupRequest(String apnName, int apnIpProtocol)1315     private TunnelSetupRequest getBasicTunnelSetupRequest(String apnName, int apnIpProtocol) {
1316         return getBasicTunnelSetupRequest(apnName, apnIpProtocol, 1);
1317     }
1318 
getBasicTunnelSetupRequest( String apnName, int apnIpProtocol, int pduSessionId)1319     private TunnelSetupRequest getBasicTunnelSetupRequest(
1320             String apnName, int apnIpProtocol, int pduSessionId) {
1321         return TunnelSetupRequest.builder()
1322                 .setApnName(apnName)
1323                 .setIsRoaming(false /*isRoaming*/)
1324                 .setIsEmergency(false /*IsEmergency*/)
1325                 .setRequestPcscf(false /*requestPcscf*/)
1326                 .setApnIpProtocol(apnIpProtocol)
1327                 .setPduSessionId(pduSessionId)
1328                 .build();
1329     }
1330 
getHandoverTunnelSetupRequest(String apnName, int apnIpProtocol)1331     private TunnelSetupRequest getHandoverTunnelSetupRequest(String apnName, int apnIpProtocol) {
1332         TunnelSetupRequest.Builder bld = TunnelSetupRequest.builder();
1333         bld.setApnName(apnName)
1334                 .setIsRoaming(false /*isRoaming*/)
1335                 .setIsEmergency(false /*IsEmergency*/)
1336                 .setRequestPcscf(false /*requestPcscf*/)
1337                 .setApnIpProtocol(apnIpProtocol)
1338                 .setPduSessionId(1);
1339         switch (apnIpProtocol) {
1340             case ApnSetting.PROTOCOL_IP:
1341                 bld.setSrcIpv4Address(InetAddresses.parseNumericAddress("10.10.10.10"));
1342                 break;
1343             case ApnSetting.PROTOCOL_IPV6:
1344                 bld.setSrcIpv6Address(
1345                         InetAddresses.parseNumericAddress(
1346                                 "2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
1347                 break;
1348             case ApnSetting.PROTOCOL_IPV4V6:
1349                 bld.setSrcIpv4Address(InetAddresses.parseNumericAddress("10.10.10.10"));
1350                 bld.setSrcIpv6Address(
1351                         InetAddresses.parseNumericAddress(
1352                                 "2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
1353                 break;
1354         }
1355         return bld.build();
1356     }
1357 
1358     @Test
testHandleOnClosedWithEpdgConnected_True()1359     public void testHandleOnClosedWithEpdgConnected_True() throws Exception {
1360         String testApnName = "www.xyz.com";
1361         IwlanError error =
1362                 new IwlanError(IwlanError.IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED);
1363 
1364         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1365         mEpdgTunnelManager.putApnNameToTunnelConfig(
1366                 testApnName,
1367                 mMockIkeSession,
1368                 mMockIwlanTunnelCallback,
1369                 mMockIpSecTunnelInterface,
1370                 null /* srcIpv6Addr */,
1371                 0 /* srcIPv6AddrPrefixLen */,
1372                 false /* isEmergency */,
1373                 InetAddresses.parseNumericAddress(EPDG_ADDRESS));
1374         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
1375 
1376         mEpdgTunnelManager.onConnectedToEpdg(true);
1377         mEpdgTunnelManager.mEpdgMonitor.onApnConnectToEpdg(
1378                 testApnName, InetAddresses.parseNumericAddress(EPDG_ADDRESS));
1379 
1380         mEpdgTunnelManager.getTmIkeSessionCallback(testApnName, token).onClosed();
1381         mTestLooper.dispatchAll();
1382 
1383         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1384         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1385     }
1386 
1387     @Test
testHandleOnClosedWithEpdgConnected_False()1388     public void testHandleOnClosedWithEpdgConnected_False() throws Exception {
1389         String testApnName = "www.xyz.com";
1390         IwlanError error =
1391                 new IwlanError(IwlanError.IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED);
1392 
1393         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1394 
1395         boolean ret =
1396                 mEpdgTunnelManager.bringUpTunnel(
1397                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1398                         mMockIwlanTunnelCallback);
1399         assertTrue(ret);
1400         mTestLooper.dispatchAll();
1401 
1402         mEpdgTunnelManager.sendSelectionRequestComplete(
1403                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
1404         mTestLooper.dispatchAll();
1405 
1406         mEpdgTunnelManager.onConnectedToEpdg(false);
1407 
1408         mEpdgTunnelManager.getTmIkeSessionCallback(testApnName, DEFAULT_TOKEN).onClosed();
1409         mTestLooper.dispatchAll();
1410 
1411         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1412         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1413     }
1414 
setOneTunnelOpened(String apnName)1415     private void setOneTunnelOpened(String apnName) throws Exception {
1416         InetAddress epdgAddress =
1417                 mEpdgTunnelManager.validateAndSetEpdgAddress(EXPECTED_EPDG_ADDRESSES);
1418         mEpdgTunnelManager.putApnNameToTunnelConfig(
1419                 apnName,
1420                 mMockIkeSession,
1421                 mMockIwlanTunnelCallback,
1422                 mMockIpSecTunnelInterface,
1423                 null /* srcIpv6Addr */,
1424                 0 /* srcIPv6AddrPrefixLen */,
1425                 false /* isEmergency */,
1426                 epdgAddress);
1427         mEpdgTunnelManager.mEpdgMonitor.onApnConnectToEpdg(apnName, epdgAddress);
1428         mEpdgTunnelManager.onConnectedToEpdg(true);
1429     }
1430 
verifyBringUpTunnelWithDnsQuery( String apnName, Network network)1431     private IkeSessionArgumentCaptors verifyBringUpTunnelWithDnsQuery(
1432             String apnName, Network network) throws Exception {
1433         return verifyBringUpTunnelWithDnsQuery(apnName, network, null);
1434     }
1435 
verifyBringUpTunnelWithDnsQuery( String apnName, Network network, IkeSession ikeSession)1436     private IkeSessionArgumentCaptors verifyBringUpTunnelWithDnsQuery(
1437             String apnName, Network network, IkeSession ikeSession) throws Exception {
1438         reset(mMockIwlanTunnelCallback);
1439         IkeSessionArgumentCaptors ikeSessionArgumentCaptors = new IkeSessionArgumentCaptors();
1440 
1441         verifyBringUpTunnel(apnName, network, true /* needPendingBringUpReq */);
1442 
1443         doReturn(ikeSession)
1444                 .when(mMockIkeSessionCreator)
1445                 .createIkeSession(
1446                         eq(mMockContext),
1447                         ikeSessionArgumentCaptors.mIkeSessionParamsCaptor.capture(),
1448                         ikeSessionArgumentCaptors.mChildSessionParamsCaptor.capture(),
1449                         any(Executor.class),
1450                         ikeSessionArgumentCaptors.mIkeSessionCallbackCaptor.capture(),
1451                         ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.capture());
1452 
1453         mEpdgTunnelManager.sendSelectionRequestComplete(
1454                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
1455         mTestLooper.dispatchAll();
1456 
1457         verify(mMockIkeSessionCreator)
1458                 .createIkeSession(
1459                         eq(mMockContext),
1460                         ikeSessionArgumentCaptors.mIkeSessionParamsCaptor.capture(),
1461                         ikeSessionArgumentCaptors.mChildSessionParamsCaptor.capture(),
1462                         any(Executor.class),
1463                         ikeSessionArgumentCaptors.mIkeSessionCallbackCaptor.capture(),
1464                         ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.capture());
1465 
1466         return ikeSessionArgumentCaptors;
1467     }
1468 
verifyBringUpTunnel( String apnName, Network network, boolean needPendingBringUpReq)1469     private IkeSessionArgumentCaptors verifyBringUpTunnel(
1470             String apnName, Network network, boolean needPendingBringUpReq) throws Exception {
1471         reset(mMockIkeSessionCreator);
1472         IkeSessionArgumentCaptors ikeSessionArgumentCaptors = new IkeSessionArgumentCaptors();
1473 
1474         doReturn(null)
1475                 .when(mMockIkeSessionCreator)
1476                 .createIkeSession(
1477                         eq(mMockContext),
1478                         ikeSessionArgumentCaptors.mIkeSessionParamsCaptor.capture(),
1479                         ikeSessionArgumentCaptors.mChildSessionParamsCaptor.capture(),
1480                         any(Executor.class),
1481                         ikeSessionArgumentCaptors.mIkeSessionCallbackCaptor.capture(),
1482                         ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.capture());
1483 
1484         boolean ret =
1485                 mEpdgTunnelManager.bringUpTunnel(
1486                         getBasicTunnelSetupRequest(apnName, ApnSetting.PROTOCOL_IP),
1487                         mMockIwlanTunnelCallback);
1488         assertTrue(ret);
1489         mTestLooper.dispatchAll();
1490 
1491         verify(mMockIkeSessionCreator, times(needPendingBringUpReq ? 0 : 1))
1492                 .createIkeSession(
1493                         eq(mMockContext),
1494                         ikeSessionArgumentCaptors.mIkeSessionParamsCaptor.capture(),
1495                         ikeSessionArgumentCaptors.mChildSessionParamsCaptor.capture(),
1496                         any(Executor.class),
1497                         ikeSessionArgumentCaptors.mIkeSessionCallbackCaptor.capture(),
1498                         ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.capture());
1499 
1500         if (!needPendingBringUpReq) {
1501             verify(mMockIpSecManager)
1502                     .createIpSecTunnelInterface(
1503                             any(InetAddress.class), any(InetAddress.class), eq(network));
1504         }
1505 
1506         return ikeSessionArgumentCaptors;
1507     }
1508 
verifyTunnelOnOpened(String apnName, ChildSessionCallback childSessionCallback)1509     private void verifyTunnelOnOpened(String apnName, ChildSessionCallback childSessionCallback) {
1510         clearInvocations(mMockIpSecManager);
1511         doReturn(0L)
1512                 .when(mEpdgTunnelManager)
1513                 .reportIwlanError(eq(apnName), eq(new IwlanError(IwlanError.NO_ERROR)));
1514 
1515         mEpdgTunnelManager
1516                 .getTmIkeSessionCallback(apnName, mEpdgTunnelManager.getCurrentTokenForApn(apnName))
1517                 .onOpened(mMockIkeSessionConfiguration);
1518         mTestLooper.dispatchAll();
1519         childSessionCallback.onIpSecTransformCreated(
1520                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
1521         mTestLooper.dispatchAll();
1522         childSessionCallback.onIpSecTransformCreated(
1523                 mMockedIpSecTransformOut, IpSecManager.DIRECTION_OUT);
1524         mTestLooper.dispatchAll();
1525 
1526         childSessionCallback.onOpened(mMockChildSessionConfiguration);
1527         mTestLooper.dispatchAll();
1528         verify(mEpdgTunnelManager)
1529                 .reportIwlanError(eq(apnName), eq(new IwlanError(IwlanError.NO_ERROR)));
1530         verify(mMockIwlanTunnelCallback).onOpened(eq(apnName), any(), any());
1531     }
1532 
1533     @Test
testHandleOnOpenedWithEpdgConnected_True()1534     public void testHandleOnOpenedWithEpdgConnected_True() throws Exception {
1535         final String openedApnName = "ims";
1536         final String toBeOpenedApnName = "mms";
1537 
1538         setOneTunnelOpened(openedApnName);
1539 
1540         // FIXME: Since the network from bringUpTunnel() will only be stored for the first request,
1541         // and we are skipping the first tunnel setup procedure in this test case, it is necessary
1542         // to set the network instance directly.
1543         mEpdgTunnelManager.updateNetwork(mMockDefaultNetwork, mMockLinkProperties);
1544         mTestLooper.dispatchAll();
1545 
1546         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
1547                 verifyBringUpTunnel(
1548                         toBeOpenedApnName, mMockDefaultNetwork, false /* needPendingBringUpReq */);
1549         ChildSessionCallback childSessionCallback =
1550                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
1551         verifyTunnelOnOpened(toBeOpenedApnName, childSessionCallback);
1552         verify(mMockEpdgSelector, never()).onEpdgConnectionFailed(any(), any());
1553         verify(mMockEpdgSelector).onEpdgConnectedSuccessfully();
1554     }
1555 
1556     @Test
testServicePendingRequests()1557     public void testServicePendingRequests() throws Exception {
1558         final String firstApnName = "ims";
1559         final String secondApnName = "mms";
1560 
1561         IkeSessionArgumentCaptors firstTunnelArgumentCaptors =
1562                 verifyBringUpTunnelWithDnsQuery(firstApnName, mMockDefaultNetwork);
1563         ChildSessionCallback firstCallback =
1564                 firstTunnelArgumentCaptors.mChildSessionCallbackCaptor.getValue();
1565 
1566         IkeSessionArgumentCaptors secondTunnelArgumentCaptors =
1567                 verifyBringUpTunnel(
1568                         secondApnName, mMockDefaultNetwork, true /* needPendingBringUpReq */);
1569         verifyTunnelOnOpened(firstApnName, firstCallback);
1570 
1571         ChildSessionCallback secondCallback =
1572                 secondTunnelArgumentCaptors.mChildSessionCallbackCaptor.getValue();
1573         verifyTunnelOnOpened(secondApnName, secondCallback);
1574     }
1575 
1576     @Test
testHandleOnClosedExceptionallyWithEpdgConnected_True()1577     public void testHandleOnClosedExceptionallyWithEpdgConnected_True() throws Exception {
1578         String testApnName = "www.xyz.com";
1579         IwlanError error = new IwlanError(mMockIkeException);
1580 
1581         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1582 
1583         mEpdgTunnelManager.putApnNameToTunnelConfig(
1584                 testApnName,
1585                 mMockIkeSession,
1586                 mMockIwlanTunnelCallback,
1587                 mMockIpSecTunnelInterface,
1588                 null /* srcIpv6Addr */,
1589                 0 /* srcIPv6AddrPrefixLen */,
1590                 false /* isEmergency */,
1591                 InetAddresses.parseNumericAddress(EPDG_ADDRESS));
1592         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
1593 
1594         mEpdgTunnelManager.onConnectedToEpdg(true);
1595         mEpdgTunnelManager.mEpdgMonitor.onApnConnectToEpdg(
1596                 testApnName, InetAddresses.parseNumericAddress(EPDG_ADDRESS));
1597 
1598         mEpdgTunnelManager
1599                 .getTmIkeSessionCallback(testApnName, token)
1600                 .onClosedWithException(mMockIkeException);
1601         mTestLooper.dispatchAll();
1602 
1603         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1604         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1605     }
1606 
1607     @Test
testHandleOnClosedExceptionallyWithEpdgConnected_False()1608     public void testHandleOnClosedExceptionallyWithEpdgConnected_False() throws Exception {
1609         String testApnName = "www.xyz.com";
1610         IwlanError error = new IwlanError(mMockIkeException);
1611 
1612         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1613 
1614         boolean ret =
1615                 mEpdgTunnelManager.bringUpTunnel(
1616                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1617                         mMockIwlanTunnelCallback);
1618         assertTrue(ret);
1619         mTestLooper.dispatchAll();
1620 
1621         mEpdgTunnelManager.sendSelectionRequestComplete(
1622                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
1623         mTestLooper.dispatchAll();
1624 
1625         mEpdgTunnelManager.mEpdgMonitor.onApnDisconnectFromEpdg(TEST_APN_NAME);
1626         mEpdgTunnelManager.onConnectedToEpdg(false);
1627 
1628         mEpdgTunnelManager
1629                 .getTmIkeSessionCallback(testApnName, DEFAULT_TOKEN)
1630                 .onClosedWithException(mMockIkeException);
1631         mTestLooper.dispatchAll();
1632 
1633         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), any(IwlanError.class), any());
1634         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1635     }
1636 
1637     @Test
testIkeSessionOnOpenedUpdatesPcscfAddrInTunnelConfig()1638     public void testIkeSessionOnOpenedUpdatesPcscfAddrInTunnelConfig() throws Exception {
1639         String testApnName = "ims";
1640         IwlanError error = new IwlanError(IwlanError.NO_ERROR);
1641 
1642         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1643         mEpdgTunnelManager.putApnNameToTunnelConfig(
1644                 testApnName,
1645                 mMockIkeSession,
1646                 mMockIwlanTunnelCallback,
1647                 mMockIpSecTunnelInterface,
1648                 null /* srcIpv6Addr */,
1649                 0 /* srcIPv6AddrPrefixLen */,
1650                 false /* isEmergency */,
1651                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
1652         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
1653 
1654         when(mMockIkeSessionConfiguration.getPcscfServers()).thenReturn(EXPECTED_EPDG_ADDRESSES);
1655 
1656         mEpdgTunnelManager
1657                 .getTmIkeSessionCallback(testApnName, token)
1658                 .onOpened(mMockIkeSessionConfiguration);
1659         mTestLooper.dispatchAll();
1660 
1661         EpdgTunnelManager.TunnelConfig testApnTunnelConfig =
1662                 mEpdgTunnelManager.getTunnelConfigForApn(testApnName);
1663         assertEquals(EXPECTED_EPDG_ADDRESSES, testApnTunnelConfig.getPcscfAddrList());
1664     }
1665 
1666     @Test
testIkeSessionClosesWhenChildSessionTransformThrows()1667     public void testIkeSessionClosesWhenChildSessionTransformThrows() throws Exception {
1668         String testApnName = "ims";
1669 
1670         doThrow(new IllegalArgumentException())
1671                 .when(mMockIpSecManager)
1672                 .applyTunnelModeTransform(eq(mMockIpSecTunnelInterface), anyInt(), any());
1673         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
1674                 verifyBringUpTunnelWithDnsQuery(testApnName, mMockDefaultNetwork, mMockIkeSession);
1675         ChildSessionCallback childSessionCallback =
1676                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
1677         childSessionCallback.onIpSecTransformCreated(
1678                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
1679         mTestLooper.dispatchAll();
1680 
1681         verify(mMockIkeSession).close();
1682     }
1683 
1684     @Test
testIkeSessionConnectionInfoChangedSetsUnderlyingNetwork()1685     public void testIkeSessionConnectionInfoChangedSetsUnderlyingNetwork() throws Exception {
1686         String testApnName = "ims";
1687         when(mMockConnectivityManager.getLinkProperties(any())).thenReturn(mMockLinkProperties);
1688 
1689         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
1690                 verifyBringUpTunnelWithDnsQuery(testApnName, mMockDefaultNetwork, mMockIkeSession);
1691         ChildSessionCallback childSessionCallback =
1692                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
1693         childSessionCallback.onIpSecTransformCreated(
1694                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
1695 
1696         mEpdgTunnelManager
1697                 .getTmIkeSessionCallback(testApnName, DEFAULT_TOKEN)
1698                 .onIkeSessionConnectionInfoChanged(mMockIkeSessionConnectionInfo);
1699         mTestLooper.dispatchAll();
1700 
1701         verify(mMockIpSecTunnelInterface).setUnderlyingNetwork(mMockDefaultNetwork);
1702     }
1703 
1704     @Test
testIkeSessionConnectionInfoChangedWithNullLinkPropertiesDoesNothing()1705     public void testIkeSessionConnectionInfoChangedWithNullLinkPropertiesDoesNothing()
1706             throws Exception {
1707         String testApnName = "ims";
1708         when(mMockConnectivityManager.getLinkProperties(any())).thenReturn(null);
1709 
1710         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
1711                 verifyBringUpTunnelWithDnsQuery(testApnName, mMockDefaultNetwork, mMockIkeSession);
1712         ChildSessionCallback childSessionCallback =
1713                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
1714         childSessionCallback.onIpSecTransformCreated(
1715                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
1716 
1717         mEpdgTunnelManager
1718                 .getTmIkeSessionCallback(testApnName, DEFAULT_TOKEN)
1719                 .onIkeSessionConnectionInfoChanged(mMockIkeSessionConnectionInfo);
1720         mTestLooper.dispatchAll();
1721 
1722         verify(mMockIpSecTunnelInterface, never()).setUnderlyingNetwork(any());
1723     }
1724 
1725     @Test
testSetIkeTrafficSelectorsIPv4()1726     public void testSetIkeTrafficSelectorsIPv4() throws Exception {
1727         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IP, false);
1728     }
1729 
1730     @Test
testSetIkeTrafficSelectorsIPv6()1731     public void testSetIkeTrafficSelectorsIPv6() throws Exception {
1732         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV6, false);
1733     }
1734 
1735     @Test
testSetIkeTrafficSelectorsIPv4v6()1736     public void testSetIkeTrafficSelectorsIPv4v6() throws Exception {
1737         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV4V6, false);
1738     }
1739 
1740     @Test
testSetIkeTrafficSelectorsIPv4_handover()1741     public void testSetIkeTrafficSelectorsIPv4_handover() throws Exception {
1742         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IP, true);
1743     }
1744 
1745     @Test
testSetIkeTrafficSelectorsIPv6_handover()1746     public void testSetIkeTrafficSelectorsIPv6_handover() throws Exception {
1747         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV6, true);
1748     }
1749 
1750     @Test
testSetIkeTrafficSelectorsIPv4v6_handover()1751     public void testSetIkeTrafficSelectorsIPv4v6_handover() throws Exception {
1752         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV4V6, true);
1753     }
1754 
testSetIkeTrafficSelectors(int apnProtocol, boolean handover)1755     private void testSetIkeTrafficSelectors(int apnProtocol, boolean handover) throws Exception {
1756         doReturn(null)
1757                 .when(mMockIkeSessionCreator)
1758                 .createIkeSession(
1759                         eq(mMockContext),
1760                         any(IkeSessionParams.class),
1761                         any(ChildSessionParams.class),
1762                         any(Executor.class),
1763                         any(IkeSessionCallback.class),
1764                         any(ChildSessionCallback.class));
1765 
1766         boolean ret;
1767 
1768         if (handover) {
1769             ret =
1770                     mEpdgTunnelManager.bringUpTunnel(
1771                             getHandoverTunnelSetupRequest(TEST_APN_NAME, apnProtocol),
1772                             mMockIwlanTunnelCallback);
1773         } else {
1774             ret =
1775                     mEpdgTunnelManager.bringUpTunnel(
1776                             getBasicTunnelSetupRequest(TEST_APN_NAME, apnProtocol),
1777                             mMockIwlanTunnelCallback);
1778         }
1779 
1780         assertTrue(ret);
1781         mTestLooper.dispatchAll();
1782 
1783         mEpdgTunnelManager.sendSelectionRequestComplete(
1784                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
1785         mTestLooper.dispatchAll();
1786 
1787         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1788                 ArgumentCaptor.forClass(IkeSessionParams.class);
1789         ArgumentCaptor<ChildSessionParams> childSessionParamsCaptor =
1790                 ArgumentCaptor.forClass(ChildSessionParams.class);
1791         verify(mMockIkeSessionCreator)
1792                 .createIkeSession(
1793                         eq(mMockContext),
1794                         ikeSessionParamsCaptor.capture(),
1795                         childSessionParamsCaptor.capture(),
1796                         any(Executor.class),
1797                         any(IkeSessionCallback.class),
1798                         any(ChildSessionCallback.class));
1799 
1800         ChildSessionParams childSessionParams = childSessionParamsCaptor.getValue();
1801 
1802         switch (apnProtocol) {
1803             case ApnSetting.PROTOCOL_IPV4V6:
1804                 assertEquals(2, childSessionParams.getInboundTrafficSelectors().size());
1805                 assertEquals(2, childSessionParams.getOutboundTrafficSelectors().size());
1806                 assertNotSame(
1807                         childSessionParams.getInboundTrafficSelectors().get(0).endingAddress,
1808                         childSessionParams.getInboundTrafficSelectors().get(1).endingAddress);
1809                 assertNotSame(
1810                         childSessionParams.getInboundTrafficSelectors().get(0).startingAddress,
1811                         childSessionParams.getInboundTrafficSelectors().get(1).startingAddress);
1812                 break;
1813             case ApnSetting.PROTOCOL_IPV6:
1814                 assertEquals(1, childSessionParams.getInboundTrafficSelectors().size());
1815                 assertEquals(1, childSessionParams.getOutboundTrafficSelectors().size());
1816                 assertEquals(
1817                         childSessionParams.getOutboundTrafficSelectors().get(0),
1818                         childSessionParams.getInboundTrafficSelectors().get(0));
1819                 assertEquals(
1820                         InetAddresses.parseNumericAddress(
1821                                 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
1822                         childSessionParams.getInboundTrafficSelectors().get(0).endingAddress);
1823                 assertEquals(
1824                         InetAddresses.parseNumericAddress("::"),
1825                         childSessionParams.getInboundTrafficSelectors().get(0).startingAddress);
1826                 break;
1827             case ApnSetting.PROTOCOL_IP:
1828                 assertEquals(1, childSessionParams.getInboundTrafficSelectors().size());
1829                 assertEquals(1, childSessionParams.getOutboundTrafficSelectors().size());
1830                 assertEquals(
1831                         childSessionParams.getOutboundTrafficSelectors().get(0),
1832                         childSessionParams.getInboundTrafficSelectors().get(0));
1833                 assertEquals(
1834                         InetAddresses.parseNumericAddress("255.255.255.255"),
1835                         childSessionParams.getInboundTrafficSelectors().get(0).endingAddress);
1836                 assertEquals(
1837                         InetAddresses.parseNumericAddress("0.0.0.0"),
1838                         childSessionParams.getInboundTrafficSelectors().get(0).startingAddress);
1839                 break;
1840         }
1841     }
1842 
1843     @Test
testUnsetPduSessionIdInclusion()1844     public void testUnsetPduSessionIdInclusion() throws Exception {
1845         verifyN1modeCapability(0);
1846     }
1847 
1848     @Test
testPduSessionIdInclusion()1849     public void testPduSessionIdInclusion() throws Exception {
1850         verifyN1modeCapability(8);
1851     }
1852 
1853     @Test
testReportIwlanErrorIkeProtocolException()1854     public void testReportIwlanErrorIkeProtocolException() throws Exception {
1855         String testApnName = "www.xyz.com";
1856 
1857         IkeProtocolException mockException = mock(IkeProtocolException.class);
1858         doReturn(IkeProtocolException.ERROR_TYPE_INVALID_IKE_SPI)
1859                 .when(mockException)
1860                 .getErrorType();
1861         doReturn(new byte[0]).when(mockException).getErrorData();
1862         IwlanError error = new IwlanError(mockException);
1863 
1864         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1865 
1866         mEpdgTunnelManager.putApnNameToTunnelConfig(
1867                 testApnName,
1868                 mMockIkeSession,
1869                 mMockIwlanTunnelCallback,
1870                 mMockIpSecTunnelInterface,
1871                 null /* srcIpv6Addr */,
1872                 0 /* srcIPv6AddrPrefixLen */,
1873                 false /* isEmergency */,
1874                 InetAddresses.parseNumericAddress(EPDG_ADDRESS));
1875         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
1876 
1877         mEpdgTunnelManager.onConnectedToEpdg(true);
1878         mEpdgTunnelManager.mEpdgMonitor.onApnConnectToEpdg(
1879                 testApnName, InetAddresses.parseNumericAddress(EPDG_ADDRESS));
1880 
1881         mEpdgTunnelManager
1882                 .getTmIkeSessionCallback(testApnName, token)
1883                 .onClosedWithException(mockException);
1884         mTestLooper.dispatchAll();
1885 
1886         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1887         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1888     }
1889 
1890     @Test
testReportIwlanErrorServerSelectionFailed()1891     public void testReportIwlanErrorServerSelectionFailed() throws Exception {
1892         String testApnName = "www.xyz.com";
1893         IwlanError error = new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
1894 
1895         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1896 
1897         boolean ret =
1898                 mEpdgTunnelManager.bringUpTunnel(
1899                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1900                         mMockIwlanTunnelCallback);
1901         assertTrue(ret);
1902         mTestLooper.dispatchAll();
1903 
1904         mEpdgTunnelManager.sendSelectionRequestComplete(null, error, 1);
1905         mTestLooper.dispatchAll();
1906 
1907         mEpdgTunnelManager.mEpdgMonitor.onApnDisconnectFromEpdg(TEST_APN_NAME);
1908         mEpdgTunnelManager.onConnectedToEpdg(false);
1909 
1910         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1911     }
1912 
1913     @Test
testNeverReportIwlanErrorWhenCloseAnOpenedTunnel()1914     public void testNeverReportIwlanErrorWhenCloseAnOpenedTunnel() throws Exception {
1915         IkeInternalException ikeException =
1916                 new IkeInternalException(new IOException("Retransmitting failure"));
1917 
1918         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
1919                 verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME, mMockDefaultNetwork);
1920 
1921         ChildSessionCallback childSessionCallback =
1922                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
1923         verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
1924 
1925         reset(mEpdgTunnelManager); // reset number of times of reportIwlanError()
1926 
1927         mEpdgTunnelManager
1928                 .getTmIkeSessionCallback(TEST_APN_NAME, 0)
1929                 .onClosedWithException(ikeException);
1930         mTestLooper.dispatchAll();
1931         verify(mEpdgTunnelManager, never()).reportIwlanError(eq(TEST_APN_NAME), any());
1932         verify(mMockIwlanTunnelCallback)
1933                 .onClosed(eq(TEST_APN_NAME), eq(new IwlanError(ikeException)), any());
1934     }
1935 
1936     @Test
testCanBringUpTunnel()1937     public void testCanBringUpTunnel() throws Exception {
1938         String testApnName = "www.xyz.com";
1939         IwlanError error = new IwlanError(mMockIkeException);
1940 
1941         doReturn(error).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName), anyBoolean());
1942         doReturn(error).when(mEpdgTunnelManager).getLastError(eq(testApnName));
1943 
1944         boolean ret =
1945                 mEpdgTunnelManager.bringUpTunnel(
1946                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1947                         mMockIwlanTunnelCallback);
1948         assertTrue(ret);
1949         mTestLooper.dispatchAll();
1950         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
1951     }
1952 
verifyN1modeCapability(int pduSessionId)1953     private void verifyN1modeCapability(int pduSessionId) throws Exception {
1954         byte pduSessionIdToByte = (byte) pduSessionId;
1955 
1956         doReturn(null)
1957                 .when(mMockIkeSessionCreator)
1958                 .createIkeSession(
1959                         eq(mMockContext),
1960                         any(IkeSessionParams.class),
1961                         any(ChildSessionParams.class),
1962                         any(Executor.class),
1963                         any(IkeSessionCallback.class),
1964                         any(ChildSessionCallback.class));
1965 
1966         boolean ret;
1967 
1968         ret =
1969                 mEpdgTunnelManager.bringUpTunnel(
1970                         getBasicTunnelSetupRequest(
1971                                 TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6, pduSessionId),
1972                         mMockIwlanTunnelCallback);
1973 
1974         assertTrue(ret);
1975         mTestLooper.dispatchAll();
1976 
1977         mEpdgTunnelManager.sendSelectionRequestComplete(
1978                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
1979         mTestLooper.dispatchAll();
1980 
1981         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1982                 ArgumentCaptor.forClass(IkeSessionParams.class);
1983         ArgumentCaptor<ChildSessionParams> childSessionParamsCaptor =
1984                 ArgumentCaptor.forClass(ChildSessionParams.class);
1985         verify(mMockIkeSessionCreator)
1986                 .createIkeSession(
1987                         eq(mMockContext),
1988                         ikeSessionParamsCaptor.capture(),
1989                         childSessionParamsCaptor.capture(),
1990                         any(Executor.class),
1991                         any(IkeSessionCallback.class),
1992                         any(ChildSessionCallback.class));
1993 
1994         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
1995 
1996         assertNotNull(ikeSessionParams.getIke3gppExtension().getIke3gppParams());
1997 
1998         byte pduSessionIdByte =
1999                 ikeSessionParams.getIke3gppExtension().getIke3gppParams().getPduSessionId();
2000         assertEquals(pduSessionIdByte, pduSessionIdToByte);
2001     }
2002 
2003     @Test
testInvalidNattTimerFromCarrierConfig()2004     public void testInvalidNattTimerFromCarrierConfig() throws Exception {
2005         int nattTimer = 4500; // valid range for natt timer is 0-3600
2006         int defaultNattTimer =
2007                 IwlanCarrierConfig.getDefaultConfigInt(
2008                         CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT);
2009 
2010         IwlanCarrierConfig.putTestConfigInt(
2011                 CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT, nattTimer);
2012 
2013         doReturn(null)
2014                 .when(mMockIkeSessionCreator)
2015                 .createIkeSession(
2016                         eq(mMockContext),
2017                         any(IkeSessionParams.class),
2018                         any(ChildSessionParams.class),
2019                         any(Executor.class),
2020                         any(IkeSessionCallback.class),
2021                         any(ChildSessionCallback.class));
2022 
2023         boolean ret =
2024                 mEpdgTunnelManager.bringUpTunnel(
2025                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
2026                         mMockIwlanTunnelCallback);
2027         assertTrue(ret);
2028         mTestLooper.dispatchAll();
2029 
2030         mEpdgTunnelManager.sendSelectionRequestComplete(
2031                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
2032         mTestLooper.dispatchAll();
2033 
2034         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
2035                 ArgumentCaptor.forClass(IkeSessionParams.class);
2036 
2037         verify(mMockIkeSessionCreator)
2038                 .createIkeSession(
2039                         eq(mMockContext),
2040                         ikeSessionParamsCaptor.capture(),
2041                         any(ChildSessionParams.class),
2042                         any(Executor.class),
2043                         any(IkeSessionCallback.class),
2044                         any(ChildSessionCallback.class));
2045 
2046         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
2047         assertEquals(defaultNattTimer, ikeSessionParams.getNattKeepAliveDelaySeconds());
2048     }
2049 
2050     @Test
testTunnelSetupRequestParams()2051     public void testTunnelSetupRequestParams() throws Exception {
2052         String testApnName = "www.xyz.com";
2053         Inet6Address testAddressV6 = Inet6Address.getByAddress("25.25.25.25", new byte[16], 0);
2054         Inet4Address testAddressV4 = (Inet4Address) Inet4Address.getByName("30.30.30.30");
2055         int pduSessionId = 5;
2056         boolean isRoaming = false;
2057         boolean isEmergency = true;
2058         boolean requestPcscf = true;
2059         int ipv6AddressLen = 64;
2060 
2061         TunnelSetupRequest tsr =
2062                 TunnelSetupRequest.builder()
2063                         .setApnName(testApnName)
2064                         .setApnIpProtocol(ApnSetting.PROTOCOL_IPV4V6)
2065                         .setSrcIpv6Address(testAddressV6)
2066                         .setSrcIpv6AddressPrefixLength(ipv6AddressLen)
2067                         .setSrcIpv4Address(testAddressV4)
2068                         .setPduSessionId(pduSessionId)
2069                         .setIsRoaming(isRoaming)
2070                         .setIsEmergency(isEmergency)
2071                         .setRequestPcscf(requestPcscf)
2072                         .build();
2073 
2074         doReturn(null)
2075                 .when(mMockIkeSessionCreator)
2076                 .createIkeSession(
2077                         eq(mMockContext),
2078                         any(IkeSessionParams.class),
2079                         any(ChildSessionParams.class),
2080                         any(Executor.class),
2081                         any(IkeSessionCallback.class),
2082                         any(ChildSessionCallback.class));
2083 
2084         boolean ret = mEpdgTunnelManager.bringUpTunnel(tsr, mMockIwlanTunnelCallback);
2085         assertTrue(ret);
2086         mTestLooper.dispatchAll();
2087 
2088         // verify isRoaming, isEmergency and Network variables.
2089         verify(mMockEpdgSelector)
2090                 .getValidatedServerList(
2091                         anyInt(),
2092                         anyInt(), // only Ipv6 address is added
2093                         anyInt(),
2094                         eq(isRoaming),
2095                         eq(isEmergency),
2096                         eq(mMockDefaultNetwork),
2097                         any(EpdgSelector.EpdgSelectorCallback.class));
2098 
2099         mEpdgTunnelManager.sendSelectionRequestComplete(
2100                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
2101         mTestLooper.dispatchAll();
2102 
2103         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
2104                 ArgumentCaptor.forClass(IkeSessionParams.class);
2105         ArgumentCaptor<TunnelModeChildSessionParams> childSessionParamsCaptor =
2106                 ArgumentCaptor.forClass(TunnelModeChildSessionParams.class);
2107 
2108         verify(mMockIkeSessionCreator)
2109                 .createIkeSession(
2110                         eq(mMockContext),
2111                         ikeSessionParamsCaptor.capture(),
2112                         childSessionParamsCaptor.capture(),
2113                         any(Executor.class),
2114                         any(IkeSessionCallback.class),
2115                         any(ChildSessionCallback.class));
2116 
2117         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
2118         TunnelModeChildSessionParams childSessionParams = childSessionParamsCaptor.getValue();
2119 
2120         // apnName verification. By default remote identification is type fqdn
2121         IkeFqdnIdentification ikeId =
2122                 (IkeFqdnIdentification) ikeSessionParams.getRemoteIdentification();
2123         assertEquals(testApnName, ikeId.fqdn);
2124 
2125         // verify Network
2126         assertEquals(mMockDefaultNetwork, ikeSessionParams.getNetwork());
2127 
2128         // verify requestPcscf (true) with Apn protocol IPV6
2129         // it should add the pcscf config requests of type ConfigRequestIpv6PcscfServer and
2130         // ConfigRequestIpv4PcscfServer
2131         assertTrue(
2132                 ikeSessionParams.getConfigurationRequests().stream()
2133                         .anyMatch(c -> c instanceof IkeSessionParams.ConfigRequestIpv6PcscfServer));
2134         assertTrue(
2135                 ikeSessionParams.getConfigurationRequests().stream()
2136                         .anyMatch(c -> c instanceof IkeSessionParams.ConfigRequestIpv4PcscfServer));
2137 
2138         // verify pduSessionID
2139         assertEquals(
2140                 pduSessionId,
2141                 ikeSessionParams.getIke3gppExtension().getIke3gppParams().getPduSessionId());
2142 
2143         // verify src ipv6  and src ipv4 address
2144         List<TunnelModeChildSessionParams.TunnelModeChildConfigRequest> configRequests =
2145                 childSessionParams.getConfigurationRequests();
2146         boolean ipv6ConfigRequestPresent = false;
2147         boolean ipv4ConfigRequestPresent = true;
2148         for (TunnelModeChildSessionParams.TunnelModeChildConfigRequest configRequest :
2149                 configRequests) {
2150             if (configRequest
2151                     instanceof
2152                     TunnelModeChildSessionParams.ConfigRequestIpv6Address
2153                                     configRequestIpv6Address) {
2154                 ipv6ConfigRequestPresent = true;
2155                 assertEquals(testAddressV6, configRequestIpv6Address.getAddress());
2156                 assertEquals(
2157                         ipv6AddressLen,
2158                         ((TunnelModeChildSessionParams.ConfigRequestIpv6Address) configRequest)
2159                                 .getPrefixLength());
2160             }
2161             if (configRequest
2162                     instanceof
2163                     TunnelModeChildSessionParams.ConfigRequestIpv4Address
2164                                     configRequestIpv4Address) {
2165                 ipv4ConfigRequestPresent = true;
2166                 assertEquals(testAddressV4, configRequestIpv4Address.getAddress());
2167             }
2168         }
2169         assertTrue(ipv6ConfigRequestPresent);
2170         assertTrue(ipv4ConfigRequestPresent);
2171     }
2172 
2173     @Test
testBringupTunnelFailWithInvalidSimState()2174     public void testBringupTunnelFailWithInvalidSimState() throws Exception {
2175         String testApnName = "www.xyz.com";
2176         IwlanError error = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
2177 
2178         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
2179 
2180         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(DEFAULT_SLOT_INDEX))
2181                 .thenReturn(null);
2182 
2183         boolean ret =
2184                 mEpdgTunnelManager.bringUpTunnel(
2185                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
2186                         mMockIwlanTunnelCallback);
2187         assertTrue(ret);
2188         mTestLooper.dispatchAll();
2189 
2190         mEpdgTunnelManager.sendSelectionRequestComplete(
2191                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
2192         mTestLooper.dispatchAll();
2193 
2194         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
2195     }
2196 
2197     @Test
testBringupTunnelFailWithInvalidNai()2198     public void testBringupTunnelFailWithInvalidNai() throws Exception {
2199         String testApnName = "www.xyz.com";
2200         IwlanError error = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
2201 
2202         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
2203 
2204         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(DEFAULT_SLOT_INDEX))
2205                 .thenReturn(mMockSubscriptionInfo)
2206                 .thenReturn(mMockSubscriptionInfo)
2207                 .thenReturn(null);
2208 
2209         boolean ret =
2210                 mEpdgTunnelManager.bringUpTunnel(
2211                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
2212                         mMockIwlanTunnelCallback);
2213         assertTrue(ret);
2214         mTestLooper.dispatchAll();
2215 
2216         mEpdgTunnelManager.sendSelectionRequestComplete(
2217                 EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
2218         mTestLooper.dispatchAll();
2219 
2220         verify(mMockIwlanTunnelCallback).onClosed(eq(testApnName), eq(error), any());
2221     }
2222 
2223     @Test
testCloseTunnelWithEpdgSelectionIncomplete()2224     public void testCloseTunnelWithEpdgSelectionIncomplete() {
2225         // Bring up tunnel
2226 
2227         boolean ret =
2228                 mEpdgTunnelManager.bringUpTunnel(
2229                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
2230                         mMockIwlanTunnelCallback);
2231         assertTrue(ret);
2232 
2233         // close tunnel when ePDG selection is incomplete
2234         mEpdgTunnelManager.closeTunnel(
2235                 TEST_APN_NAME,
2236                 false /*forceClose*/,
2237                 mMockIwlanTunnelCallback,
2238                 BRINGDOWN_REASON_UNKNOWN);
2239         mTestLooper.dispatchAll();
2240 
2241         ArgumentCaptor<OnClosedMetrics> metricsCaptor =
2242                 ArgumentCaptor.forClass(OnClosedMetrics.class);
2243         verify(mMockIwlanTunnelCallback)
2244                 .onClosed(
2245                         eq(TEST_APN_NAME),
2246                         eq(new IwlanError(IwlanError.NO_ERROR)),
2247                         metricsCaptor.capture());
2248         assertEquals(TEST_APN_NAME, metricsCaptor.getValue().getApnName());
2249         assertNull(metricsCaptor.getValue().getEpdgServerAddress());
2250     }
2251 
2252     @Test
testIgnoreSignalFromObsoleteCallback()2253     public void testIgnoreSignalFromObsoleteCallback() throws Exception {
2254         int transactionId = 0;
2255 
2256         // testApnName with token 0
2257         setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, ++transactionId);
2258         mEpdgTunnelManager.onConnectedToEpdg(true);
2259 
2260         IwlanError error = new IwlanError(mMockIkeException);
2261         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(TEST_APN_NAME), eq(error));
2262 
2263         mEpdgTunnelManager
2264                 .getTmIkeSessionCallback(TEST_APN_NAME, 0 /* token */)
2265                 .onClosedWithException(mMockIkeException);
2266         mTestLooper.dispatchAll();
2267         verify(mMockIwlanTunnelCallback).onClosed(eq(TEST_APN_NAME), eq(error), any());
2268         assertNull(mEpdgTunnelManager.getTunnelConfigForApn(TEST_APN_NAME));
2269 
2270         // testApnName1 with token 1
2271         setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, ++transactionId);
2272         mEpdgTunnelManager.onConnectedToEpdg(true);
2273 
2274         // signal from obsolete callback (token 0), ignore it
2275         reset(mMockIwlanTunnelCallback);
2276         mEpdgTunnelManager
2277                 .getTmIkeSessionCallback(TEST_APN_NAME, 0 /* token */)
2278                 .onClosedWithException(mMockIkeException);
2279         mTestLooper.dispatchAll();
2280         verify(mMockIwlanTunnelCallback, never()).onClosed(eq(TEST_APN_NAME), eq(error), any());
2281         assertNotNull(mEpdgTunnelManager.getTunnelConfigForApn(TEST_APN_NAME));
2282 
2283         // signals from active callback
2284         mEpdgTunnelManager
2285                 .getTmIkeSessionCallback(TEST_APN_NAME, 1 /* token */)
2286                 .onClosedWithException(mMockIkeException);
2287         mTestLooper.dispatchAll();
2288         verify(mMockIwlanTunnelCallback).onClosed(eq(TEST_APN_NAME), eq(error), any());
2289         assertNull(mEpdgTunnelManager.getTunnelConfigForApn(TEST_APN_NAME));
2290     }
2291 
2292     @Test
testBringUpTunnelIpv4Preferred()2293     public void testBringUpTunnelIpv4Preferred() throws Exception {
2294         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
2295 
2296         IwlanCarrierConfig.putTestConfigInt(
2297                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT,
2298                 CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_PREFERRED);
2299 
2300         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
2301         assertTrue(ret);
2302         mTestLooper.dispatchAll();
2303 
2304         verify(mMockEpdgSelector)
2305                 .getValidatedServerList(
2306                         anyInt(),
2307                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
2308                         eq(EpdgSelector.IPV4_PREFERRED),
2309                         eq(false),
2310                         eq(false),
2311                         eq(mMockDefaultNetwork),
2312                         any());
2313     }
2314 
2315     @Test
testBringUpTunnelIpv6Preferred()2316     public void testBringUpTunnelIpv6Preferred() throws Exception {
2317         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
2318 
2319         IwlanCarrierConfig.putTestConfigInt(
2320                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT,
2321                 CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_PREFERRED);
2322 
2323         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
2324         assertTrue(ret);
2325         mTestLooper.dispatchAll();
2326 
2327         verify(mMockEpdgSelector)
2328                 .getValidatedServerList(
2329                         anyInt(),
2330                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
2331                         eq(EpdgSelector.IPV6_PREFERRED),
2332                         eq(false),
2333                         eq(false),
2334                         eq(mMockDefaultNetwork),
2335                         any());
2336     }
2337 
2338     @Test
testBringUpTunnelIpv4Only()2339     public void testBringUpTunnelIpv4Only() throws Exception {
2340         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
2341 
2342         IwlanCarrierConfig.putTestConfigInt(
2343                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT,
2344                 CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_ONLY);
2345 
2346         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
2347         assertTrue(ret);
2348         mTestLooper.dispatchAll();
2349 
2350         verify(mMockEpdgSelector)
2351                 .getValidatedServerList(
2352                         anyInt(),
2353                         eq(EpdgSelector.PROTO_FILTER_IPV4),
2354                         eq(EpdgSelector.SYSTEM_PREFERRED),
2355                         eq(false),
2356                         eq(false),
2357                         eq(mMockDefaultNetwork),
2358                         any());
2359     }
2360 
2361     @Test
testBringUpTunnelIpv6Only()2362     public void testBringUpTunnelIpv6Only() throws Exception {
2363         TunnelSetupRequest TSR =
2364                 getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6);
2365         doReturn(EXPECTED_IPV6_LOCAL_ADDRESSES)
2366                 .when(mEpdgTunnelManager)
2367                 .getAddressForNetwork(any());
2368 
2369         IwlanCarrierConfig.putTestConfigInt(
2370                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT,
2371                 CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_ONLY);
2372 
2373         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
2374         assertTrue(ret);
2375         mTestLooper.dispatchAll();
2376 
2377         verify(mMockEpdgSelector)
2378                 .getValidatedServerList(
2379                         anyInt(),
2380                         eq(EpdgSelector.PROTO_FILTER_IPV6),
2381                         eq(EpdgSelector.SYSTEM_PREFERRED),
2382                         eq(false),
2383                         eq(false),
2384                         eq(mMockDefaultNetwork),
2385                         any());
2386     }
2387 
2388     @Test
testBringUpTunnelIpv6OnlyOnIpv4Wifi()2389     public void testBringUpTunnelIpv6OnlyOnIpv4Wifi() throws Exception {
2390         TunnelSetupRequest TSR =
2391                 getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6);
2392         IwlanError error = new IwlanError(IwlanError.EPDG_ADDRESS_ONLY_IPV6_ALLOWED);
2393         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(TEST_APN_NAME), eq(error));
2394 
2395         IwlanCarrierConfig.putTestConfigInt(
2396                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT,
2397                 CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_ONLY);
2398 
2399         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
2400         assertTrue(ret);
2401         mTestLooper.dispatchAll();
2402 
2403         verify(mMockEpdgSelector, never())
2404                 .getValidatedServerList(
2405                         anyInt(),
2406                         anyInt(),
2407                         anyInt(),
2408                         eq(false),
2409                         eq(false),
2410                         eq(mMockDefaultNetwork),
2411                         any());
2412         verify(mEpdgTunnelManager).reportIwlanError(eq(TEST_APN_NAME), eq(error));
2413         verify(mMockIwlanTunnelCallback).onClosed(eq(TEST_APN_NAME), eq(error), any());
2414     }
2415 
2416     @Test
testBringUpTunnelSystemPreferred()2417     public void testBringUpTunnelSystemPreferred() throws Exception {
2418         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
2419 
2420         IwlanCarrierConfig.putTestConfigInt(
2421                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT,
2422                 CarrierConfigManager.Iwlan.EPDG_ADDRESS_SYSTEM_PREFERRED);
2423 
2424         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
2425         assertTrue(ret);
2426         mTestLooper.dispatchAll();
2427 
2428         verify(mMockEpdgSelector)
2429                 .getValidatedServerList(
2430                         anyInt(),
2431                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
2432                         eq(EpdgSelector.SYSTEM_PREFERRED),
2433                         eq(false),
2434                         eq(false),
2435                         eq(mMockDefaultNetwork),
2436                         any());
2437     }
2438 
2439     @Test
testCloseTunnelWithIkeInitTimeout()2440     public void testCloseTunnelWithIkeInitTimeout() throws Exception {
2441         String testApnName = "www.xyz.com";
2442         IwlanError error = new IwlanError(IwlanError.IKE_INIT_TIMEOUT, mMockIkeIoException);
2443         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
2444 
2445         setupTunnelBringup();
2446 
2447         ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
2448                 ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
2449         verify(mMockIkeSessionCreator, atLeastOnce())
2450                 .createIkeSession(
2451                         eq(mMockContext),
2452                         any(IkeSessionParams.class),
2453                         any(ChildSessionParams.class),
2454                         any(Executor.class),
2455                         ikeSessionCallbackCaptor.capture(),
2456                         any(ChildSessionCallback.class));
2457         ikeSessionCallbackCaptor.getValue().onClosedWithException(mMockIkeIoException);
2458         mTestLooper.dispatchAll();
2459 
2460         verify(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
2461         verify(mMockEpdgSelector)
2462                 .onEpdgConnectionFailed(
2463                         eq(EXPECTED_EPDG_ADDRESSES.get(0)), any(IkeIOException.class));
2464         verify(mMockEpdgSelector, never()).onEpdgConnectedSuccessfully();
2465         verify(mMockIwlanTunnelCallback, atLeastOnce()).onClosed(eq(testApnName), eq(error), any());
2466     }
2467 
2468     @Test
testCloseTunnelWithIkeDpdTimeout()2469     public void testCloseTunnelWithIkeDpdTimeout() throws Exception {
2470         IwlanError error = new IwlanError(IwlanError.IKE_DPD_TIMEOUT, mMockIkeIoException);
2471 
2472         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
2473                 verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME, mMockDefaultNetwork);
2474         ChildSessionCallback childSessionCallback =
2475                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
2476         verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
2477         mEpdgTunnelManager
2478                 .getTmIkeSessionCallback(
2479                         TEST_APN_NAME, mEpdgTunnelManager.getCurrentTokenForApn(TEST_APN_NAME))
2480                 .onClosedWithException(mMockIkeIoException);
2481         mTestLooper.dispatchAll();
2482 
2483         verify(mEpdgTunnelManager, never()).reportIwlanError(eq(TEST_APN_NAME), eq(error));
2484         verify(mMockIwlanTunnelCallback).onClosed(eq(TEST_APN_NAME), eq(error), any());
2485     }
2486 
2487     @Test
testCloseTunnelWithIkeMobilityTimeout()2488     public void testCloseTunnelWithIkeMobilityTimeout() throws Exception {
2489         IwlanError error = new IwlanError(IwlanError.IKE_MOBILITY_TIMEOUT, mMockIkeIoException);
2490 
2491         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
2492                 verifyBringUpTunnelWithDnsQuery(
2493                         TEST_APN_NAME, mMockDefaultNetwork, mMockIkeSession);
2494         ChildSessionCallback childSessionCallback =
2495                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
2496         verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
2497 
2498         Network newNetwork = mock(Network.class);
2499         mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
2500         mTestLooper.dispatchAll();
2501 
2502         mEpdgTunnelManager
2503                 .getTmIkeSessionCallback(
2504                         TEST_APN_NAME, mEpdgTunnelManager.getCurrentTokenForApn(TEST_APN_NAME))
2505                 .onClosedWithException(mMockIkeIoException);
2506         mTestLooper.dispatchAll();
2507 
2508         verify(mMockIkeSession).setNetwork(eq(newNetwork));
2509         verify(mEpdgTunnelManager, never()).reportIwlanError(eq(TEST_APN_NAME), eq(error));
2510         verify(mMockIwlanTunnelCallback).onClosed(eq(TEST_APN_NAME), eq(error), any());
2511     }
2512 
2513     @Test
testUpdateNetworkToOpenedTunnel()2514     public void testUpdateNetworkToOpenedTunnel() throws Exception {
2515         String apnName = "ims";
2516 
2517         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
2518                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork, mMockIkeSession);
2519         ChildSessionCallback childSessionCallback =
2520                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
2521         childSessionCallback.onIpSecTransformCreated(
2522                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
2523         mTestLooper.dispatchAll();
2524 
2525         mEpdgTunnelManager.mEpdgMonitor.onApnConnectToEpdg(
2526                 apnName, InetAddresses.parseNumericAddress(EPDG_ADDRESS));
2527         mEpdgTunnelManager.onConnectedToEpdg(true);
2528         Network newNetwork = mock(Network.class);
2529         mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
2530         mTestLooper.dispatchAll();
2531         verify(mMockIkeSession).setNetwork(eq(newNetwork));
2532     }
2533 
2534     @Test
testUpdateNetworkForIncomingSetupRequest()2535     public void testUpdateNetworkForIncomingSetupRequest() throws Exception {
2536         String apnName = "ims";
2537         Network newNetwork = mock(Network.class);
2538 
2539         mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
2540         mTestLooper.dispatchAll();
2541 
2542         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
2543                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork, mMockIkeSession);
2544         ChildSessionCallback childSessionCallback =
2545                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
2546         childSessionCallback.onIpSecTransformCreated(
2547                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
2548         mTestLooper.dispatchAll();
2549 
2550         verify(mMockEpdgSelector)
2551                 .getValidatedServerList(
2552                         anyInt(), /* transactionId */
2553                         anyInt(), /* filter */
2554                         anyInt(), /* order */
2555                         eq(false), /* isRoaming */
2556                         eq(false), /* isEmergency */
2557                         eq(newNetwork),
2558                         any(EpdgSelector.EpdgSelectorCallback.class));
2559         IkeSessionParams ikeSessionParams =
2560                 ikeSessionArgumentCaptors.mIkeSessionParamsCaptor.getValue();
2561         assertEquals(newNetwork, ikeSessionParams.getNetwork());
2562     }
2563 
2564     @Test
testUpdateNullNetworkToOpenedTunnel()2565     public void testUpdateNullNetworkToOpenedTunnel() throws Exception {
2566         String apnName = "ims";
2567 
2568         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
2569                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork, mMockIkeSession);
2570         ChildSessionCallback childSessionCallback =
2571                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
2572         childSessionCallback.onIpSecTransformCreated(
2573                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
2574         mTestLooper.dispatchAll();
2575 
2576         mEpdgTunnelManager.updateNetwork(null, null);
2577         mTestLooper.dispatchAll();
2578         verify(mMockIkeSession, never()).setNetwork(any());
2579     }
2580 
2581     @Test
testUpdateNullNetworkAndRejectIncomingSetupRequest()2582     public void testUpdateNullNetworkAndRejectIncomingSetupRequest() throws Exception {
2583         String apnName = "ims";
2584 
2585         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(apnName), any(IwlanError.class));
2586 
2587         mEpdgTunnelManager.updateNetwork(null, null);
2588         mTestLooper.dispatchAll();
2589 
2590         mEpdgTunnelManager.bringUpTunnel(
2591                 getBasicTunnelSetupRequest(apnName, ApnSetting.PROTOCOL_IP),
2592                 mMockIwlanTunnelCallback);
2593         mTestLooper.dispatchAll();
2594         verify(mMockIwlanTunnelCallback).onClosed(eq(apnName), any(IwlanError.class), any());
2595     }
2596 
2597     @Test
testUpdateUnreachableLinkProperties()2598     public void testUpdateUnreachableLinkProperties() throws Exception {
2599         String apnName = "ims";
2600 
2601         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
2602                 verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork, mMockIkeSession);
2603         ChildSessionCallback childSessionCallback =
2604                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
2605         childSessionCallback.onIpSecTransformCreated(
2606                 mMockedIpSecTransformIn, IpSecManager.DIRECTION_IN);
2607         mTestLooper.dispatchAll();
2608 
2609         mEpdgTunnelManager.mEpdgMonitor.onApnConnectToEpdg(
2610                 apnName, InetAddresses.parseNumericAddress(EPDG_ADDRESS));
2611         mEpdgTunnelManager.onConnectedToEpdg(true);
2612         Network newNetwork = mock(Network.class);
2613         LinkProperties mockUnreachableLinkProperties = mock(LinkProperties.class);
2614         when(mockUnreachableLinkProperties.isReachable(any())).thenReturn(false);
2615         mEpdgTunnelManager.updateNetwork(newNetwork, mockUnreachableLinkProperties);
2616         mTestLooper.dispatchAll();
2617         verify(mMockIkeSession, never()).setNetwork(eq(newNetwork));
2618 
2619         mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
2620         mTestLooper.dispatchAll();
2621         verify(mMockIkeSession).setNetwork(eq(newNetwork));
2622     }
2623 
2624     @Test
testNetworkValidationSuccess()2625     public void testNetworkValidationSuccess() throws Exception {
2626         String testApnName = "ims";
2627         mEpdgTunnelManager.putApnNameToTunnelConfig(
2628                 testApnName,
2629                 mMockIkeSession,
2630                 mMockIwlanTunnelCallback,
2631                 mMockIpSecTunnelInterface,
2632                 null /* srcIpv6Addr */,
2633                 0 /* srcIPv6AddrPrefixLen */,
2634                 false /* isEmergency */,
2635                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
2636         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
2637 
2638         mEpdgTunnelManager.requestNetworkValidationForApn(testApnName);
2639         mTestLooper.dispatchAll();
2640         verify(mMockIkeSession).requestLivenessCheck();
2641 
2642         int[][] orderedUpdateEvents = {
2643             {
2644                 IkeSessionCallback.LIVENESS_STATUS_ON_DEMAND_STARTED,
2645                 PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS,
2646                 1
2647             },
2648             {
2649                 IkeSessionCallback.LIVENESS_STATUS_ON_DEMAND_ONGOING,
2650                 PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS,
2651                 2
2652             },
2653             {
2654                 IkeSessionCallback.LIVENESS_STATUS_SUCCESS,
2655                 PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS,
2656                 1
2657             },
2658         };
2659 
2660         for (int[] event : orderedUpdateEvents) {
2661             int testedLivenessStatus = event[0];
2662             int expectedNetworkVadlidationState = event[1];
2663             int numOfSameStatus = event[2];
2664             mEpdgTunnelManager
2665                     .getTmIkeSessionCallback(testApnName, token)
2666                     .onLivenessStatusChanged(testedLivenessStatus);
2667             mTestLooper.dispatchAll();
2668             verify(mMockIwlanTunnelCallback, times(numOfSameStatus))
2669                     .onNetworkValidationStatusChanged(
2670                             eq(testApnName), eq(expectedNetworkVadlidationState));
2671         }
2672     }
2673 
2674     @Test
testNetworkValidationFailed()2675     public void testNetworkValidationFailed() throws Exception {
2676         String testApnName = "ims";
2677         mEpdgTunnelManager.putApnNameToTunnelConfig(
2678                 testApnName,
2679                 mMockIkeSession,
2680                 mMockIwlanTunnelCallback,
2681                 mMockIpSecTunnelInterface,
2682                 null /* srcIpv6Addr */,
2683                 0 /* srcIPv6AddrPrefixLen */,
2684                 false /* isEmergency */,
2685                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
2686 
2687         mEpdgTunnelManager.requestNetworkValidationForApn(testApnName);
2688         mTestLooper.dispatchAll();
2689         verify(mMockIkeSession).requestLivenessCheck();
2690 
2691         int[][] orderedUpdateEvents = {
2692             {
2693                 IkeSessionCallback.LIVENESS_STATUS_ON_DEMAND_STARTED,
2694                 PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS,
2695                 1
2696             },
2697             {
2698                 IkeSessionCallback.LIVENESS_STATUS_ON_DEMAND_ONGOING,
2699                 PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS,
2700                 2
2701             },
2702             {
2703                 IkeSessionCallback.LIVENESS_STATUS_FAILURE,
2704                 PreciseDataConnectionState.NETWORK_VALIDATION_FAILURE,
2705                 1
2706             }
2707         };
2708         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
2709 
2710         for (int[] event : orderedUpdateEvents) {
2711             int testedLivenessStatus = event[0];
2712             int expectedNetworkVadlidationState = event[1];
2713             int numOfSameStatus = event[2];
2714             mEpdgTunnelManager
2715                     .getTmIkeSessionCallback(testApnName, token)
2716                     .onLivenessStatusChanged(testedLivenessStatus);
2717             mTestLooper.dispatchAll();
2718             verify(mMockIwlanTunnelCallback, times(numOfSameStatus))
2719                     .onNetworkValidationStatusChanged(
2720                             eq(testApnName), eq(expectedNetworkVadlidationState));
2721         }
2722     }
2723 
2724     @Test
testOnBackgroundLivenessCheckUpdate()2725     public void testOnBackgroundLivenessCheckUpdate() throws Exception {
2726         String testApnName = "ims";
2727         mEpdgTunnelManager.putApnNameToTunnelConfig(
2728                 testApnName,
2729                 mMockIkeSession,
2730                 mMockIwlanTunnelCallback,
2731                 mMockIpSecTunnelInterface,
2732                 null /* srcIpv6Addr */,
2733                 0 /* srcIPv6AddrPrefixLen */,
2734                 false /* isEmergency */,
2735                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
2736         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
2737 
2738         int[][] orderedUpdateEvents = {
2739             {
2740                 IkeSessionCallback.LIVENESS_STATUS_BACKGROUND_STARTED,
2741                 PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS,
2742                 1
2743             },
2744             {
2745                 IkeSessionCallback.LIVENESS_STATUS_BACKGROUND_ONGOING,
2746                 PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS,
2747                 2
2748             },
2749             {
2750                 IkeSessionCallback.LIVENESS_STATUS_SUCCESS,
2751                 PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS,
2752                 1
2753             }
2754         };
2755 
2756         for (int[] event : orderedUpdateEvents) {
2757             int testedLivenessStatus = event[0];
2758             int expectedNetworkVadlidationState = event[1];
2759             int numOfSameStatus = event[2];
2760             mEpdgTunnelManager
2761                     .getTmIkeSessionCallback(testApnName, token)
2762                     .onLivenessStatusChanged(testedLivenessStatus);
2763             mTestLooper.dispatchAll();
2764             verify(mMockIwlanTunnelCallback, times(numOfSameStatus))
2765                     .onNetworkValidationStatusChanged(
2766                             eq(testApnName), eq(expectedNetworkVadlidationState));
2767         }
2768     }
2769 
2770     @Test
testLivenessCheckUpdateWithUnknownStatus()2771     public void testLivenessCheckUpdateWithUnknownStatus() throws Exception {
2772         String testApnName = "ims";
2773         mEpdgTunnelManager.putApnNameToTunnelConfig(
2774                 testApnName,
2775                 mMockIkeSession,
2776                 mMockIwlanTunnelCallback,
2777                 mMockIpSecTunnelInterface,
2778                 null /* srcIpv6Addr */,
2779                 0 /* srcIPv6AddrPrefixLen */,
2780                 false /* isEmergency */,
2781                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
2782         int token = mEpdgTunnelManager.incrementAndGetCurrentTokenForApn(testApnName);
2783         int unknown_liveness_status = 9999;
2784 
2785         mEpdgTunnelManager
2786                 .getTmIkeSessionCallback(testApnName, token)
2787                 .onLivenessStatusChanged(unknown_liveness_status);
2788         mTestLooper.dispatchAll();
2789         verify(mMockIwlanTunnelCallback)
2790                 .onNetworkValidationStatusChanged(
2791                         eq(testApnName), eq(PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS));
2792     }
2793 
2794     @Test
testRequestNetworkValidationWithNoActiveApn()2795     public void testRequestNetworkValidationWithNoActiveApn() {
2796         String testApnName = "ims";
2797         mEpdgTunnelManager.requestNetworkValidationForApn(testApnName);
2798         mTestLooper.dispatchAll();
2799         verify(mMockIkeSession, never()).requestLivenessCheck();
2800     }
2801 
getBasicEmergencyTunnelSetupRequest(String apnName)2802     private TunnelSetupRequest getBasicEmergencyTunnelSetupRequest(String apnName) {
2803         return TunnelSetupRequest.builder()
2804                 .setApnName(apnName)
2805                 .setIsRoaming(false)
2806                 .setIsEmergency(true)
2807                 .setRequestPcscf(true)
2808                 .setApnIpProtocol(ApnSetting.PROTOCOL_IP)
2809                 .setPduSessionId(1)
2810                 .build();
2811     }
2812 
setOneEmeregencyTunnelOpened(String apnName, InetAddress epdgAddress)2813     private void setOneEmeregencyTunnelOpened(String apnName, InetAddress epdgAddress)
2814             throws Exception {
2815         mEpdgTunnelManager.putApnNameToTunnelConfig(
2816                 apnName,
2817                 mMockIkeSession,
2818                 mMockIwlanTunnelCallback,
2819                 mMockIpSecTunnelInterface,
2820                 null /* srcIPv6Addr */,
2821                 0 /* srcIPv6AddrPrefixLen */,
2822                 true /* isEmergency */,
2823                 epdgAddress);
2824         mEpdgTunnelManager.mEpdgMonitor.onApnConnectToEpdg(apnName, epdgAddress);
2825         mEpdgTunnelManager.onConnectedToEpdg(true);
2826     }
2827 
2828     @Test
testEmergencyPdnEstablishWithImsPdn_Success()2829     public void testEmergencyPdnEstablishWithImsPdn_Success() throws Exception {
2830         when(mFakeFeatureFlags.distinctEpdgSelectionForEmergencySessions()).thenReturn(true);
2831         IwlanCarrierConfig.putTestConfigBoolean(
2832                 IwlanCarrierConfig.KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL, true);
2833         String testImsApnName = "testIms";
2834         String testEmergencyApnName = "testSos";
2835         setOneTunnelOpened(testImsApnName);
2836         mEpdgTunnelManager.updateNetwork(mMockDefaultNetwork, mMockLinkProperties);
2837         mTestLooper.dispatchAll();
2838         // Verify IMS PDN established
2839         assertTrue(mEpdgTunnelManager.mEpdgMonitor.hasEpdgConnectedForNormalSession());
2840         assertFalse(mEpdgTunnelManager.mEpdgMonitor.hasSeparateEpdgConnectedForEmergencySession());
2841 
2842         boolean ret =
2843                 mEpdgTunnelManager.bringUpTunnel(
2844                         getBasicEmergencyTunnelSetupRequest(testEmergencyApnName),
2845                         mMockIwlanTunnelCallback);
2846         assertTrue(ret);
2847         mTestLooper.dispatchAll();
2848 
2849         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
2850                 ArgumentCaptor.forClass(IkeSessionParams.class);
2851         verify(mMockIkeSessionCreator)
2852                 .createIkeSession(
2853                         eq(mMockContext),
2854                         ikeSessionParamsCaptor.capture(),
2855                         any(ChildSessionParams.class),
2856                         any(Executor.class),
2857                         any(IkeSessionCallback.class),
2858                         any(ChildSessionCallback.class));
2859         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
2860         assertEquals(EPDG_ADDRESS, ikeSessionParams.getServerHostname());
2861     }
2862 
2863     @Test
testEmergencyPdnFailedEstablishWithImsPdn_establishWithSeparateEpdg()2864     public void testEmergencyPdnFailedEstablishWithImsPdn_establishWithSeparateEpdg()
2865             throws Exception {
2866         when(mFakeFeatureFlags.distinctEpdgSelectionForEmergencySessions()).thenReturn(true);
2867         when(mFakeFeatureFlags.epdgSelectionExcludeFailedIpAddress()).thenReturn(true);
2868         IwlanCarrierConfig.putTestConfigBoolean(
2869                 IwlanCarrierConfig.KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL, true);
2870         assertTrue(
2871                 IwlanCarrierConfig.getConfigBoolean(
2872                         mMockContext,
2873                         DEFAULT_SLOT_INDEX,
2874                         IwlanCarrierConfig.KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL));
2875         String testImsApnName = "testIms";
2876         String testEmergencyApnName = "testSos";
2877 
2878         setOneTunnelOpened(testImsApnName);
2879         mEpdgTunnelManager.updateNetwork(mMockDefaultNetwork, mMockLinkProperties);
2880         mTestLooper.dispatchAll();
2881         // Verify IMS PDN established
2882         assertTrue(mEpdgTunnelManager.mEpdgMonitor.hasEpdgConnectedForNormalSession());
2883         assertFalse(mEpdgTunnelManager.mEpdgMonitor.hasSeparateEpdgConnectedForEmergencySession());
2884 
2885         IwlanError error =
2886                 new IwlanError(IwlanError.IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED);
2887         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testEmergencyApnName), eq(error));
2888 
2889         boolean ret =
2890                 mEpdgTunnelManager.bringUpTunnel(
2891                         getBasicEmergencyTunnelSetupRequest(testEmergencyApnName),
2892                         mMockIwlanTunnelCallback);
2893         assertTrue(ret);
2894         mTestLooper.dispatchAll();
2895 
2896         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
2897                 ArgumentCaptor.forClass(IkeSessionParams.class);
2898         verify(mMockIkeSessionCreator)
2899                 .createIkeSession(
2900                         eq(mMockContext),
2901                         ikeSessionParamsCaptor.capture(),
2902                         any(ChildSessionParams.class),
2903                         any(Executor.class),
2904                         any(IkeSessionCallback.class),
2905                         any(ChildSessionCallback.class));
2906         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
2907         assertEquals(EPDG_ADDRESS, ikeSessionParams.getServerHostname());
2908         assertFalse(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT));
2909 
2910         mEpdgTunnelManager.getTmIkeSessionCallback(testEmergencyApnName, DEFAULT_TOKEN).onClosed();
2911         mTestLooper.dispatchAll();
2912 
2913         ret =
2914                 mEpdgTunnelManager.bringUpTunnel(
2915                         getBasicEmergencyTunnelSetupRequest(testEmergencyApnName),
2916                         mMockIwlanTunnelCallback);
2917         assertTrue(ret);
2918         mTestLooper.dispatchAll();
2919 
2920         mEpdgTunnelManager.sendSelectionRequestComplete(
2921                 EXPECTE_EPDG_ADDRESSES_FOR_EMERGENCY_SESSION,
2922                 new IwlanError(IwlanError.NO_ERROR),
2923                 1);
2924         mTestLooper.dispatchAll();
2925 
2926         verify(mMockIkeSessionCreator, times(2))
2927                 .createIkeSession(
2928                         eq(mMockContext),
2929                         ikeSessionParamsCaptor.capture(),
2930                         any(ChildSessionParams.class),
2931                         any(Executor.class),
2932                         any(IkeSessionCallback.class),
2933                         any(ChildSessionCallback.class));
2934         ikeSessionParams = ikeSessionParamsCaptor.getValue();
2935         assertEquals(SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY, ikeSessionParams.getServerHostname());
2936         assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT));
2937     }
2938 
bringUpImsPdnAndEmergencyPdnWithDifferentEpdgs()2939     private void bringUpImsPdnAndEmergencyPdnWithDifferentEpdgs() throws Exception {
2940         when(mFakeFeatureFlags.distinctEpdgSelectionForEmergencySessions()).thenReturn(true);
2941         String testImsApnName = "testIms";
2942         String testEmergencyApnName = "testSos";
2943         setOneTunnelOpened(testImsApnName);
2944         mEpdgTunnelManager.updateNetwork(mMockDefaultNetwork, mMockLinkProperties);
2945         mTestLooper.dispatchAll();
2946         setOneEmeregencyTunnelOpened(
2947                 testEmergencyApnName,
2948                 InetAddresses.parseNumericAddress(SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY));
2949         mTestLooper.dispatchAll();
2950 
2951         // Verify IMS PDN established on ePDG A, emergency PDN established on ePDG B
2952         assertTrue(mEpdgTunnelManager.mEpdgMonitor.hasEpdgConnectedForNormalSession());
2953         assertEquals(
2954                 InetAddresses.parseNumericAddress(EPDG_ADDRESS),
2955                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
2956         assertTrue(mEpdgTunnelManager.mEpdgMonitor.hasSeparateEpdgConnectedForEmergencySession());
2957         assertEquals(
2958                 InetAddresses.parseNumericAddress(SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY),
2959                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForEmergencySession());
2960     }
2961 
2962     @Test
testMmsPdnEstablishWithEmergencySessionEpdgNotNormalSessionEpdg_Success()2963     public void testMmsPdnEstablishWithEmergencySessionEpdgNotNormalSessionEpdg_Success()
2964             throws Exception {
2965         when(mFakeFeatureFlags.distinctEpdgSelectionForEmergencySessions()).thenReturn(true);
2966         IwlanCarrierConfig.putTestConfigBoolean(
2967                 IwlanCarrierConfig.KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL, true);
2968         String testMmsApnName = "testMms";
2969         bringUpImsPdnAndEmergencyPdnWithDifferentEpdgs();
2970 
2971         boolean ret =
2972                 mEpdgTunnelManager.bringUpTunnel(
2973                         getBasicTunnelSetupRequest(testMmsApnName, ApnSetting.PROTOCOL_IP),
2974                         mMockIwlanTunnelCallback);
2975         assertTrue(ret);
2976         mTestLooper.dispatchAll();
2977 
2978         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
2979                 ArgumentCaptor.forClass(IkeSessionParams.class);
2980         verify(mMockIkeSessionCreator)
2981                 .createIkeSession(
2982                         eq(mMockContext),
2983                         ikeSessionParamsCaptor.capture(),
2984                         any(ChildSessionParams.class),
2985                         any(Executor.class),
2986                         any(IkeSessionCallback.class),
2987                         any(ChildSessionCallback.class));
2988         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
2989         assertEquals(SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY, ikeSessionParams.getServerHostname());
2990     }
2991 
2992     @Test
testImsPdnReestablishWithEpdgForEmergencySession()2993     public void testImsPdnReestablishWithEpdgForEmergencySession() throws Exception {
2994         when(mFakeFeatureFlags.distinctEpdgSelectionForEmergencySessions()).thenReturn(true);
2995         IwlanCarrierConfig.putTestConfigBoolean(
2996                 IwlanCarrierConfig.KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL, true);
2997         String testImsApnName = "testIms";
2998         bringUpImsPdnAndEmergencyPdnWithDifferentEpdgs();
2999 
3000         mEpdgTunnelManager.getTmIkeSessionCallback(testImsApnName, DEFAULT_TOKEN).onClosed();
3001         mEpdgTunnelManager.removeApnNameInTunnelConfig(testImsApnName);
3002         mEpdgTunnelManager.mEpdgMonitor.onApnDisconnectFromEpdg(testImsApnName);
3003         mTestLooper.dispatchAll();
3004 
3005         assertTrue(mEpdgTunnelManager.mEpdgMonitor.hasEpdgConnectedForNormalSession());
3006         assertFalse(mEpdgTunnelManager.mEpdgMonitor.hasSeparateEpdgConnectedForEmergencySession());
3007         assertEquals(
3008                 InetAddresses.parseNumericAddress(SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY),
3009                 mEpdgTunnelManager.mEpdgMonitor.getEpdgAddressForNormalSession());
3010 
3011         boolean ret =
3012                 mEpdgTunnelManager.bringUpTunnel(
3013                         getBasicTunnelSetupRequest(testImsApnName, ApnSetting.PROTOCOL_IP),
3014                         mMockIwlanTunnelCallback);
3015         assertTrue(ret);
3016         mTestLooper.dispatchAll();
3017 
3018         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
3019                 ArgumentCaptor.forClass(IkeSessionParams.class);
3020         verify(mMockIkeSessionCreator)
3021                 .createIkeSession(
3022                         eq(mMockContext),
3023                         ikeSessionParamsCaptor.capture(),
3024                         any(ChildSessionParams.class),
3025                         any(Executor.class),
3026                         any(IkeSessionCallback.class),
3027                         any(ChildSessionCallback.class));
3028         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
3029         assertEquals(SEPARATE_EPDG_ADDRESS_FOR_EMERGENCY, ikeSessionParams.getServerHostname());
3030     }
3031 
3032     @Test
testUnderlyingNetworkValidation_IkeInitTimeout()3033     public void testUnderlyingNetworkValidation_IkeInitTimeout() throws Exception {
3034         when(mMockNetworkCapabilities.hasCapability(
3035                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3036                 .thenReturn(true);
3037         IwlanCarrierConfig.putTestConfigIntArray(
3038                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3039                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_NO_RESPONSE});
3040 
3041         advanceClockByTimeMs(100000);
3042         setupTunnelBringup();
3043         ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
3044                 ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
3045         verify(mMockIkeSessionCreator, atLeastOnce())
3046                 .createIkeSession(
3047                         eq(mMockContext),
3048                         any(IkeSessionParams.class),
3049                         any(ChildSessionParams.class),
3050                         any(Executor.class),
3051                         ikeSessionCallbackCaptor.capture(),
3052                         any(ChildSessionCallback.class));
3053         ikeSessionCallbackCaptor.getValue().onClosedWithException(mMockIkeIoException);
3054         mTestLooper.dispatchAll();
3055 
3056         verify(mMockConnectivityManager)
3057                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3058     }
3059 
3060     @Test
testUnderlyingNetworkValidation_IkeDpdTimeout()3061     public void testUnderlyingNetworkValidation_IkeDpdTimeout() throws Exception {
3062         when(mMockNetworkCapabilities.hasCapability(
3063                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3064                 .thenReturn(true);
3065         IwlanCarrierConfig.putTestConfigIntArray(
3066                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3067                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_NO_RESPONSE});
3068 
3069         advanceClockByTimeMs(100000);
3070         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
3071                 verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME, mMockDefaultNetwork);
3072         ChildSessionCallback childSessionCallback =
3073                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
3074         verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
3075         mEpdgTunnelManager
3076                 .getTmIkeSessionCallback(
3077                         TEST_APN_NAME, mEpdgTunnelManager.getCurrentTokenForApn(TEST_APN_NAME))
3078                 .onClosedWithException(mMockIkeIoException);
3079         mTestLooper.dispatchAll();
3080 
3081         verify(mMockConnectivityManager)
3082                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3083     }
3084 
3085     @Test
testUnderlyingNetworkValidation_IkeMobilityTimeout()3086     public void testUnderlyingNetworkValidation_IkeMobilityTimeout() throws Exception {
3087         when(mMockNetworkCapabilities.hasCapability(
3088                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3089                 .thenReturn(true);
3090         IwlanCarrierConfig.putTestConfigIntArray(
3091                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3092                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_NO_RESPONSE});
3093 
3094         advanceClockByTimeMs(100000);
3095         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
3096                 verifyBringUpTunnelWithDnsQuery(
3097                         TEST_APN_NAME, mMockDefaultNetwork, mMockIkeSession);
3098         ChildSessionCallback childSessionCallback =
3099                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
3100         verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
3101 
3102         Network newNetwork = mock(Network.class);
3103         mEpdgTunnelManager.updateNetwork(newNetwork, mMockLinkProperties);
3104         mTestLooper.dispatchAll();
3105 
3106         mEpdgTunnelManager
3107                 .getTmIkeSessionCallback(
3108                         TEST_APN_NAME, mEpdgTunnelManager.getCurrentTokenForApn(TEST_APN_NAME))
3109                 .onClosedWithException(mMockIkeIoException);
3110         mTestLooper.dispatchAll();
3111 
3112         verify(mMockConnectivityManager).reportNetworkConnectivity(eq(newNetwork), eq(false));
3113     }
3114 
3115     @Test
testUnderlyingNetworkValidation_DnsResolutionFailure()3116     public void testUnderlyingNetworkValidation_DnsResolutionFailure() {
3117         IwlanError error = new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
3118         when(mMockNetworkCapabilities.hasCapability(
3119                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3120                 .thenReturn(true);
3121         IwlanCarrierConfig.putTestConfigIntArray(
3122                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3123                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_NO_RESPONSE});
3124 
3125         advanceClockByTimeMs(100000);
3126         boolean ret =
3127                 mEpdgTunnelManager.bringUpTunnel(
3128                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
3129                         mMockIwlanTunnelCallback);
3130         assertTrue(ret);
3131         mTestLooper.dispatchAll();
3132 
3133         mEpdgTunnelManager.sendSelectionRequestComplete(null, error, 1);
3134         mTestLooper.dispatchAll();
3135 
3136         mEpdgTunnelManager.mEpdgMonitor.onApnDisconnectFromEpdg(TEST_APN_NAME);
3137         mEpdgTunnelManager.onConnectedToEpdg(false);
3138 
3139         verify(mMockConnectivityManager)
3140                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3141     }
3142 
3143     @Test
testUnderlyingNetworkValidation_IkeNetworkLostException()3144     public void testUnderlyingNetworkValidation_IkeNetworkLostException() throws Exception {
3145         when(mMockNetworkCapabilities.hasCapability(
3146                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3147                 .thenReturn(true);
3148         IwlanCarrierConfig.putTestConfigIntArray(
3149                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3150                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_NO_RESPONSE});
3151 
3152         advanceClockByTimeMs(100000);
3153         setupTunnelBringup();
3154         ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
3155                 ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
3156         verify(mMockIkeSessionCreator, atLeastOnce())
3157                 .createIkeSession(
3158                         eq(mMockContext),
3159                         any(IkeSessionParams.class),
3160                         any(ChildSessionParams.class),
3161                         any(Executor.class),
3162                         ikeSessionCallbackCaptor.capture(),
3163                         any(ChildSessionCallback.class));
3164         ikeSessionCallbackCaptor
3165                 .getValue()
3166                 .onClosedWithException(new IkeNetworkLostException(mMockDefaultNetwork));
3167         mTestLooper.dispatchAll();
3168 
3169         verify(mMockConnectivityManager)
3170                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3171     }
3172 
3173     @Test
testUnderlyingNetworkValidation_UnvalidatedNetwork()3174     public void testUnderlyingNetworkValidation_UnvalidatedNetwork() throws Exception {
3175         when(mMockNetworkCapabilities.hasCapability(
3176                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3177                 .thenReturn(false);
3178         IwlanCarrierConfig.putTestConfigIntArray(
3179                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3180                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_NO_RESPONSE});
3181 
3182         advanceClockByTimeMs(100000);
3183         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
3184                 verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME, mMockDefaultNetwork);
3185         ChildSessionCallback childSessionCallback =
3186                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
3187         verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
3188         mEpdgTunnelManager
3189                 .getTmIkeSessionCallback(
3190                         TEST_APN_NAME, mEpdgTunnelManager.getCurrentTokenForApn(TEST_APN_NAME))
3191                 .onClosedWithException(mMockIkeIoException);
3192         mTestLooper.dispatchAll();
3193 
3194         verify(mMockConnectivityManager, never())
3195                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3196     }
3197 
3198     @Test
testUnderlyingNetworkValidation_ConfigDisabled()3199     public void testUnderlyingNetworkValidation_ConfigDisabled() throws Exception {
3200         when(mMockNetworkCapabilities.hasCapability(
3201                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3202                 .thenReturn(true);
3203         IwlanCarrierConfig.putTestConfigIntArray(
3204                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3205                 new int[] {});
3206 
3207         advanceClockByTimeMs(100000);
3208         IkeSessionArgumentCaptors ikeSessionArgumentCaptors =
3209                 verifyBringUpTunnelWithDnsQuery(TEST_APN_NAME, mMockDefaultNetwork);
3210         ChildSessionCallback childSessionCallback =
3211                 ikeSessionArgumentCaptors.mChildSessionCallbackCaptor.getValue();
3212         verifyTunnelOnOpened(TEST_APN_NAME, childSessionCallback);
3213         mEpdgTunnelManager
3214                 .getTmIkeSessionCallback(
3215                         TEST_APN_NAME, mEpdgTunnelManager.getCurrentTokenForApn(TEST_APN_NAME))
3216                 .onClosedWithException(mMockIkeIoException);
3217         mTestLooper.dispatchAll();
3218 
3219         verify(mMockConnectivityManager, never())
3220                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3221     }
3222 
3223     @Test
testMakingCallNetworkValidation_shouldValidate_ifInEventsConfig()3224     public void testMakingCallNetworkValidation_shouldValidate_ifInEventsConfig() {
3225         when(mMockNetworkCapabilities.hasCapability(
3226                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3227                 .thenReturn(true);
3228         IwlanCarrierConfig.putTestConfigIntArray(
3229                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3230                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL});
3231 
3232         advanceClockByTimeMs(100000);
3233         mEpdgTunnelManager.validateUnderlyingNetwork(
3234                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL);
3235         mTestLooper.dispatchAll();
3236 
3237         verify(mMockConnectivityManager, times(1))
3238                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3239     }
3240 
3241     @Test
testMakingCallNetworkValidation_shouldNotValidate_ifNotInEventsConfig()3242     public void testMakingCallNetworkValidation_shouldNotValidate_ifNotInEventsConfig() {
3243         when(mMockNetworkCapabilities.hasCapability(
3244                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3245                 .thenReturn(true);
3246         IwlanCarrierConfig.putTestConfigIntArray(
3247                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3248                 new int[] {});
3249 
3250         advanceClockByTimeMs(100000);
3251         mEpdgTunnelManager.validateUnderlyingNetwork(
3252                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL);
3253         mTestLooper.dispatchAll();
3254 
3255         verify(mMockConnectivityManager, never()).reportNetworkConnectivity(any(), eq(false));
3256     }
3257 
3258     @Test
testScreenOnNetworkValidation_shouldValidate_ifInEventsConfig()3259     public void testScreenOnNetworkValidation_shouldValidate_ifInEventsConfig() {
3260         when(mMockNetworkCapabilities.hasCapability(
3261                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3262                 .thenReturn(true);
3263         IwlanCarrierConfig.putTestConfigIntArray(
3264                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3265                 new int[] {IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON});
3266 
3267         advanceClockByTimeMs(100000);
3268         mEpdgTunnelManager.validateUnderlyingNetwork(
3269                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON);
3270         mTestLooper.dispatchAll();
3271 
3272         verify(mMockConnectivityManager, times(1))
3273                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3274     }
3275 
3276     @Test
testScreenOnNetworkValidation_shouldNotValidate_ifNotInEventsConfig()3277     public void testScreenOnNetworkValidation_shouldNotValidate_ifNotInEventsConfig() {
3278         when(mMockNetworkCapabilities.hasCapability(
3279                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3280                 .thenReturn(true);
3281         IwlanCarrierConfig.putTestConfigIntArray(
3282                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3283                 new int[] {});
3284 
3285         advanceClockByTimeMs(100000);
3286         mEpdgTunnelManager.validateUnderlyingNetwork(
3287                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON);
3288         mTestLooper.dispatchAll();
3289 
3290         verify(mMockConnectivityManager, never()).reportNetworkConnectivity(any(), eq(false));
3291     }
3292 
3293     @Test
testNetworkValidation_shouldNotValidate_ifWithinInterval()3294     public void testNetworkValidation_shouldNotValidate_ifWithinInterval() {
3295         when(mMockNetworkCapabilities.hasCapability(
3296                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3297                 .thenReturn(true);
3298         IwlanCarrierConfig.putTestConfigIntArray(
3299                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3300                 new int[] {
3301                     IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL,
3302                     IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON
3303                 });
3304 
3305         advanceClockByTimeMs(100000);
3306         mEpdgTunnelManager.validateUnderlyingNetwork(
3307                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL);
3308         mTestLooper.dispatchAll();
3309         verify(mMockConnectivityManager, times(1))
3310                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3311 
3312         advanceClockByTimeMs(1000);
3313         // Since last validation passed 1s, but interval is 10s, should not trigger validation
3314         mEpdgTunnelManager.validateUnderlyingNetwork(
3315                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL);
3316         // Different validation event validation interval are shared, should not trigger validation
3317         mEpdgTunnelManager.validateUnderlyingNetwork(
3318                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON);
3319         mTestLooper.dispatchAll();
3320         verify(mMockConnectivityManager, times(1))
3321                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3322 
3323         advanceClockByTimeMs(20000);
3324         // Since last validation passed 20s, >= interval 10s, should trigger validation
3325         mEpdgTunnelManager.validateUnderlyingNetwork(
3326                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL);
3327         mTestLooper.dispatchAll();
3328         verify(mMockConnectivityManager, times(2))
3329                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3330     }
3331 
verifyValidationMetricsAtom( MetricsAtom metricsAtom, int triggerReason, int validationResult, int transportType, int duration)3332     private void verifyValidationMetricsAtom(
3333             MetricsAtom metricsAtom,
3334             int triggerReason,
3335             int validationResult,
3336             int transportType,
3337             int duration) {
3338         assertEquals(
3339                 IwlanStatsLog.IWLAN_UNDERLYING_NETWORK_VALIDATION_RESULT_REPORTED,
3340                 metricsAtom.getMessageId());
3341         assertEquals(triggerReason, metricsAtom.getTriggerReason());
3342         assertEquals(validationResult, metricsAtom.getValidationResult());
3343         assertEquals(transportType, metricsAtom.getValidationTransportType());
3344         assertEquals(duration, metricsAtom.getValidationDurationMills());
3345     }
3346 
createConnectivityReport(Network network, int validationResult)3347     private ConnectivityReport createConnectivityReport(Network network, int validationResult) {
3348         PersistableBundle bundle = new PersistableBundle();
3349         bundle.putInt(ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT, validationResult);
3350         return new ConnectivityReport(
3351                 network, /* reportTimestamp */
3352                 0,
3353                 new LinkProperties(),
3354                 new NetworkCapabilities(),
3355                 bundle);
3356     }
3357 
3358     @Test
testReportValidationMetricsAtom_Validated()3359     public void testReportValidationMetricsAtom_Validated() {
3360         ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback callback =
3361                 mConnectivityDiagnosticsCallbackArgumentCaptor.getValue();
3362         when(mMockNetworkCapabilities.hasCapability(
3363                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3364                 .thenReturn(true);
3365         when(mMockNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
3366                 .thenReturn(true);
3367         IwlanCarrierConfig.putTestConfigIntArray(
3368                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3369                 new int[] {
3370                     IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL,
3371                     IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON
3372                 });
3373 
3374         advanceClockByTimeMs(100000);
3375         mEpdgTunnelManager.validateUnderlyingNetwork(
3376                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL);
3377         mTestLooper.dispatchAll();
3378         verify(mMockConnectivityManager, times(1))
3379                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3380 
3381         MetricsAtom metricsAtom = mEpdgTunnelManager.getValidationMetricsAtom(mMockDefaultNetwork);
3382         advanceClockByTimeMs(1000);
3383         callback.onConnectivityReportAvailable(
3384                 createConnectivityReport(
3385                         mMockDefaultNetwork, ConnectivityReport.NETWORK_VALIDATION_RESULT_VALID));
3386 
3387         verifyValidationMetricsAtom(
3388                 metricsAtom,
3389                 NETWORK_VALIDATION_EVENT_MAKING_CALL,
3390                 NETWORK_VALIDATION_RESULT_VALID,
3391                 NETWORK_VALIDATION_TRANSPORT_TYPE_WIFI,
3392                 /* duration= */ 1000);
3393     }
3394 
3395     @Test
testReportValidationMetricsAtom_NotValidated()3396     public void testReportValidationMetricsAtom_NotValidated() {
3397         ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback callback =
3398                 mConnectivityDiagnosticsCallbackArgumentCaptor.getValue();
3399         when(mMockNetworkCapabilities.hasCapability(
3400                         eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
3401                 .thenReturn(true);
3402         when(mMockNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
3403                 .thenReturn(true);
3404         IwlanCarrierConfig.putTestConfigIntArray(
3405                 IwlanCarrierConfig.KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY,
3406                 new int[] {
3407                     IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL,
3408                     IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON
3409                 });
3410 
3411         advanceClockByTimeMs(100000);
3412         mEpdgTunnelManager.validateUnderlyingNetwork(
3413                 IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON);
3414         mTestLooper.dispatchAll();
3415         verify(mMockConnectivityManager, times(1))
3416                 .reportNetworkConnectivity(eq(mMockDefaultNetwork), eq(false));
3417 
3418         MetricsAtom metricsAtom = mEpdgTunnelManager.getValidationMetricsAtom(mMockDefaultNetwork);
3419         advanceClockByTimeMs(1000);
3420         callback.onConnectivityReportAvailable(
3421                 createConnectivityReport(
3422                         mMockDefaultNetwork, ConnectivityReport.NETWORK_VALIDATION_RESULT_INVALID));
3423 
3424         verifyValidationMetricsAtom(
3425                 metricsAtom,
3426                 NETWORK_VALIDATION_EVENT_SCREEN_ON,
3427                 NETWORK_VALIDATION_RESULT_INVALID,
3428                 NETWORK_VALIDATION_TRANSPORT_TYPE_CELLULAR,
3429                 /* duration= */ 1000);
3430     }
3431 
3432     @Test
testClose()3433     public void testClose() {
3434         ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback callback =
3435                 mConnectivityDiagnosticsCallbackArgumentCaptor.getValue();
3436         mEpdgTunnelManager.close();
3437         verify(mMockConnectivityDiagnosticsManager, times(1))
3438                 .unregisterConnectivityDiagnosticsCallback(eq(callback));
3439     }
3440 }
3441