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