• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
20 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
21 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
22 
23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotEquals;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertThrows;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.Matchers.isNull;
32 import static org.mockito.Mockito.any;
33 import static org.mockito.Mockito.anyBoolean;
34 import static org.mockito.Mockito.anyInt;
35 import static org.mockito.Mockito.atLeastOnce;
36 import static org.mockito.Mockito.clearInvocations;
37 import static org.mockito.Mockito.doNothing;
38 import static org.mockito.Mockito.doReturn;
39 import static org.mockito.Mockito.eq;
40 import static org.mockito.Mockito.mock;
41 import static org.mockito.Mockito.never;
42 import static org.mockito.Mockito.spy;
43 import static org.mockito.Mockito.timeout;
44 import static org.mockito.Mockito.times;
45 import static org.mockito.Mockito.verify;
46 import static org.mockito.Mockito.when;
47 
48 import android.content.ContentResolver;
49 import android.content.Context;
50 import android.net.ConnectivityManager;
51 import android.net.ConnectivityManager.NetworkCallback;
52 import android.net.LinkAddress;
53 import android.net.LinkProperties;
54 import android.net.Network;
55 import android.net.NetworkCapabilities;
56 import android.net.TelephonyNetworkSpecifier;
57 import android.net.ipsec.ike.exceptions.IkeInternalException;
58 import android.net.vcn.VcnTransportInfo;
59 import android.os.test.TestLooper;
60 import android.telephony.AccessNetworkConstants.AccessNetworkType;
61 import android.telephony.DataFailCause;
62 import android.telephony.SubscriptionInfo;
63 import android.telephony.SubscriptionManager;
64 import android.telephony.TelephonyManager;
65 import android.telephony.data.ApnSetting;
66 import android.telephony.data.DataCallResponse;
67 import android.telephony.data.DataProfile;
68 import android.telephony.data.DataService;
69 import android.telephony.data.DataServiceCallback;
70 import android.telephony.data.IDataServiceCallback;
71 import android.telephony.ims.ImsManager;
72 import android.telephony.ims.ImsMmTelManager;
73 
74 import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider;
75 import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider.IwlanTunnelCallback;
76 import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider.TunnelState;
77 import com.google.android.iwlan.epdg.EpdgSelector;
78 import com.google.android.iwlan.epdg.EpdgTunnelManager;
79 import com.google.android.iwlan.epdg.TunnelLinkProperties;
80 import com.google.android.iwlan.epdg.TunnelLinkPropertiesTest;
81 import com.google.android.iwlan.epdg.TunnelSetupRequest;
82 import com.google.android.iwlan.proto.MetricsAtom;
83 
84 import org.junit.After;
85 import org.junit.Before;
86 import org.junit.Test;
87 import org.mockito.ArgumentCaptor;
88 import org.mockito.Mock;
89 import org.mockito.MockitoAnnotations;
90 import org.mockito.MockitoSession;
91 import org.mockito.quality.Strictness;
92 
93 import java.lang.reflect.Method;
94 import java.net.Inet4Address;
95 import java.net.Inet6Address;
96 import java.net.InetAddress;
97 import java.util.ArrayList;
98 import java.util.Calendar;
99 import java.util.Collections;
100 import java.util.Date;
101 import java.util.List;
102 import java.util.LongSummaryStatistics;
103 import java.util.concurrent.CountDownLatch;
104 import java.util.concurrent.TimeUnit;
105 
106 public class IwlanDataServiceTest {
107     private static final int DEFAULT_SLOT_INDEX = 0;
108     private static final int DEFAULT_SUB_INDEX = 0;
109     private static final int INVALID_SUB_INDEX = -1;
110     private static final int LINK_MTU = 1280;
111     private static final String TEST_APN_NAME = "ims";
112     private static final String IP_ADDRESS = "192.0.2.1";
113     private static final String DNS_ADDRESS = "8.8.8.8";
114     private static final String GATEWAY_ADDRESS = "0.0.0.0";
115     private static final String PSCF_ADDRESS = "10.159.204.230";
116     private static final String INTERFACE_NAME = "ipsec6";
117 
118     @Mock private Context mMockContext;
119     @Mock private SubscriptionManager mMockSubscriptionManager;
120     @Mock private SubscriptionInfo mMockSubscriptionInfo;
121     @Mock private ContentResolver mMockContentResolver;
122     @Mock private ConnectivityManager mMockConnectivityManager;
123     @Mock private DataServiceCallback mMockDataServiceCallback;
124     @Mock private EpdgTunnelManager mMockEpdgTunnelManager;
125     @Mock private IwlanDataServiceProvider mMockIwlanDataServiceProvider;
126     @Mock private Network mMockNetwork;
127     @Mock private TunnelLinkProperties mMockTunnelLinkProperties;
128     @Mock private ErrorPolicyManager mMockErrorPolicyManager;
129     @Mock private ImsManager mMockImsManager;
130     @Mock private ImsMmTelManager mMockImsMmTelManager;
131     @Mock private TelephonyManager mMockTelephonyManager;
132     @Mock private EpdgSelector mMockEpdgSelector;
133     @Mock private LinkAddress mMockIPv4LinkAddress;
134     @Mock private LinkAddress mMockIPv6LinkAddress;
135     @Mock private Inet4Address mMockInet4Address;
136     @Mock private Inet6Address mMockInet6Address;
137 
138     MockitoSession mStaticMockSession;
139 
140     private LinkProperties mLinkProperties;
141     private List<DataCallResponse> mResultDataCallList;
142     private @DataServiceCallback.ResultCode int mResultCode;
143     private CountDownLatch latch;
144     private IwlanDataService mIwlanDataService;
145     private IwlanDataServiceProvider mSpyIwlanDataServiceProvider;
146     private TestLooper mTestLooper = new TestLooper();
147     private long mMockedCalendarTime;
148     private ArgumentCaptor<NetworkCallback> mNetworkCallbackCaptor =
149             ArgumentCaptor.forClass(NetworkCallback.class);
150 
151     private final class IwlanDataServiceCallback extends IDataServiceCallback.Stub {
152 
153         private final String mTag;
154 
IwlanDataServiceCallback(String tag)155         IwlanDataServiceCallback(String tag) {
156             mTag = tag;
157         }
158 
159         @Override
onSetupDataCallComplete( @ataServiceCallback.ResultCode int resultCode, DataCallResponse response)160         public void onSetupDataCallComplete(
161                 @DataServiceCallback.ResultCode int resultCode, DataCallResponse response) {}
162 
163         @Override
onDeactivateDataCallComplete(@ataServiceCallback.ResultCode int resultCode)164         public void onDeactivateDataCallComplete(@DataServiceCallback.ResultCode int resultCode) {}
165 
166         @Override
onSetInitialAttachApnComplete(@ataServiceCallback.ResultCode int resultCode)167         public void onSetInitialAttachApnComplete(@DataServiceCallback.ResultCode int resultCode) {}
168 
169         @Override
onSetDataProfileComplete(@ataServiceCallback.ResultCode int resultCode)170         public void onSetDataProfileComplete(@DataServiceCallback.ResultCode int resultCode) {}
171 
172         @Override
onRequestDataCallListComplete( @ataServiceCallback.ResultCode int resultCode, List<DataCallResponse> dataCallList)173         public void onRequestDataCallListComplete(
174                 @DataServiceCallback.ResultCode int resultCode,
175                 List<DataCallResponse> dataCallList) {
176             mResultCode = resultCode;
177             mResultDataCallList = new ArrayList<DataCallResponse>(dataCallList);
178             latch.countDown();
179         }
180 
181         @Override
onDataCallListChanged(List<DataCallResponse> dataCallList)182         public void onDataCallListChanged(List<DataCallResponse> dataCallList) {}
183 
184         @Override
onHandoverStarted(@ataServiceCallback.ResultCode int result)185         public void onHandoverStarted(@DataServiceCallback.ResultCode int result) {}
186 
187         @Override
onHandoverCancelled(@ataServiceCallback.ResultCode int result)188         public void onHandoverCancelled(@DataServiceCallback.ResultCode int result) {}
189 
190         @Override
onApnUnthrottled(String apn)191         public void onApnUnthrottled(String apn) {}
192 
193         @Override
onDataProfileUnthrottled(DataProfile dataProfile)194         public void onDataProfileUnthrottled(DataProfile dataProfile) {}
195     }
196 
197     @Before
setUp()198     public void setUp() throws Exception {
199         MockitoAnnotations.initMocks(this);
200 
201         mStaticMockSession =
202                 mockitoSession()
203                         .mockStatic(EpdgSelector.class)
204                         .mockStatic(EpdgTunnelManager.class)
205                         .mockStatic(ErrorPolicyManager.class)
206                         .mockStatic(IwlanBroadcastReceiver.class)
207                         .mockStatic(SubscriptionManager.class)
208                         .strictness(Strictness.LENIENT)
209                         .startMocking();
210 
211         when(mMockContext.getSystemService(eq(ConnectivityManager.class)))
212                 .thenReturn(mMockConnectivityManager);
213 
214         when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
215                 .thenReturn(mMockSubscriptionManager);
216 
217         doNothing()
218                 .when(mMockConnectivityManager)
219                 .registerSystemDefaultNetworkCallback(mNetworkCallbackCaptor.capture(), any());
220 
221         when(EpdgTunnelManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX))
222                 .thenReturn(mMockEpdgTunnelManager);
223         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt()))
224                 .thenReturn(mMockSubscriptionInfo);
225         when(mMockSubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DEFAULT_SUB_INDEX);
226         when(mMockSubscriptionManager.getSlotIndex(DEFAULT_SUB_INDEX))
227                 .thenReturn(DEFAULT_SLOT_INDEX);
228         when(mMockSubscriptionManager.getSlotIndex(DEFAULT_SUB_INDEX + 1))
229                 .thenReturn(DEFAULT_SLOT_INDEX + 1);
230 
231         when(mMockSubscriptionInfo.getSubscriptionId()).thenReturn(DEFAULT_SUB_INDEX);
232 
233         when(mMockContext.getSystemService(eq(TelephonyManager.class)))
234                 .thenReturn(mMockTelephonyManager);
235 
236         when(mMockTelephonyManager.createForSubscriptionId(eq(DEFAULT_SUB_INDEX)))
237                 .thenReturn(mMockTelephonyManager);
238 
239         when(mMockTelephonyManager.isNetworkRoaming()).thenReturn(false);
240 
241         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
242 
243         when(mMockContext.getSystemService(eq(ImsManager.class))).thenReturn(mMockImsManager);
244 
245         when(mMockImsManager.getImsMmTelManager(anyInt())).thenReturn(mMockImsMmTelManager);
246 
247         when(mMockImsMmTelManager.isVoWiFiSettingEnabled()).thenReturn(false);
248 
249         when(EpdgSelector.getSelectorInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
250                 .thenReturn(mMockEpdgSelector);
251 
252         when(mMockIPv4LinkAddress.getAddress()).thenReturn(mMockInet4Address);
253         when(mMockIPv6LinkAddress.getAddress()).thenReturn(mMockInet6Address);
254 
255         mIwlanDataService = spy(new IwlanDataService());
256         // Injects the test looper into the IwlanDataServiceHandler
257         doReturn(mTestLooper.getLooper()).when(mIwlanDataService).getLooper();
258         mIwlanDataService.setAppContext(mMockContext);
259         mSpyIwlanDataServiceProvider =
260                 spy(
261                         (IwlanDataServiceProvider)
262                                 mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX));
263         mTestLooper.dispatchAll();
264 
265         when(Calendar.getInstance().getTime()).thenAnswer(i -> mMockedCalendarTime);
266 
267         mLinkProperties = new LinkProperties();
268         mLinkProperties.setInterfaceName("wlan0");
269         mLinkProperties.addLinkAddress(mMockIPv4LinkAddress);
270 
271         when(mMockConnectivityManager.getLinkProperties(eq(mMockNetwork)))
272                 .thenReturn(mLinkProperties);
273     }
274 
275     @After
cleanUp()276     public void cleanUp() throws Exception {
277         mStaticMockSession.finishMocking();
278         mSpyIwlanDataServiceProvider.close();
279         mTestLooper.dispatchAll();
280         if (mIwlanDataService != null) {
281             mIwlanDataService.onDestroy();
282         }
283     }
284 
createMockNetwork(LinkProperties linkProperties)285     public Network createMockNetwork(LinkProperties linkProperties) {
286         Network network = mock(Network.class);
287         when(mMockConnectivityManager.getLinkProperties(eq(network))).thenReturn(linkProperties);
288         return network;
289     }
290 
getNetworkMonitorCallback()291     private NetworkCallback getNetworkMonitorCallback() {
292         return mNetworkCallbackCaptor.getValue();
293     }
294 
onSystemDefaultNetworkConnected( Network network, LinkProperties linkProperties, int transportType, int subId)295     private void onSystemDefaultNetworkConnected(
296             Network network, LinkProperties linkProperties, int transportType, int subId) {
297         NetworkCapabilities nc =
298                 prepareNetworkCapabilitiesForTest(
299                         transportType,
300                         subId /* unused if transportType is TRANSPORT_WIFI */,
301                         false /* isVcn */);
302         NetworkCallback networkMonitorCallback = getNetworkMonitorCallback();
303         networkMonitorCallback.onCapabilitiesChanged(network, nc);
304         networkMonitorCallback.onLinkPropertiesChanged(network, linkProperties);
305         mTestLooper.dispatchAll();
306     }
307 
onSystemDefaultNetworkConnected(int transportType)308     private void onSystemDefaultNetworkConnected(int transportType) {
309         Network newNetwork = createMockNetwork(mLinkProperties);
310         onSystemDefaultNetworkConnected(
311                 newNetwork, mLinkProperties, transportType, DEFAULT_SUB_INDEX);
312     }
313 
onSystemDefaultNetworkLost()314     private void onSystemDefaultNetworkLost() {
315         NetworkCallback networkMonitorCallback = getNetworkMonitorCallback();
316         networkMonitorCallback.onLost(mMockNetwork);
317         mTestLooper.dispatchAll();
318     }
319 
320     @Test
testWifiOnConnected()321     public void testWifiOnConnected() {
322         onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
323         assertTrue(
324                 mIwlanDataService.isNetworkConnected(
325                         false /* isActiveDataOnOtherSub */, false /* isCstEnabled */));
326     }
327 
328     @Test
testWifiOnLost()329     public void testWifiOnLost() {
330         when(mMockIwlanDataServiceProvider.getSlotIndex()).thenReturn(DEFAULT_SLOT_INDEX + 1);
331         mIwlanDataService.addIwlanDataServiceProvider(mMockIwlanDataServiceProvider);
332 
333         onSystemDefaultNetworkLost();
334         assertFalse(
335                 mIwlanDataService.isNetworkConnected(
336                         false /* isActiveDataOnOtherSub */, false /* isCstEnabled */));
337         verify(mMockIwlanDataServiceProvider).forceCloseTunnelsInDeactivatingState();
338         mIwlanDataService.removeDataServiceProvider(mMockIwlanDataServiceProvider);
339         mTestLooper.dispatchAll();
340     }
341 
342     @Test
testWifiOnReconnected()343     public void testWifiOnReconnected() {
344         Network newNetwork = createMockNetwork(mLinkProperties);
345         onSystemDefaultNetworkConnected(
346                 newNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
347         verify(mMockEpdgTunnelManager, times(1)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
348 
349         onSystemDefaultNetworkLost();
350         onSystemDefaultNetworkConnected(
351                 newNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
352         verify(mMockEpdgTunnelManager, times(2)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
353     }
354 
355     @Test
testOnLinkPropertiesChangedForConnectedNetwork()356     public void testOnLinkPropertiesChangedForConnectedNetwork() {
357         NetworkCallback networkCallback = getNetworkMonitorCallback();
358         onSystemDefaultNetworkConnected(
359                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
360 
361         clearInvocations(mMockEpdgTunnelManager);
362 
363         LinkProperties newLinkProperties = new LinkProperties(mLinkProperties);
364         newLinkProperties.setInterfaceName("wlan0");
365         newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
366 
367         networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
368         verify(mMockEpdgTunnelManager, times(1))
369                 .updateNetwork(eq(mMockNetwork), eq(newLinkProperties));
370     }
371 
372     @Test
testOnLinkPropertiesChangedForNonConnectedNetwork()373     public void testOnLinkPropertiesChangedForNonConnectedNetwork() {
374         NetworkCallback networkCallback = getNetworkMonitorCallback();
375         onSystemDefaultNetworkConnected(
376                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
377 
378         clearInvocations(mMockEpdgTunnelManager);
379 
380         LinkProperties newLinkProperties = new LinkProperties();
381         newLinkProperties.setInterfaceName("wlan0");
382         newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
383         Network newNetwork = createMockNetwork(newLinkProperties);
384 
385         networkCallback.onLinkPropertiesChanged(newNetwork, newLinkProperties);
386         verify(mMockEpdgTunnelManager, never())
387                 .updateNetwork(eq(newNetwork), any(LinkProperties.class));
388     }
389 
390     @Test
testOnLinkPropertiesChangedWithClatInstalled()391     public void testOnLinkPropertiesChangedWithClatInstalled() throws Exception {
392         NetworkCallback networkCallback = getNetworkMonitorCallback();
393         mLinkProperties.setLinkAddresses(
394                 new ArrayList<>(Collections.singletonList(mMockIPv6LinkAddress)));
395         onSystemDefaultNetworkConnected(
396                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
397 
398         clearInvocations(mMockEpdgTunnelManager);
399 
400         // LinkProperties#addStackedLink() is marked with @UnsupportedAppUsage
401         LinkProperties newLinkProperties = new LinkProperties(mLinkProperties);
402         newLinkProperties.setInterfaceName("wlan0");
403         LinkProperties stackedLink = new LinkProperties();
404         stackedLink.setInterfaceName("v4-wlan0");
405         stackedLink.addLinkAddress(mMockIPv4LinkAddress);
406         Class<?>[] parameterTypes = new Class<?>[] {LinkProperties.class};
407         Object[] args = new Object[] {stackedLink};
408         callUnsupportedAppUsageMethod(newLinkProperties, "addStackedLink", parameterTypes, args);
409         assertNotEquals(mLinkProperties, newLinkProperties);
410 
411         networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
412         verify(mMockEpdgTunnelManager, times(1))
413                 .updateNetwork(eq(mMockNetwork), eq(newLinkProperties));
414     }
415 
416     @Test
testOnLinkPropertiesChangedForBringingUpIkeSession()417     public void testOnLinkPropertiesChangedForBringingUpIkeSession() {
418         DataProfile dp = buildImsDataProfile();
419 
420         NetworkCallback networkCallback = getNetworkMonitorCallback();
421         onSystemDefaultNetworkConnected(
422                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
423 
424         clearInvocations(mMockEpdgTunnelManager);
425 
426         mSpyIwlanDataServiceProvider.setTunnelState(
427                 dp,
428                 mMockDataServiceCallback,
429                 TunnelState.TUNNEL_IN_BRINGUP,
430                 null, /* linkProperties */
431                 false /* isHandover */,
432                 1 /* pduSessionId */,
433                 true /* isImsOrEmergency */);
434 
435         LinkProperties newLinkProperties = new LinkProperties(mLinkProperties);
436         newLinkProperties.setInterfaceName("wlan0");
437         newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
438 
439         networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
440         verify(mMockEpdgTunnelManager, times(1))
441                 .updateNetwork(eq(mMockNetwork), eq(newLinkProperties));
442         verify(mMockEpdgTunnelManager, never()).closeTunnel(any(), anyBoolean(), any(), any());
443     }
444 
445     @Test
testNetworkNotConnectedWithCellularOnSameSubAndCrossSimEnabled()446     public void testNetworkNotConnectedWithCellularOnSameSubAndCrossSimEnabled()
447             throws InterruptedException {
448         NetworkCapabilities nc =
449                 prepareNetworkCapabilitiesForTest(
450                         TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
451         getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
452 
453         boolean isActiveDataOnOtherSub =
454                 mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
455 
456         assertFalse(isActiveDataOnOtherSub);
457         assertFalse(
458                 mIwlanDataService.isNetworkConnected(
459                         isActiveDataOnOtherSub, true /* isCstEnabled */));
460     }
461 
462     @Test
testCrossSimNetworkConnectedWithCellularOnDifferentSub()463     public void testCrossSimNetworkConnectedWithCellularOnDifferentSub()
464             throws InterruptedException {
465         NetworkCapabilities nc =
466                 prepareNetworkCapabilitiesForTest(
467                         TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, false /* isVcn */);
468         getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
469 
470         boolean isActiveDataOnOtherSub =
471                 mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
472 
473         assertTrue(isActiveDataOnOtherSub);
474         assertTrue(
475                 mIwlanDataService.isNetworkConnected(
476                         isActiveDataOnOtherSub, true /* isCstEnabled */));
477     }
478 
479     @Test
testCrossSimNetworkConnectedWithVcnCellularOnDifferentSub()480     public void testCrossSimNetworkConnectedWithVcnCellularOnDifferentSub()
481             throws InterruptedException {
482         NetworkCapabilities nc =
483                 prepareNetworkCapabilitiesForTest(
484                         TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, true /* isVcn */);
485         getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
486 
487         boolean isActiveDataOnOtherSub =
488                 mIwlanDataService.isActiveDataOnOtherSub(DEFAULT_SLOT_INDEX);
489 
490         assertTrue(isActiveDataOnOtherSub);
491         assertTrue(
492                 mIwlanDataService.isNetworkConnected(
493                         isActiveDataOnOtherSub, true /* isCstEnabled */));
494     }
495 
496     @Test
testOnCrossSimCallingEnable_doNotUpdateTunnelManagerIfCellularDataOnSameSub()497     public void testOnCrossSimCallingEnable_doNotUpdateTunnelManagerIfCellularDataOnSameSub()
498             throws Exception {
499         when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
500 
501         Network newNetwork = createMockNetwork(mLinkProperties);
502         onSystemDefaultNetworkConnected(
503                 newNetwork, mLinkProperties, TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX);
504 
505         mIwlanDataService
506                 .mIwlanDataServiceHandler
507                 .obtainMessage(
508                         IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT,
509                         DEFAULT_SLOT_INDEX,
510                         0 /* unused */)
511                 .sendToTarget();
512         mTestLooper.dispatchAll();
513         verify(mMockEpdgTunnelManager, never())
514                 .updateNetwork(eq(newNetwork), any(LinkProperties.class));
515     }
516 
517     @Test
testOnCrossSimCallingEnable_updateTunnelManagerIfCellularDataOnDifferentSub()518     public void testOnCrossSimCallingEnable_updateTunnelManagerIfCellularDataOnDifferentSub()
519             throws Exception {
520         when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
521 
522         Network newNetwork = createMockNetwork(mLinkProperties);
523         onSystemDefaultNetworkConnected(
524                 newNetwork, mLinkProperties, TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1);
525         verify(mMockEpdgTunnelManager, times(1)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
526 
527         mIwlanDataService
528                 .mIwlanDataServiceHandler
529                 .obtainMessage(
530                         IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT,
531                         DEFAULT_SLOT_INDEX,
532                         0 /* unused */)
533                 .sendToTarget();
534         mTestLooper.dispatchAll();
535         verify(mMockEpdgTunnelManager, times(2)).updateNetwork(eq(newNetwork), eq(mLinkProperties));
536     }
537 
538     @Test
testOnCrossSimCallingEnable_doNotUpdateTunnelManagerIfNoNetwork()539     public void testOnCrossSimCallingEnable_doNotUpdateTunnelManagerIfNoNetwork() throws Exception {
540         when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
541         onSystemDefaultNetworkLost();
542 
543         mIwlanDataService
544                 .mIwlanDataServiceHandler
545                 .obtainMessage(
546                         IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT,
547                         DEFAULT_SLOT_INDEX,
548                         0 /* unused */)
549                 .sendToTarget();
550         mTestLooper.dispatchAll();
551         verify(mMockEpdgTunnelManager, never())
552                 .updateNetwork(any(Network.class), any(LinkProperties.class));
553     }
554 
555     @Test
testOnEthernetConnection_doNotUpdateTunnelManager()556     public void testOnEthernetConnection_doNotUpdateTunnelManager() throws Exception {
557         Network newNetwork = createMockNetwork(mLinkProperties);
558         onSystemDefaultNetworkConnected(
559                 newNetwork, mLinkProperties, TRANSPORT_ETHERNET, DEFAULT_SUB_INDEX);
560         verify(mMockEpdgTunnelManager, never())
561                 .updateNetwork(eq(newNetwork), any(LinkProperties.class));
562     }
563 
564     @Test
testAddDuplicateDataServiceProviderThrows()565     public void testAddDuplicateDataServiceProviderThrows() throws Exception {
566         when(mMockIwlanDataServiceProvider.getSlotIndex()).thenReturn(DEFAULT_SLOT_INDEX);
567         assertThrows(
568                 IllegalStateException.class,
569                 () -> mIwlanDataService.addIwlanDataServiceProvider(mMockIwlanDataServiceProvider));
570     }
571 
572     @Test
testRemoveDataServiceProvider()573     public void testRemoveDataServiceProvider() {
574         when(mMockIwlanDataServiceProvider.getSlotIndex()).thenReturn(DEFAULT_SLOT_INDEX);
575         mIwlanDataService.removeDataServiceProvider(mMockIwlanDataServiceProvider);
576         mTestLooper.dispatchAll();
577         verify(mIwlanDataService, times(1)).deinitNetworkCallback();
578         mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX);
579         mTestLooper.dispatchAll();
580     }
581 
582     @Test
testRequestDataCallListPass()583     public void testRequestDataCallListPass() throws Exception {
584         DataProfile dp = buildImsDataProfile();
585         List<LinkAddress> mInternalAddressList;
586         List<InetAddress> mDNSAddressList;
587         List<InetAddress> mGatewayAddressList;
588         List<InetAddress> mPCSFAddressList;
589 
590         latch = new CountDownLatch(1);
591         IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
592         TunnelLinkProperties mLinkProperties =
593                 TunnelLinkPropertiesTest.createTestTunnelLinkProperties();
594         mSpyIwlanDataServiceProvider.setTunnelState(
595                 dp,
596                 new DataServiceCallback(callback),
597                 TunnelState.TUNNEL_UP,
598                 mLinkProperties,
599                 false, /* isHandover */
600                 1, /* pduSessionId */
601                 true /* isImsOrEmergency */);
602         mSpyIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
603         mTestLooper.dispatchAll();
604         latch.await(1, TimeUnit.SECONDS);
605 
606         assertEquals(mResultCode, DataServiceCallback.RESULT_SUCCESS);
607         assertEquals(mResultDataCallList.size(), 1);
608         for (DataCallResponse dataCallInfo : mResultDataCallList) {
609             assertEquals(dataCallInfo.getId(), TEST_APN_NAME.hashCode());
610             assertEquals(dataCallInfo.getLinkStatus(), DataCallResponse.LINK_STATUS_ACTIVE);
611             assertEquals(dataCallInfo.getProtocolType(), ApnSetting.PROTOCOL_IPV4V6);
612             assertEquals(dataCallInfo.getInterfaceName(), INTERFACE_NAME);
613 
614             mInternalAddressList = dataCallInfo.getAddresses();
615             assertEquals(mInternalAddressList.size(), 1);
616             for (LinkAddress mLinkAddress : mInternalAddressList) {
617                 assertEquals(mLinkAddress, new LinkAddress(InetAddress.getByName(IP_ADDRESS), 3));
618             }
619 
620             mDNSAddressList = dataCallInfo.getDnsAddresses();
621             assertEquals(mDNSAddressList.size(), 1);
622             for (InetAddress mInetAddress : mDNSAddressList) {
623                 assertEquals(mInetAddress, InetAddress.getByName(DNS_ADDRESS));
624             }
625 
626             mGatewayAddressList = dataCallInfo.getGatewayAddresses();
627             assertEquals(mGatewayAddressList.size(), 1);
628             for (InetAddress mInetAddress : mGatewayAddressList) {
629                 assertEquals(mInetAddress, Inet4Address.getByName(GATEWAY_ADDRESS));
630             }
631 
632             mPCSFAddressList = dataCallInfo.getPcscfAddresses();
633             assertEquals(mPCSFAddressList.size(), 1);
634             for (InetAddress mInetAddress : mPCSFAddressList) {
635                 assertEquals(mInetAddress, InetAddress.getByName(PSCF_ADDRESS));
636             }
637 
638             assertEquals(dataCallInfo.getMtuV4(), LINK_MTU);
639             assertEquals(dataCallInfo.getMtuV6(), LINK_MTU);
640         }
641     }
642 
643     @Test
testRequestDataCallListEmpty()644     public void testRequestDataCallListEmpty() throws Exception {
645         latch = new CountDownLatch(1);
646         IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
647         mSpyIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
648         mTestLooper.dispatchAll();
649         latch.await(1, TimeUnit.SECONDS);
650 
651         assertEquals(mResultCode, DataServiceCallback.RESULT_SUCCESS);
652         assertEquals(mResultDataCallList.size(), 0);
653     }
654 
655     @Test
testIwlanSetupDataCallWithInvalidArg()656     public void testIwlanSetupDataCallWithInvalidArg() {
657         mSpyIwlanDataServiceProvider.setupDataCall(
658                 AccessNetworkType.UNKNOWN, /* AccessNetworkType */
659                 null, /* dataProfile */
660                 false, /* isRoaming */
661                 true, /* allowRoaming */
662                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
663                 null, /* LinkProperties */
664                 2, /* pdu session id */
665                 null, /* sliceInfo */
666                 null, /* trafficDescriptor */
667                 true, /* matchAllRuleAllowed */
668                 mMockDataServiceCallback);
669         mTestLooper.dispatchAll();
670 
671         verify(mMockDataServiceCallback, timeout(1000).times(1))
672                 .onSetupDataCallComplete(
673                         eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG), isNull());
674     }
675 
676     @Test
testIwlanSetupDataCallWithIllegalState()677     public void testIwlanSetupDataCallWithIllegalState() {
678         DataProfile dp = buildImsDataProfile();
679 
680         /* Wifi is not connected */
681         onSystemDefaultNetworkLost();
682 
683         mSpyIwlanDataServiceProvider.setupDataCall(
684                 AccessNetworkType.IWLAN, /* AccessNetworkType */
685                 dp, /* dataProfile */
686                 false, /* isRoaming */
687                 true, /* allowRoaming */
688                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
689                 null, /* LinkProperties */
690                 1, /* pdu session id */
691                 null, /* sliceInfo */
692                 null, /* trafficDescriptor */
693                 true, /* matchAllRuleAllowed */
694                 mMockDataServiceCallback);
695         mTestLooper.dispatchAll();
696 
697         verify(mMockDataServiceCallback, timeout(1000).times(1))
698                 .onSetupDataCallComplete(
699                         eq(5 /*DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */),
700                         isNull());
701     }
702 
703     @Test
testIwlanDeactivateDataCallWithInvalidArg()704     public void testIwlanDeactivateDataCallWithInvalidArg() {
705         mSpyIwlanDataServiceProvider.deactivateDataCall(
706                 0, /* cid */
707                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
708                 mMockDataServiceCallback);
709         mTestLooper.dispatchAll();
710 
711         verify(mMockDataServiceCallback, timeout(1000).times(1))
712                 .onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG));
713     }
714 
715     @Test
testIwlanSetupDataCallWithBringUpTunnel()716     public void testIwlanSetupDataCallWithBringUpTunnel() {
717         DataProfile dp = buildImsDataProfile();
718 
719         /* Wifi is connected */
720         onSystemDefaultNetworkConnected(
721                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
722 
723         mSpyIwlanDataServiceProvider.setupDataCall(
724                 AccessNetworkType.IWLAN, /* AccessNetworkType */
725                 dp, /* dataProfile */
726                 false, /* isRoaming */
727                 true, /* allowRoaming */
728                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
729                 null, /* LinkProperties */
730                 1, /* pduSessionId */
731                 null, /* sliceInfo */
732                 null, /* trafficDescriptor */
733                 true, /* matchAllRuleAllowed */
734                 mMockDataServiceCallback);
735         mTestLooper.dispatchAll();
736 
737         /* Check bringUpTunnel() is called. */
738         verify(mMockEpdgTunnelManager, times(1))
739                 .bringUpTunnel(
740                         any(TunnelSetupRequest.class),
741                         any(IwlanTunnelCallback.class),
742                         any(IwlanTunnelMetricsImpl.class));
743 
744         /* Check callback result is RESULT_SUCCESS when onOpened() is called. */
745         mSpyIwlanDataServiceProvider
746                 .getIwlanTunnelCallback()
747                 .onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
748         mTestLooper.dispatchAll();
749         verify(mMockDataServiceCallback, times(1))
750                 .onSetupDataCallComplete(
751                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
752     }
753 
754     @Test
testSliceInfoInclusionInDataCallResponse()755     public void testSliceInfoInclusionInDataCallResponse() throws Exception {
756         DataProfile dp = buildImsDataProfile();
757 
758         /* Wifi is connected */
759         onSystemDefaultNetworkConnected(
760                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
761 
762         mSpyIwlanDataServiceProvider.setupDataCall(
763                 AccessNetworkType.IWLAN, /* AccessNetworkType */
764                 dp, /* dataProfile */
765                 false, /* isRoaming */
766                 true, /* allowRoaming */
767                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
768                 null, /* LinkProperties */
769                 1, /* pduSessionId */
770                 null, /* sliceInfo */
771                 null, /* trafficDescriptor */
772                 true, /* matchAllRuleAllowed */
773                 mMockDataServiceCallback);
774         mTestLooper.dispatchAll();
775 
776         /* Check bringUpTunnel() is called. */
777         verify(mMockEpdgTunnelManager, times(1))
778                 .bringUpTunnel(
779                         any(TunnelSetupRequest.class),
780                         any(IwlanTunnelCallback.class),
781                         any(IwlanTunnelMetricsImpl.class));
782 
783         /* Check callback result is RESULT_SUCCESS when onOpened() is called. */
784         TunnelLinkProperties tp = TunnelLinkPropertiesTest.createTestTunnelLinkProperties();
785 
786         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
787                 ArgumentCaptor.forClass(DataCallResponse.class);
788 
789         mSpyIwlanDataServiceProvider.getIwlanTunnelCallback().onOpened(TEST_APN_NAME, tp);
790         mTestLooper.dispatchAll();
791         verify(mMockDataServiceCallback, times(1))
792                 .onSetupDataCallComplete(
793                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
794 
795         /* check that sliceinfo is filled up and matches */
796         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
797         assertNotNull(dataCallResponse.getSliceInfo());
798         assertEquals(dataCallResponse.getSliceInfo(), tp.sliceInfo().get());
799     }
800 
801     @Test
testIwlanDeactivateDataCallWithCloseTunnel()802     public void testIwlanDeactivateDataCallWithCloseTunnel() {
803         DataProfile dp = buildImsDataProfile();
804 
805         onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
806 
807         mSpyIwlanDataServiceProvider.setTunnelState(
808                 dp,
809                 mMockDataServiceCallback,
810                 TunnelState.TUNNEL_IN_BRINGUP,
811                 null, /* linkProperties */
812                 false, /* isHandover */
813                 1, /* pduSessionId */
814                 true /* isImsOrEmergency */);
815 
816         mSpyIwlanDataServiceProvider.deactivateDataCall(
817                 TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
818                 DataService.REQUEST_REASON_NORMAL,
819                 mMockDataServiceCallback);
820         mTestLooper.dispatchAll();
821         /* Check closeTunnel() is called. */
822         verify(mMockEpdgTunnelManager, times(1))
823                 .closeTunnel(
824                         eq(TEST_APN_NAME),
825                         eq(false),
826                         any(IwlanTunnelCallback.class),
827                         any(IwlanTunnelMetricsImpl.class));
828 
829         /* Check callback result is RESULT_SUCCESS when onClosed() is called. */
830         mSpyIwlanDataServiceProvider
831                 .getIwlanTunnelCallback()
832                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
833         mTestLooper.dispatchAll();
834         verify(mMockDataServiceCallback, times(1))
835                 .onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
836     }
837 
838     @Test
testIwlanDeactivateDataCallAfterSuccessHandover()839     public void testIwlanDeactivateDataCallAfterSuccessHandover() {
840         DataProfile dp = buildImsDataProfile();
841 
842         onSystemDefaultNetworkConnected(TRANSPORT_WIFI);
843 
844         mSpyIwlanDataServiceProvider.setTunnelState(
845                 dp,
846                 mMockDataServiceCallback,
847                 TunnelState.TUNNEL_IN_BRINGUP,
848                 null, /* linkProperties */
849                 false, /* isHandover */
850                 1, /* pduSessionId */
851                 true /* isImsOrEmergency */);
852 
853         mSpyIwlanDataServiceProvider.deactivateDataCall(
854                 TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
855                 DataService.REQUEST_REASON_HANDOVER,
856                 mMockDataServiceCallback);
857         mTestLooper.dispatchAll();
858         /* Check closeTunnel() is called. */
859         verify(mMockEpdgTunnelManager, times(1))
860                 .closeTunnel(
861                         eq(TEST_APN_NAME),
862                         eq(true),
863                         any(IwlanTunnelCallback.class),
864                         any(IwlanTunnelMetricsImpl.class));
865 
866         /* Check callback result is RESULT_SUCCESS when onClosed() is called. */
867         mSpyIwlanDataServiceProvider
868                 .getIwlanTunnelCallback()
869                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
870         mTestLooper.dispatchAll();
871         verify(mMockDataServiceCallback, times(1))
872                 .onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
873     }
874 
875     @Test
testHandoverFailureModeDefault()876     public void testHandoverFailureModeDefault() {
877         DataProfile dp = buildImsDataProfile();
878         int setupDataReason = DataService.REQUEST_REASON_NORMAL;
879 
880         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
881                 .thenReturn(mMockErrorPolicyManager);
882         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(5L);
883         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
884                 .thenReturn(DataFailCause.USER_AUTHENTICATION);
885 
886         mSpyIwlanDataServiceProvider.setTunnelState(
887                 dp,
888                 mMockDataServiceCallback,
889                 TunnelState.TUNNEL_IN_BRINGUP,
890                 null, /* linkProperties */
891                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
892                 1 /* pduSessionId */,
893                 true /* isImsOrEmergency */);
894 
895         mSpyIwlanDataServiceProvider.setMetricsAtom(
896                 TEST_APN_NAME,
897                 64, // type IMS
898                 true,
899                 13, // LTE
900                 false,
901                 true,
902                 1 // Transport Wi-Fi
903                 );
904 
905         mSpyIwlanDataServiceProvider
906                 .getIwlanTunnelCallback()
907                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
908         mTestLooper.dispatchAll();
909 
910         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
911                 ArgumentCaptor.forClass(DataCallResponse.class);
912 
913         verify(mMockDataServiceCallback, times(1))
914                 .onSetupDataCallComplete(
915                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
916 
917         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
918         assertEquals(
919                 dataCallResponse.getHandoverFailureMode(),
920                 DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY);
921         assertEquals(dataCallResponse.getCause(), DataFailCause.USER_AUTHENTICATION);
922         assertEquals(dataCallResponse.getRetryDurationMillis(), 5L);
923     }
924 
925     @Test
testHandoverFailureModeHandover()926     public void testHandoverFailureModeHandover() {
927         DataProfile dp = buildImsDataProfile();
928         int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
929 
930         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
931                 .thenReturn(mMockErrorPolicyManager);
932         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
933         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
934                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
935         when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
936                 .thenReturn(false);
937 
938         mSpyIwlanDataServiceProvider.setTunnelState(
939                 dp,
940                 mMockDataServiceCallback,
941                 TunnelState.TUNNEL_IN_BRINGUP,
942                 null, /* linkProperties */
943                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
944                 1 /* pduSessionId */,
945                 true /* isImsOrEmergency */);
946 
947         mSpyIwlanDataServiceProvider.setMetricsAtom(
948                 TEST_APN_NAME,
949                 64, // type IMS
950                 true,
951                 13, // LTE
952                 false,
953                 true,
954                 1 // Transport Wi-Fi
955                 );
956 
957         mSpyIwlanDataServiceProvider
958                 .getIwlanTunnelCallback()
959                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
960         mTestLooper.dispatchAll();
961 
962         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
963                 ArgumentCaptor.forClass(DataCallResponse.class);
964 
965         verify(mMockDataServiceCallback, times(1))
966                 .onSetupDataCallComplete(
967                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
968 
969         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
970         assertEquals(
971                 dataCallResponse.getHandoverFailureMode(),
972                 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER);
973         assertEquals(dataCallResponse.getCause(), DataFailCause.ERROR_UNSPECIFIED);
974         assertEquals(dataCallResponse.getRetryDurationMillis(), -1L);
975     }
976 
977     @Test
testSupportInitialAttachSuccessOnIms()978     public void testSupportInitialAttachSuccessOnIms() {
979         DataProfile dp = buildImsDataProfile();
980         int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
981 
982         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
983                 .thenReturn(mMockErrorPolicyManager);
984         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
985         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
986                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
987         when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
988                 .thenReturn(true);
989 
990         // APN = IMS, in idle call state
991         mIwlanDataService
992                 .mIwlanDataServiceHandler
993                 .obtainMessage(
994                         IwlanEventListener.CALL_STATE_CHANGED_EVENT,
995                         DEFAULT_SLOT_INDEX,
996                         TelephonyManager.CALL_STATE_IDLE)
997                 .sendToTarget();
998 
999         mSpyIwlanDataServiceProvider.setTunnelState(
1000                 dp,
1001                 mMockDataServiceCallback,
1002                 TunnelState.TUNNEL_IN_BRINGUP,
1003                 null, /* linkProperties */
1004                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1005                 1 /* pduSessionId */,
1006                 true /* isImsOrEmergency */);
1007 
1008         mSpyIwlanDataServiceProvider.setMetricsAtom(
1009                 TEST_APN_NAME,
1010                 64, // type IMS
1011                 true,
1012                 13, // LTE
1013                 false,
1014                 true,
1015                 1 // Transport Wi-Fi
1016                 );
1017 
1018         mSpyIwlanDataServiceProvider
1019                 .getIwlanTunnelCallback()
1020                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
1021         mTestLooper.dispatchAll();
1022 
1023         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
1024                 ArgumentCaptor.forClass(DataCallResponse.class);
1025         verify(mMockDataServiceCallback, times(1))
1026                 .onSetupDataCallComplete(
1027                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
1028         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
1029         // Not on video or voice call
1030         assertEquals(
1031                 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL,
1032                 dataCallResponse.getHandoverFailureMode());
1033     }
1034 
1035     @Test
testSupportInitialAttachSuccessOnEmergency()1036     public void testSupportInitialAttachSuccessOnEmergency() {
1037         DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
1038         int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
1039 
1040         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1041                 .thenReturn(mMockErrorPolicyManager);
1042         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
1043         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
1044                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
1045         when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
1046                 .thenReturn(true);
1047 
1048         // APN = Emergency, in idle call state
1049         mIwlanDataService
1050                 .mIwlanDataServiceHandler
1051                 .obtainMessage(
1052                         IwlanEventListener.CALL_STATE_CHANGED_EVENT,
1053                         DEFAULT_SLOT_INDEX,
1054                         TelephonyManager.CALL_STATE_IDLE)
1055                 .sendToTarget();
1056 
1057         mSpyIwlanDataServiceProvider.setTunnelState(
1058                 dp,
1059                 mMockDataServiceCallback,
1060                 TunnelState.TUNNEL_IN_BRINGUP,
1061                 null, /* linkProperties */
1062                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1063                 1 /* pduSessionId */,
1064                 true /* isImsOrEmergency */);
1065 
1066         mSpyIwlanDataServiceProvider.setMetricsAtom(
1067                 TEST_APN_NAME,
1068                 512, // type Emergency
1069                 true,
1070                 13, // LTE
1071                 false,
1072                 true,
1073                 1 // Transport Wi-Fi
1074                 );
1075 
1076         mSpyIwlanDataServiceProvider
1077                 .getIwlanTunnelCallback()
1078                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
1079         mTestLooper.dispatchAll();
1080 
1081         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
1082                 ArgumentCaptor.forClass(DataCallResponse.class);
1083         verify(mMockDataServiceCallback, times(1))
1084                 .onSetupDataCallComplete(
1085                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
1086         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
1087         // Not on video or voice call
1088         assertEquals(
1089                 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL,
1090                 dataCallResponse.getHandoverFailureMode());
1091     }
1092 
1093     @Test
testSupportInitialAttachOnImsCall()1094     public void testSupportInitialAttachOnImsCall() {
1095         DataProfile dp = buildImsDataProfile();
1096         int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
1097 
1098         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1099                 .thenReturn(mMockErrorPolicyManager);
1100         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
1101         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
1102                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
1103         when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
1104                 .thenReturn(true);
1105 
1106         // APN = IMS, in call
1107         mIwlanDataService
1108                 .mIwlanDataServiceHandler
1109                 .obtainMessage(
1110                         IwlanEventListener.CALL_STATE_CHANGED_EVENT,
1111                         DEFAULT_SLOT_INDEX,
1112                         TelephonyManager.CALL_STATE_OFFHOOK)
1113                 .sendToTarget();
1114 
1115         mSpyIwlanDataServiceProvider.setTunnelState(
1116                 dp,
1117                 mMockDataServiceCallback,
1118                 TunnelState.TUNNEL_IN_BRINGUP,
1119                 null /* linkProperties */,
1120                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1121                 1 /* pduSessionId */,
1122                 true /* isImsOrEmergency */);
1123 
1124         mSpyIwlanDataServiceProvider.setMetricsAtom(
1125                 TEST_APN_NAME,
1126                 64, // type IMS
1127                 true,
1128                 13, // LTE
1129                 false,
1130                 true,
1131                 1 // Transport Wi-Fi
1132                 );
1133 
1134         mSpyIwlanDataServiceProvider
1135                 .getIwlanTunnelCallback()
1136                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
1137         mTestLooper.dispatchAll();
1138 
1139         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
1140                 ArgumentCaptor.forClass(DataCallResponse.class);
1141         verify(mMockDataServiceCallback, times(1))
1142                 .onSetupDataCallComplete(
1143                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
1144         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
1145         // In call state
1146         assertEquals(
1147                 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER,
1148                 dataCallResponse.getHandoverFailureMode());
1149     }
1150 
1151     @Test
testSupportInitialAttachOnEmergencyCall()1152     public void testSupportInitialAttachOnEmergencyCall() {
1153         DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
1154         int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
1155 
1156         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1157                 .thenReturn(mMockErrorPolicyManager);
1158         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
1159         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
1160                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
1161         when(mMockErrorPolicyManager.shouldRetryWithInitialAttach(eq(TEST_APN_NAME)))
1162                 .thenReturn(true);
1163 
1164         // APN = Emergency, in call
1165         mIwlanDataService
1166                 .mIwlanDataServiceHandler
1167                 .obtainMessage(
1168                         IwlanEventListener.CALL_STATE_CHANGED_EVENT,
1169                         DEFAULT_SLOT_INDEX,
1170                         TelephonyManager.CALL_STATE_OFFHOOK)
1171                 .sendToTarget();
1172 
1173         mSpyIwlanDataServiceProvider.setTunnelState(
1174                 dp,
1175                 mMockDataServiceCallback,
1176                 TunnelState.TUNNEL_IN_BRINGUP,
1177                 null /* linkProperties */,
1178                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
1179                 1 /* pduSessionId */,
1180                 true /* isImsOrEmergency */);
1181 
1182         mSpyIwlanDataServiceProvider.setMetricsAtom(
1183                 TEST_APN_NAME,
1184                 512, // type Emergency
1185                 true,
1186                 13, // LTE
1187                 false,
1188                 true,
1189                 1 // Transport Wi-Fi
1190                 );
1191 
1192         mSpyIwlanDataServiceProvider
1193                 .getIwlanTunnelCallback()
1194                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
1195         mTestLooper.dispatchAll();
1196 
1197         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
1198                 ArgumentCaptor.forClass(DataCallResponse.class);
1199         verify(mMockDataServiceCallback, times(1))
1200                 .onSetupDataCallComplete(
1201                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
1202         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
1203         // In call state
1204         assertEquals(
1205                 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER,
1206                 dataCallResponse.getHandoverFailureMode());
1207     }
1208 
1209     @Test
testDnsPrefetching()1210     public void testDnsPrefetching() throws Exception {
1211         NetworkCallback networkCallback = getNetworkMonitorCallback();
1212         /* Wifi is connected */
1213         onSystemDefaultNetworkConnected(
1214                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
1215         networkCallback.onLinkPropertiesChanged(mMockNetwork, mLinkProperties);
1216 
1217         mIwlanDataService
1218                 .mIwlanDataServiceHandler
1219                 .obtainMessage(
1220                         IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT,
1221                         DEFAULT_SLOT_INDEX,
1222                         0 /* unused */)
1223                 .sendToTarget();
1224 
1225         mIwlanDataService
1226                 .mIwlanDataServiceHandler
1227                 .obtainMessage(
1228                         IwlanEventListener.WIFI_CALLING_ENABLE_EVENT,
1229                         DEFAULT_SLOT_INDEX,
1230                         0 /* unused */)
1231                 .sendToTarget();
1232         mTestLooper.dispatchAll();
1233 
1234         LinkProperties newLinkProperties = new LinkProperties();
1235         newLinkProperties.setInterfaceName("wlan0");
1236         newLinkProperties.addLinkAddress(mMockIPv4LinkAddress);
1237         newLinkProperties.addLinkAddress(mMockIPv6LinkAddress);
1238 
1239         networkCallback.onLinkPropertiesChanged(mMockNetwork, newLinkProperties);
1240 
1241         /* Prefetching will be triggered twice.
1242            1. Network connected, CarrierConfig ready, WifiCallingSetting enabled
1243            2. Connection ipFamily changed.
1244         */
1245         verify(mMockEpdgSelector, times(2))
1246                 .getValidatedServerList(
1247                         eq(0),
1248                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
1249                         eq(EpdgSelector.SYSTEM_PREFERRED),
1250                         eq(false),
1251                         eq(false),
1252                         eq(mMockNetwork),
1253                         isNull());
1254         verify(mMockEpdgSelector, times(2))
1255                 .getValidatedServerList(
1256                         eq(0),
1257                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
1258                         eq(EpdgSelector.SYSTEM_PREFERRED),
1259                         eq(false),
1260                         eq(true),
1261                         eq(mMockNetwork),
1262                         isNull());
1263     }
1264 
advanceCalendarByTimeMs(long time, Calendar calendar)1265     private void advanceCalendarByTimeMs(long time, Calendar calendar) {
1266         mMockedCalendarTime += time;
1267         if (calendar != null) {
1268             calendar.setTimeInMillis(mMockedCalendarTime);
1269         }
1270         mTestLooper.dispatchAll();
1271     }
1272 
buildImsDataProfile()1273     private DataProfile buildImsDataProfile() {
1274         return buildDataProfile(ApnSetting.TYPE_IMS);
1275     }
1276 
buildDataProfile(int supportedApnTypesBitmask)1277     private DataProfile buildDataProfile(int supportedApnTypesBitmask) {
1278         DataProfile dp =
1279                 new DataProfile.Builder()
1280                         .setProfileId(1)
1281                         .setApn(TEST_APN_NAME)
1282                         .setProtocolType(ApnSetting.PROTOCOL_IPV4V6) // IPv4v6
1283                         .setAuthType(0) // none
1284                         .setUserName("")
1285                         .setPassword("")
1286                         .setType(1) // 3gpp
1287                         // .setMaxConnectionsTime(1)
1288                         // .setMaxConnections(3)
1289                         // .setWaitTime(10)
1290                         .enable(true)
1291                         .setSupportedApnTypesBitmask(supportedApnTypesBitmask)
1292                         .setRoamingProtocolType(ApnSetting.PROTOCOL_IPV4V6) // IPv4v6
1293                         .setBearerBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)
1294                         .setPersistent(true)
1295                         .setPreferred(true)
1296                         .build();
1297         return dp;
1298     }
1299 
prepareNetworkCapabilitiesForTest( int transportType, int subId, boolean isVcn)1300     private NetworkCapabilities prepareNetworkCapabilitiesForTest(
1301             int transportType, int subId, boolean isVcn) {
1302         NetworkCapabilities.Builder builder =
1303                 new NetworkCapabilities.Builder().addTransportType(transportType);
1304         if (isVcn) {
1305             builder.setTransportInfo(new VcnTransportInfo(subId));
1306         } else {
1307             builder.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId));
1308         }
1309         return builder.build();
1310     }
1311 
1312     @Test
testIwlanSetupDataCallFailsWithCellularAndCstDisabled()1313     public void testIwlanSetupDataCallFailsWithCellularAndCstDisabled() throws Exception {
1314         DataProfile dp = buildImsDataProfile();
1315         /* CST is disabled, and data is on the same sub as the data service provider */
1316         when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(false);
1317 
1318         NetworkCapabilities nc =
1319                 prepareNetworkCapabilitiesForTest(
1320                         TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
1321         getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
1322 
1323         mSpyIwlanDataServiceProvider.setupDataCall(
1324                 AccessNetworkType.IWLAN, /* AccessNetworkType */
1325                 dp, /* dataProfile */
1326                 false, /* isRoaming */
1327                 true, /* allowRoaming */
1328                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
1329                 null, /* LinkProperties */
1330                 1, /* pdu session id */
1331                 null, /* sliceInfo */
1332                 null, /* trafficDescriptor */
1333                 true, /* matchAllRuleAllowed */
1334                 mMockDataServiceCallback);
1335         mTestLooper.dispatchAll();
1336 
1337         verify(mMockDataServiceCallback, timeout(1000).times(1))
1338                 .onSetupDataCallComplete(
1339                         eq(5 /* DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */),
1340                         isNull());
1341     }
1342 
1343     @Test
testIwlanSetupDataCallFailsWithCellularOnSameSubAndCstEnabled()1344     public void testIwlanSetupDataCallFailsWithCellularOnSameSubAndCstEnabled() throws Exception {
1345         DataProfile dp = buildImsDataProfile();
1346 
1347         /* CST is enabled, but data is on the same sub as the DataServiceProvider */
1348         when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
1349 
1350         NetworkCapabilities nc =
1351                 prepareNetworkCapabilitiesForTest(
1352                         TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX, false /* isVcn */);
1353         getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
1354 
1355         mSpyIwlanDataServiceProvider.setupDataCall(
1356                 AccessNetworkType.IWLAN, /* AccessNetworkType */
1357                 dp, /* dataProfile */
1358                 false, /* isRoaming */
1359                 true, /* allowRoaming */
1360                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
1361                 null, /* LinkProperties */
1362                 1, /* pduSessionId */
1363                 null, /* sliceInfo */
1364                 null, /* trafficDescriptor */
1365                 true, /* matchAllRuleAllowed */
1366                 mMockDataServiceCallback);
1367         mTestLooper.dispatchAll();
1368 
1369         verify(mMockDataServiceCallback, timeout(1000).times(1))
1370                 .onSetupDataCallComplete(
1371                         eq(5 /* DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */),
1372                         isNull());
1373     }
1374 
1375     @Test
testIwlanSetupDataCallSucceedsWithCellularOnDifferentSubAndCstEnabled()1376     public void testIwlanSetupDataCallSucceedsWithCellularOnDifferentSubAndCstEnabled()
1377             throws Exception {
1378         DataProfile dp = buildImsDataProfile();
1379 
1380         /* CST is enabled, but data is on the same sub as the DataServiceProvider */
1381         when(mMockImsMmTelManager.isCrossSimCallingEnabled()).thenReturn(true);
1382 
1383         NetworkCapabilities nc =
1384                 prepareNetworkCapabilitiesForTest(
1385                         TRANSPORT_CELLULAR, DEFAULT_SUB_INDEX + 1, false /* isVcn */);
1386         getNetworkMonitorCallback().onCapabilitiesChanged(mMockNetwork, nc);
1387 
1388         mSpyIwlanDataServiceProvider.setupDataCall(
1389                 AccessNetworkType.IWLAN, /* AccessNetworkType */
1390                 dp, /* dataProfile */
1391                 false, /* isRoaming */
1392                 true, /* allowRoaming */
1393                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
1394                 null, /* LinkProperties */
1395                 1, /* pduSessionId */
1396                 null, /* sliceInfo */
1397                 null, /* trafficDescriptor */
1398                 true, /* matchAllRuleAllowed */
1399                 mMockDataServiceCallback);
1400         mTestLooper.dispatchAll();
1401 
1402         /* Check bringUpTunnel() is called. */
1403         verify(mMockEpdgTunnelManager, times(1))
1404                 .bringUpTunnel(
1405                         any(TunnelSetupRequest.class),
1406                         any(IwlanTunnelCallback.class),
1407                         any(IwlanTunnelMetricsImpl.class));
1408 
1409         /* Check callback result is RESULT_SUCCESS when onOpened() is called. */
1410         mSpyIwlanDataServiceProvider
1411                 .getIwlanTunnelCallback()
1412                 .onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
1413         mTestLooper.dispatchAll();
1414         verify(mMockDataServiceCallback, times(1))
1415                 .onSetupDataCallComplete(
1416                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
1417     }
1418 
1419     @Test
testIwlanTunnelStatsFailureCounts()1420     public void testIwlanTunnelStatsFailureCounts() {
1421         DataProfile dp = buildImsDataProfile();
1422 
1423         onSystemDefaultNetworkConnected(
1424                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
1425 
1426         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1427                 .thenReturn(mMockErrorPolicyManager);
1428 
1429         long count = 3L;
1430         for (int i = 0; i < count; i++) {
1431             mockTunnelSetupFail(dp);
1432             mTestLooper.dispatchAll();
1433         }
1434 
1435         IwlanDataServiceProvider.IwlanDataTunnelStats stats =
1436                 mSpyIwlanDataServiceProvider.getTunnelStats();
1437         long result = stats.mTunnelSetupFailureCounts.get(TEST_APN_NAME);
1438         assertEquals(result, count);
1439     }
1440 
1441     @Test
testIwlanTunnelStatsUnsolDownCounts()1442     public void testIwlanTunnelStatsUnsolDownCounts() {
1443         DataProfile dp = buildImsDataProfile();
1444 
1445         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1446                 .thenReturn(mMockErrorPolicyManager);
1447         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
1448                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
1449 
1450         onSystemDefaultNetworkConnected(
1451                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
1452 
1453         long count = 3L;
1454         for (int i = 0; i < count; i++) {
1455             mockTunnelSetupSuccess(dp, 0, null);
1456             mockUnsolTunnelDown();
1457         }
1458 
1459         IwlanDataServiceProvider.IwlanDataTunnelStats stats =
1460                 mSpyIwlanDataServiceProvider.getTunnelStats();
1461         long result = stats.mUnsolTunnelDownCounts.get(TEST_APN_NAME);
1462         assertEquals(result, count);
1463     }
1464 
1465     @Test
testIwlanTunnelStats()1466     public void testIwlanTunnelStats() {
1467         DataProfile dp = buildImsDataProfile();
1468         Calendar calendar = mock(Calendar.class);
1469         when(calendar.getTime()).thenAnswer(i -> new Date(mMockedCalendarTime));
1470 
1471         mSpyIwlanDataServiceProvider.setCalendar(calendar);
1472         onSystemDefaultNetworkConnected(
1473                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
1474 
1475         LongSummaryStatistics tunnelSetupSuccessStats = new LongSummaryStatistics();
1476         LongSummaryStatistics tunnelUpStats = new LongSummaryStatistics();
1477 
1478         Date beforeSetup = calendar.getTime();
1479         mockTunnelSetupSuccess(dp, 0, calendar);
1480         Date tunnelUp = calendar.getTime();
1481         mockDeactivateTunnel(0, calendar);
1482         Date tunnelDown = calendar.getTime();
1483         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
1484         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
1485 
1486         beforeSetup = calendar.getTime();
1487         mockTunnelSetupSuccess(dp, 1000, calendar);
1488         tunnelUp = calendar.getTime();
1489         mockDeactivateTunnel(3000, calendar);
1490         tunnelDown = calendar.getTime();
1491         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
1492         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
1493 
1494         beforeSetup = calendar.getTime();
1495         mockTunnelSetupSuccess(dp, 600, calendar);
1496         tunnelUp = calendar.getTime();
1497         mockDeactivateTunnel(500, calendar);
1498         tunnelDown = calendar.getTime();
1499         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
1500         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
1501 
1502         IwlanDataServiceProvider.IwlanDataTunnelStats stats =
1503                 mSpyIwlanDataServiceProvider.getTunnelStats();
1504         LongSummaryStatistics finalSetupStats = stats.mTunnelSetupSuccessStats.get(TEST_APN_NAME);
1505         LongSummaryStatistics finalUpStats = stats.mTunnelUpStats.get(TEST_APN_NAME);
1506 
1507         assertEquals(tunnelSetupSuccessStats.getAverage(), finalSetupStats.getAverage(), 0);
1508         assertEquals(tunnelSetupSuccessStats.getCount(), finalSetupStats.getCount());
1509         assertEquals(tunnelSetupSuccessStats.getMax(), finalSetupStats.getMax(), 0);
1510 
1511         assertEquals(tunnelUpStats.getAverage(), finalUpStats.getAverage(), 0);
1512         assertEquals(tunnelUpStats.getCount(), finalUpStats.getCount());
1513         assertEquals(tunnelUpStats.getMax(), finalUpStats.getMax(), 0);
1514     }
1515 
1516     @Test
testUnexpectedTunnelClosedIsSuppressed()1517     public void testUnexpectedTunnelClosedIsSuppressed() {
1518         mockUnsolTunnelDown();
1519     }
1520 
1521     @Test
testIwlanDataServiceHandlerOnUnbind()1522     public void testIwlanDataServiceHandlerOnUnbind() {
1523         DataProfile dp = buildImsDataProfile();
1524 
1525         mSpyIwlanDataServiceProvider.setTunnelState(
1526                 dp,
1527                 mMockDataServiceCallback,
1528                 TunnelState.TUNNEL_UP,
1529                 null /* linkProperties */,
1530                 false /* isHandover */,
1531                 1 /* pduSessionId */,
1532                 true /* isImsOrEmergency */);
1533 
1534         mSpyIwlanDataServiceProvider.setMetricsAtom(
1535                 TEST_APN_NAME,
1536                 64, // type IMS
1537                 true,
1538                 13, // LTE
1539                 false,
1540                 true,
1541                 1 // Transport Wi-Fi
1542                 );
1543 
1544         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1545                 .thenReturn(mMockErrorPolicyManager);
1546         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
1547                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
1548 
1549         // Simulate IwlanDataService.onUnbind() which force close all tunnels
1550         mSpyIwlanDataServiceProvider.forceCloseTunnels();
1551         // Simulate DataService.onUnbind() which remove all IwlanDataServiceProviders
1552         mSpyIwlanDataServiceProvider.close();
1553         mTestLooper.dispatchAll();
1554 
1555         verify(mMockEpdgTunnelManager, atLeastOnce())
1556                 .closeTunnel(
1557                         eq(TEST_APN_NAME),
1558                         eq(true),
1559                         any(IwlanTunnelCallback.class),
1560                         any(IwlanTunnelMetricsImpl.class));
1561         assertNotNull(mIwlanDataService.mIwlanDataServiceHandler);
1562         // Should not raise NullPointerException
1563         mSpyIwlanDataServiceProvider
1564                 .getIwlanTunnelCallback()
1565                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
1566         mTestLooper.dispatchAll();
1567     }
1568 
1569     @Test
testBackToBackOnBindAndOnUnbindDoesNotThrow()1570     public void testBackToBackOnBindAndOnUnbindDoesNotThrow() {
1571         mIwlanDataService.onBind(null);
1572         mIwlanDataService.onUnbind(null);
1573     }
1574 
1575     @Test
testMetricsWhenTunnelClosedWithWrappedException()1576     public void testMetricsWhenTunnelClosedWithWrappedException() {
1577         DataProfile dp = buildImsDataProfile();
1578 
1579         mSpyIwlanDataServiceProvider.setTunnelState(
1580                 dp,
1581                 mMockDataServiceCallback,
1582                 TunnelState.TUNNEL_IN_BRINGUP,
1583                 null, /* linkProperties */
1584                 false /* isHandover */,
1585                 1 /* pduSessionId */,
1586                 true /* isImsOrEmergency */);
1587 
1588         mSpyIwlanDataServiceProvider.setMetricsAtom(
1589                 TEST_APN_NAME,
1590                 64, // type IMS
1591                 true,
1592                 13, // LTE
1593                 false,
1594                 true,
1595                 1 // Transport Wi-Fi
1596                 );
1597 
1598         MetricsAtom metricsAtom = mSpyIwlanDataServiceProvider.getMetricsAtomByApn(TEST_APN_NAME);
1599         assertNotNull(metricsAtom);
1600 
1601         String exceptionMessage = "Some exception message";
1602         Exception mockException = spy(new IllegalStateException(exceptionMessage));
1603         String firstDeclaringClassName = "test.test.TestClass";
1604         String firstMethodName = "someMethod";
1605         String firstFileName = "TestClass.java";
1606         int firstLineNumber = 12345;
1607         StackTraceElement[] stackTraceElements = {
1608             new StackTraceElement(
1609                     firstDeclaringClassName, firstMethodName, firstFileName, firstLineNumber),
1610             new StackTraceElement("test", "test", "test.java", 123)
1611         };
1612         doReturn(stackTraceElements).when(mockException).getStackTrace();
1613 
1614         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1615                 .thenReturn(mMockErrorPolicyManager);
1616         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
1617                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
1618 
1619         mSpyIwlanDataServiceProvider
1620                 .getIwlanTunnelCallback()
1621                 .onClosed(TEST_APN_NAME, new IwlanError(new IkeInternalException(mockException)));
1622 
1623         mTestLooper.dispatchAll();
1624 
1625         var expectedStackFirstFrame =
1626                 firstDeclaringClassName
1627                         + "."
1628                         + firstMethodName
1629                         + "("
1630                         + firstFileName
1631                         + ":"
1632                         + firstLineNumber
1633                         + ")";
1634 
1635         assertEquals(
1636                 mockException.getClass().getCanonicalName(),
1637                 metricsAtom.getIwlanErrorWrappedClassname());
1638 
1639         assertEquals(expectedStackFirstFrame, metricsAtom.getIwlanErrorWrappedStackFirstFrame());
1640     }
1641 
1642     @Test
testMetricsWhenTunnelClosedWithoutWrappedException()1643     public void testMetricsWhenTunnelClosedWithoutWrappedException() {
1644         DataProfile dp = buildImsDataProfile();
1645 
1646         mSpyIwlanDataServiceProvider.setTunnelState(
1647                 dp,
1648                 mMockDataServiceCallback,
1649                 TunnelState.TUNNEL_IN_BRINGUP,
1650                 null, /* linkProperties */
1651                 false /* isHandover */,
1652                 1 /* pduSessionId */,
1653                 true /* isImsOrEmergency */);
1654 
1655         mSpyIwlanDataServiceProvider.setMetricsAtom(
1656                 TEST_APN_NAME,
1657                 64, // type IMS
1658                 true,
1659                 13, // LTE
1660                 false,
1661                 true,
1662                 1 // Transport Wi-Fi
1663                 );
1664 
1665         MetricsAtom metricsAtom = mSpyIwlanDataServiceProvider.getMetricsAtomByApn(TEST_APN_NAME);
1666         assertNotNull(metricsAtom);
1667 
1668         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
1669                 .thenReturn(mMockErrorPolicyManager);
1670         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
1671                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
1672 
1673         mSpyIwlanDataServiceProvider
1674                 .getIwlanTunnelCallback()
1675                 .onClosed(
1676                         TEST_APN_NAME,
1677                         new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED));
1678 
1679         mTestLooper.dispatchAll();
1680 
1681         assertEquals(null, metricsAtom.getIwlanErrorWrappedClassname());
1682         assertEquals(null, metricsAtom.getIwlanErrorWrappedStackFirstFrame());
1683     }
1684 
mockTunnelSetupFail(DataProfile dp)1685     private void mockTunnelSetupFail(DataProfile dp) {
1686         mSpyIwlanDataServiceProvider.setupDataCall(
1687                 AccessNetworkType.IWLAN, /* AccessNetworkType */
1688                 dp, /* dataProfile */
1689                 false, /* isRoaming */
1690                 true, /* allowRoaming */
1691                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
1692                 null, /* LinkProperties */
1693                 1, /* pduSessionId */
1694                 null, /* sliceInfo */
1695                 null, /* trafficDescriptor */
1696                 true, /* matchAllRuleAllowed */
1697                 mMockDataServiceCallback);
1698         doReturn(true)
1699                 .when(mMockEpdgTunnelManager)
1700                 .bringUpTunnel(
1701                         any(TunnelSetupRequest.class),
1702                         any(IwlanTunnelCallback.class),
1703                         any(IwlanTunnelMetricsImpl.class));
1704 
1705         mSpyIwlanDataServiceProvider
1706                 .getIwlanTunnelCallback()
1707                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION));
1708         mTestLooper.dispatchAll();
1709         verify(mMockDataServiceCallback, atLeastOnce())
1710                 .onSetupDataCallComplete(
1711                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
1712     }
1713 
mockTunnelSetupSuccess(DataProfile dp, long setupTime, Calendar calendar)1714     private void mockTunnelSetupSuccess(DataProfile dp, long setupTime, Calendar calendar) {
1715         mSpyIwlanDataServiceProvider.setupDataCall(
1716                 AccessNetworkType.IWLAN, /* AccessNetworkType */
1717                 dp, /* dataProfile */
1718                 false, /* isRoaming */
1719                 true, /* allowRoaming */
1720                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
1721                 null, /* LinkProperties */
1722                 1, /* pduSessionId */
1723                 null, /* sliceInfo */
1724                 null, /* trafficDescriptor */
1725                 true, /* matchAllRuleAllowed */
1726                 mMockDataServiceCallback);
1727         doReturn(true)
1728                 .when(mMockEpdgTunnelManager)
1729                 .bringUpTunnel(
1730                         any(TunnelSetupRequest.class),
1731                         any(IwlanTunnelCallback.class),
1732                         any(IwlanTunnelMetricsImpl.class));
1733         mTestLooper.dispatchAll();
1734 
1735         advanceCalendarByTimeMs(setupTime, calendar);
1736 
1737         mSpyIwlanDataServiceProvider
1738                 .getIwlanTunnelCallback()
1739                 .onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
1740         mTestLooper.dispatchAll();
1741         verify(mMockDataServiceCallback, atLeastOnce())
1742                 .onSetupDataCallComplete(
1743                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
1744     }
1745 
mockUnsolTunnelDown()1746     private void mockUnsolTunnelDown() {
1747         mSpyIwlanDataServiceProvider
1748                 .getIwlanTunnelCallback()
1749                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION));
1750         mTestLooper.dispatchAll();
1751     }
1752 
mockDeactivateTunnel(long deactivationTime, Calendar calendar)1753     private void mockDeactivateTunnel(long deactivationTime, Calendar calendar) {
1754         mSpyIwlanDataServiceProvider.deactivateDataCall(
1755                 TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
1756                 DataService.REQUEST_REASON_NORMAL /* DataService.REQUEST_REASON_NORMAL */,
1757                 mMockDataServiceCallback);
1758         mTestLooper.dispatchAll();
1759         verify(mMockEpdgTunnelManager, atLeastOnce())
1760                 .closeTunnel(
1761                         eq(TEST_APN_NAME),
1762                         anyBoolean(),
1763                         any(IwlanTunnelCallback.class),
1764                         any(IwlanTunnelMetricsImpl.class));
1765 
1766         advanceCalendarByTimeMs(deactivationTime, calendar);
1767 
1768         mSpyIwlanDataServiceProvider
1769                 .getIwlanTunnelCallback()
1770                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
1771         mTestLooper.dispatchAll();
1772         verify(mMockDataServiceCallback, atLeastOnce())
1773                 .onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
1774     }
1775 
callUnsupportedAppUsageMethod( Object target, String methodName, Class<?>[] parameterTypes, Object[] args)1776     private Object callUnsupportedAppUsageMethod(
1777             Object target, String methodName, Class<?>[] parameterTypes, Object[] args)
1778             throws Exception {
1779         Method method = target.getClass().getDeclaredMethod(methodName, parameterTypes);
1780         method.setAccessible(true);
1781         return method.invoke(target, args);
1782     }
1783 
1784     @Test
testNetworkChangeDuringTunnelBringUp_closeTunnel()1785     public void testNetworkChangeDuringTunnelBringUp_closeTunnel() {
1786         DataProfile dp = buildImsDataProfile();
1787         Network newNetwork1 = createMockNetwork(mLinkProperties);
1788         onSystemDefaultNetworkConnected(
1789                 newNetwork1, mLinkProperties, TRANSPORT_WIFI, DEFAULT_SUB_INDEX);
1790 
1791         mSpyIwlanDataServiceProvider.setupDataCall(
1792                 AccessNetworkType.IWLAN, /* AccessNetworkType */
1793                 dp, /* dataProfile */
1794                 false, /* isRoaming */
1795                 true, /* allowRoaming */
1796                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
1797                 null, /* LinkProperties */
1798                 1, /* pduSessionId */
1799                 null, /* sliceInfo */
1800                 null, /* trafficDescriptor */
1801                 true, /* matchAllRuleAllowed */
1802                 mMockDataServiceCallback);
1803         mTestLooper.dispatchAll();
1804 
1805         /* Check bringUpTunnel() is called. */
1806         verify(mMockEpdgTunnelManager, times(1))
1807                 .bringUpTunnel(
1808                         any(TunnelSetupRequest.class),
1809                         any(IwlanTunnelCallback.class),
1810                         any(IwlanTunnelMetricsImpl.class));
1811 
1812         Network newNetwork2 = createMockNetwork(mLinkProperties);
1813         onSystemDefaultNetworkConnected(
1814                 newNetwork2, mLinkProperties, TRANSPORT_WIFI, DEFAULT_SUB_INDEX);
1815         verify(mMockEpdgTunnelManager, times(1)).closeTunnel(any(), anyBoolean(), any(), any());
1816     }
1817 }
1818