• 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_WIFI;
21 
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
23 
24 import static org.junit.Assert.*;
25 import static org.mockito.Matchers.isNull;
26 import static org.mockito.Mockito.*;
27 
28 import android.content.ContentResolver;
29 import android.content.Context;
30 import android.net.ConnectivityManager;
31 import android.net.LinkAddress;
32 import android.net.LinkProperties;
33 import android.net.Network;
34 import android.net.NetworkCapabilities;
35 import android.telephony.AccessNetworkConstants.AccessNetworkType;
36 import android.telephony.DataFailCause;
37 import android.telephony.SubscriptionInfo;
38 import android.telephony.SubscriptionManager;
39 import android.telephony.TelephonyManager;
40 import android.telephony.data.ApnSetting;
41 import android.telephony.data.DataCallResponse;
42 import android.telephony.data.DataProfile;
43 import android.telephony.data.DataService;
44 import android.telephony.data.DataServiceCallback;
45 import android.telephony.data.IDataServiceCallback;
46 import android.telephony.ims.ImsManager;
47 import android.telephony.ims.ImsMmTelManager;
48 
49 import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider;
50 import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider.IwlanTunnelCallback;
51 import com.google.android.iwlan.IwlanDataService.IwlanDataServiceProvider.TunnelState;
52 import com.google.android.iwlan.IwlanDataService.IwlanNetworkMonitorCallback;
53 import com.google.android.iwlan.epdg.EpdgSelector;
54 import com.google.android.iwlan.epdg.EpdgTunnelManager;
55 import com.google.android.iwlan.epdg.TunnelLinkProperties;
56 import com.google.android.iwlan.epdg.TunnelLinkPropertiesTest;
57 import com.google.android.iwlan.epdg.TunnelSetupRequest;
58 
59 import org.junit.After;
60 import org.junit.Before;
61 import org.junit.Test;
62 import org.mockito.ArgumentCaptor;
63 import org.mockito.Mock;
64 import org.mockito.MockitoAnnotations;
65 import org.mockito.MockitoSession;
66 import org.mockito.quality.Strictness;
67 
68 import java.net.Inet4Address;
69 import java.net.Inet6Address;
70 import java.net.InetAddress;
71 import java.util.ArrayList;
72 import java.util.Calendar;
73 import java.util.Date;
74 import java.util.List;
75 import java.util.LongSummaryStatistics;
76 import java.util.concurrent.CountDownLatch;
77 import java.util.concurrent.TimeUnit;
78 
79 public class IwlanDataServiceTest {
80     private static final int DEFAULT_SLOT_INDEX = 0;
81     private static final int DEFAULT_SUB_INDEX = 0;
82     private static final int LINK_MTU = 1280;
83     private static final String TEST_APN_NAME = "ims";
84     private static final String IP_ADDRESS = "192.0.2.1";
85     private static final String DNS_ADDRESS = "8.8.8.8";
86     private static final String GATEWAY_ADDRESS = "0.0.0.0";
87     private static final String PSCF_ADDRESS = "10.159.204.230";
88     private static final String INTERFACE_NAME = "ipsec6";
89 
90     @Mock private Context mMockContext;
91     @Mock private SubscriptionManager mMockSubscriptionManager;
92     @Mock private SubscriptionInfo mMockSubscriptionInfo;
93     @Mock private ContentResolver mMockContentResolver;
94     @Mock private ConnectivityManager mMockConnectivityManager;
95     @Mock private DataServiceCallback mMockDataServiceCallback;
96     @Mock private EpdgTunnelManager mMockEpdgTunnelManager;
97     @Mock private IwlanDataServiceProvider mMockIwlanDataServiceProvider;
98     @Mock private Network mMockNetwork;
99     @Mock private NetworkCapabilities mMockNetworkCapabilities;
100     @Mock private TunnelLinkProperties mMockTunnelLinkProperties;
101     @Mock private ErrorPolicyManager mMockErrorPolicyManager;
102     @Mock private ImsManager mMockImsManager;
103     @Mock private ImsMmTelManager mMockImsMmTelManager;
104     @Mock private TelephonyManager mMockTelephonyManager;
105     @Mock private EpdgSelector mMockEpdgSelector;
106     @Mock private LinkProperties mMockLinkProperties;
107     @Mock private LinkAddress mMockIPv4LinkAddress;
108     @Mock private LinkAddress mMockIPv6LinkAddress;
109     @Mock private Inet4Address mMockInet4Address;
110     @Mock private Inet6Address mMockInet6Address;
111     MockitoSession mStaticMockSession;
112 
113     private List<DataCallResponse> mResultDataCallList;
114     private @DataServiceCallback.ResultCode int mResultCode;
115     private CountDownLatch latch;
116     private IwlanDataService mIwlanDataService;
117     private IwlanDataServiceProvider mIwlanDataServiceProvider;
118     private IwlanDataServiceProvider mSpyIwlanDataServiceProvider;
119 
120     private final class IwlanDataServiceCallback extends IDataServiceCallback.Stub {
121 
122         private final String mTag;
123 
IwlanDataServiceCallback(String tag)124         IwlanDataServiceCallback(String tag) {
125             mTag = tag;
126         }
127 
128         @Override
onSetupDataCallComplete( @ataServiceCallback.ResultCode int resultCode, DataCallResponse response)129         public void onSetupDataCallComplete(
130                 @DataServiceCallback.ResultCode int resultCode, DataCallResponse response) {}
131 
132         @Override
onDeactivateDataCallComplete(@ataServiceCallback.ResultCode int resultCode)133         public void onDeactivateDataCallComplete(@DataServiceCallback.ResultCode int resultCode) {}
134 
135         @Override
onSetInitialAttachApnComplete(@ataServiceCallback.ResultCode int resultCode)136         public void onSetInitialAttachApnComplete(@DataServiceCallback.ResultCode int resultCode) {}
137 
138         @Override
onSetDataProfileComplete(@ataServiceCallback.ResultCode int resultCode)139         public void onSetDataProfileComplete(@DataServiceCallback.ResultCode int resultCode) {}
140 
141         @Override
onRequestDataCallListComplete( @ataServiceCallback.ResultCode int resultCode, List<DataCallResponse> dataCallList)142         public void onRequestDataCallListComplete(
143                 @DataServiceCallback.ResultCode int resultCode,
144                 List<DataCallResponse> dataCallList) {
145             mResultCode = resultCode;
146             mResultDataCallList = new ArrayList<DataCallResponse>(dataCallList);
147             latch.countDown();
148         }
149 
150         @Override
onDataCallListChanged(List<DataCallResponse> dataCallList)151         public void onDataCallListChanged(List<DataCallResponse> dataCallList) {}
152 
153         @Override
onHandoverStarted(@ataServiceCallback.ResultCode int result)154         public void onHandoverStarted(@DataServiceCallback.ResultCode int result) {}
155 
156         @Override
onHandoverCancelled(@ataServiceCallback.ResultCode int result)157         public void onHandoverCancelled(@DataServiceCallback.ResultCode int result) {}
158 
159         @Override
onApnUnthrottled(String apn)160         public void onApnUnthrottled(String apn) {}
161     }
162 
163     @Before
setUp()164     public void setUp() throws Exception {
165         MockitoAnnotations.initMocks(this);
166 
167         mStaticMockSession =
168                 mockitoSession()
169                         .mockStatic(EpdgSelector.class)
170                         .mockStatic(ErrorPolicyManager.class)
171                         .mockStatic(IwlanBroadcastReceiver.class)
172                         .mockStatic(IwlanHelper.class)
173                         .strictness(Strictness.LENIENT)
174                         .startMocking();
175 
176         when(mMockContext.getSystemService(eq(ConnectivityManager.class)))
177                 .thenReturn(mMockConnectivityManager);
178         when(mMockConnectivityManager.getNetworkCapabilities(eq(mMockNetwork)))
179                 .thenReturn(mMockNetworkCapabilities);
180         when(mMockNetworkCapabilities.hasTransport(eq(TRANSPORT_CELLULAR))).thenReturn(false);
181         when(mMockNetworkCapabilities.hasTransport(eq(TRANSPORT_WIFI))).thenReturn(true);
182 
183         when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
184                 .thenReturn(mMockSubscriptionManager);
185 
186         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt()))
187                 .thenReturn(mMockSubscriptionInfo);
188 
189         when(mMockSubscriptionInfo.getSubscriptionId()).thenReturn(DEFAULT_SUB_INDEX);
190 
191         when(mMockContext.getSystemService(eq(TelephonyManager.class)))
192                 .thenReturn(mMockTelephonyManager);
193 
194         when(mMockTelephonyManager.createForSubscriptionId(eq(DEFAULT_SUB_INDEX)))
195                 .thenReturn(mMockTelephonyManager);
196 
197         when(mMockTelephonyManager.isNetworkRoaming()).thenReturn(false);
198 
199         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
200 
201         when(mMockContext.getSystemService(eq(ImsManager.class))).thenReturn(mMockImsManager);
202 
203         when(mMockImsManager.getImsMmTelManager(anyInt())).thenReturn(mMockImsMmTelManager);
204 
205         when(mMockImsMmTelManager.isVoWiFiSettingEnabled()).thenReturn(false);
206 
207         when(EpdgSelector.getSelectorInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
208                 .thenReturn(mMockEpdgSelector);
209 
210         when(mMockIPv4LinkAddress.getAddress()).thenReturn(mMockInet4Address);
211         when(mMockIPv6LinkAddress.getAddress()).thenReturn(mMockInet6Address);
212 
213         mIwlanDataService = spy(new IwlanDataService());
214         mIwlanDataService.setAppContext(mMockContext);
215         mIwlanDataServiceProvider =
216                 (IwlanDataServiceProvider)
217                         mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX);
218         mSpyIwlanDataServiceProvider = spy(mIwlanDataServiceProvider);
219     }
220 
221     @After
cleanUp()222     public void cleanUp() throws Exception {
223         mStaticMockSession.finishMocking();
224         mIwlanDataServiceProvider.close();
225         if (mIwlanDataService != null) {
226             mIwlanDataService.onDestroy();
227         }
228     }
229 
230     @Test
testWifiOnAvailable()231     public void testWifiOnAvailable() {
232         IwlanNetworkMonitorCallback mNetworkMonitorCallback =
233                 mIwlanDataService.getNetworkMonitorCallback();
234 
235         mNetworkMonitorCallback.onAvailable(mMockNetwork);
236         boolean ret = mIwlanDataService.isNetworkConnected(true, false);
237 
238         assertTrue(ret);
239     }
240 
241     @Test
testWifiOnLost()242     public void testWifiOnLost() {
243         mIwlanDataService.addIwlanDataServiceProvider(mMockIwlanDataServiceProvider);
244         IwlanNetworkMonitorCallback mNetworkMonitorCallback =
245                 mIwlanDataService.getNetworkMonitorCallback();
246 
247         mNetworkMonitorCallback.onLost(mMockNetwork);
248         boolean ret = mIwlanDataService.isNetworkConnected(true, false);
249 
250         assertFalse(ret);
251         verify(mMockIwlanDataServiceProvider).forceCloseTunnelsInDeactivatingState();
252         mIwlanDataService.removeDataServiceProvider(mMockIwlanDataServiceProvider);
253     }
254 
255     @Test
testRequestDataCallListPass()256     public void testRequestDataCallListPass() throws Exception {
257         DataProfile dp = buildDataProfile();
258         List<LinkAddress> mInternalAddressList;
259         List<InetAddress> mDNSAddressList;
260         List<InetAddress> mGatewayAddressList;
261         List<InetAddress> mPCSFAddressList;
262 
263         latch = new CountDownLatch(1);
264         IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
265         TunnelLinkProperties mLinkProperties =
266                 TunnelLinkPropertiesTest.createTestTunnelLinkProperties();
267         mIwlanDataServiceProvider.setTunnelState(
268                 dp,
269                 new DataServiceCallback(callback),
270                 TunnelState.TUNNEL_UP,
271                 mLinkProperties,
272                 false,
273                 1);
274         mIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
275         latch.await(1, TimeUnit.SECONDS);
276 
277         assertEquals(mResultCode, DataServiceCallback.RESULT_SUCCESS);
278         assertEquals(mResultDataCallList.size(), 1);
279         for (DataCallResponse dataCallInfo : mResultDataCallList) {
280             assertEquals(dataCallInfo.getId(), TEST_APN_NAME.hashCode());
281             assertEquals(dataCallInfo.getLinkStatus(), DataCallResponse.LINK_STATUS_ACTIVE);
282             assertEquals(dataCallInfo.getProtocolType(), ApnSetting.PROTOCOL_IPV4V6);
283             assertEquals(dataCallInfo.getInterfaceName(), INTERFACE_NAME);
284 
285             mInternalAddressList = dataCallInfo.getAddresses();
286             assertEquals(mInternalAddressList.size(), 1);
287             for (LinkAddress mLinkAddress : mInternalAddressList) {
288                 assertEquals(mLinkAddress, new LinkAddress(InetAddress.getByName(IP_ADDRESS), 3));
289             }
290 
291             mDNSAddressList = dataCallInfo.getDnsAddresses();
292             assertEquals(mDNSAddressList.size(), 1);
293             for (InetAddress mInetAddress : mDNSAddressList) {
294                 assertEquals(mInetAddress, InetAddress.getByName(DNS_ADDRESS));
295             }
296 
297             mGatewayAddressList = dataCallInfo.getGatewayAddresses();
298             assertEquals(mGatewayAddressList.size(), 1);
299             for (InetAddress mInetAddress : mGatewayAddressList) {
300                 assertEquals(mInetAddress, Inet4Address.getByName(GATEWAY_ADDRESS));
301             }
302 
303             mPCSFAddressList = dataCallInfo.getPcscfAddresses();
304             assertEquals(mPCSFAddressList.size(), 1);
305             for (InetAddress mInetAddress : mPCSFAddressList) {
306                 assertEquals(mInetAddress, InetAddress.getByName(PSCF_ADDRESS));
307             }
308 
309             assertEquals(dataCallInfo.getMtuV4(), LINK_MTU);
310             assertEquals(dataCallInfo.getMtuV6(), LINK_MTU);
311         }
312     }
313 
314     @Test
testRequestDataCallListEmpty()315     public void testRequestDataCallListEmpty() throws Exception {
316         latch = new CountDownLatch(1);
317         IwlanDataServiceCallback callback = new IwlanDataServiceCallback("requestDataCallList");
318         mIwlanDataServiceProvider.requestDataCallList(new DataServiceCallback(callback));
319         latch.await(1, TimeUnit.SECONDS);
320 
321         assertEquals(mResultCode, DataServiceCallback.RESULT_SUCCESS);
322         assertEquals(mResultDataCallList.size(), 0);
323     }
324 
325     @Test
testIwlanSetupDataCallWithInvalidArg()326     public void testIwlanSetupDataCallWithInvalidArg() {
327         mIwlanDataServiceProvider.setupDataCall(
328                 AccessNetworkType.UNKNOWN, /* AccessNetworkType */
329                 null, /* dataProfile */
330                 false, /* isRoaming */
331                 true, /* allowRoaming */
332                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
333                 null, /* LinkProperties */
334                 2, /* pdu session id */
335                 null, /* sliceInfo */
336                 null, /* trafficDescriptor */
337                 true, /* matchAllRuleAllowed */
338                 mMockDataServiceCallback);
339 
340         verify(mMockDataServiceCallback, timeout(1000).times(1))
341                 .onSetupDataCallComplete(
342                         eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG), isNull());
343     }
344 
345     @Test
testIwlanSetupDataCallWithIllegalState()346     public void testIwlanSetupDataCallWithIllegalState() {
347         DataProfile dp = buildDataProfile();
348 
349         /* Wifi is not connected */
350         mIwlanDataService.setNetworkConnected(
351                 false, mMockNetwork, IwlanDataService.Transport.UNSPECIFIED_NETWORK);
352 
353         mIwlanDataServiceProvider.setupDataCall(
354                 AccessNetworkType.IWLAN, /* AccessNetworkType */
355                 dp, /* dataProfile */
356                 false, /* isRoaming */
357                 true, /* allowRoaming */
358                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
359                 null, /* LinkProperties */
360                 1, /* pdu session id */
361                 null, /* sliceInfo */
362                 null, /* trafficDescriptor */
363                 true, /* matchAllRuleAllowed */
364                 mMockDataServiceCallback);
365 
366         verify(mMockDataServiceCallback, timeout(1000).times(1))
367                 .onSetupDataCallComplete(
368                         eq(5 /*DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */), isNull());
369     }
370 
371     @Test
testIwlanDeactivateDataCallWithInvalidArg()372     public void testIwlanDeactivateDataCallWithInvalidArg() {
373         mIwlanDataServiceProvider.deactivateDataCall(
374                 0, /* cid */
375                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
376                 mMockDataServiceCallback);
377 
378         verify(mMockDataServiceCallback, timeout(1000).times(1))
379                 .onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_ERROR_INVALID_ARG));
380     }
381 
382     @Test
testIwlanSetupDataCallWithBringUpTunnel()383     public void testIwlanSetupDataCallWithBringUpTunnel() {
384         DataProfile dp = buildDataProfile();
385 
386         /* Wifi is connected */
387         mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
388 
389         doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
390 
391         mSpyIwlanDataServiceProvider.setupDataCall(
392                 AccessNetworkType.IWLAN, /* AccessNetworkType */
393                 dp, /* dataProfile */
394                 false, /* isRoaming */
395                 true, /* allowRoaming */
396                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
397                 null, /* LinkProperties */
398                 1, /* pduSessionId */
399                 null, /* sliceInfo */
400                 null, /* trafficDescriptor */
401                 true, /* matchAllRuleAllowed */
402                 mMockDataServiceCallback);
403 
404         /* Check bringUpTunnel() is called. */
405         verify(mMockEpdgTunnelManager, times(1))
406                 .bringUpTunnel(any(TunnelSetupRequest.class), any(IwlanTunnelCallback.class));
407 
408         /* Check callback result is RESULT_SUCCESS when onOpened() is called. */
409         mSpyIwlanDataServiceProvider
410                 .getIwlanTunnelCallback()
411                 .onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
412         verify(mMockDataServiceCallback, times(1))
413                 .onSetupDataCallComplete(
414                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
415     }
416 
417     @Test
testSliceInfoInclusionInDataCallResponse()418     public void testSliceInfoInclusionInDataCallResponse() throws Exception {
419         DataProfile dp = buildDataProfile();
420 
421         /* Wifi is connected */
422         mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
423 
424         doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
425 
426         mSpyIwlanDataServiceProvider.setupDataCall(
427                 AccessNetworkType.IWLAN, /* AccessNetworkType */
428                 dp, /* dataProfile */
429                 false, /* isRoaming */
430                 true, /* allowRoaming */
431                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
432                 null, /* LinkProperties */
433                 1, /* pduSessionId */
434                 null, /* sliceInfo */
435                 null, /* trafficDescriptor */
436                 true, /* matchAllRuleAllowed */
437                 mMockDataServiceCallback);
438 
439         /* Check bringUpTunnel() is called. */
440         verify(mMockEpdgTunnelManager, times(1))
441                 .bringUpTunnel(any(TunnelSetupRequest.class), any(IwlanTunnelCallback.class));
442 
443         /* Check callback result is RESULT_SUCCESS when onOpened() is called. */
444         TunnelLinkProperties tp = TunnelLinkPropertiesTest.createTestTunnelLinkProperties();
445 
446         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
447                 ArgumentCaptor.forClass(DataCallResponse.class);
448 
449         mSpyIwlanDataServiceProvider.getIwlanTunnelCallback().onOpened(TEST_APN_NAME, tp);
450         verify(mMockDataServiceCallback, times(1))
451                 .onSetupDataCallComplete(
452                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
453 
454         /* check that sliceinfo is filled up and matches */
455         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
456         assertNotNull(dataCallResponse.getSliceInfo());
457         assertEquals(dataCallResponse.getSliceInfo(), tp.sliceInfo().get());
458     }
459 
460     @Test
testIwlanDeactivateDataCallWithCloseTunnel()461     public void testIwlanDeactivateDataCallWithCloseTunnel() {
462         DataProfile dp = buildDataProfile();
463 
464         doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
465 
466         mSpyIwlanDataServiceProvider.setTunnelState(
467                 dp, mMockDataServiceCallback, TunnelState.TUNNEL_IN_BRINGUP, null, false, 1);
468 
469         mSpyIwlanDataServiceProvider.deactivateDataCall(
470                 TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
471                 DataService.REQUEST_REASON_NORMAL /* DataService.REQUEST_REASON_NORMAL */,
472                 mMockDataServiceCallback);
473 
474         /* Check closeTunnel() is called. */
475         verify(mMockEpdgTunnelManager, times(1)).closeTunnel(eq(TEST_APN_NAME), anyBoolean());
476 
477         /* Check callback result is RESULT_SUCCESS when onClosed() is called. */
478         mSpyIwlanDataServiceProvider
479                 .getIwlanTunnelCallback()
480                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
481         verify(mMockDataServiceCallback, times(1))
482                 .onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
483     }
484 
485     @Test
testHandoverFailureModeNormal()486     public void testHandoverFailureModeNormal() {
487         DataProfile dp = buildDataProfile();
488         int setupDataReason = DataService.REQUEST_REASON_NORMAL;
489 
490         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
491                 .thenReturn(mMockErrorPolicyManager);
492         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(5L);
493         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
494                 .thenReturn(DataFailCause.USER_AUTHENTICATION);
495 
496         mSpyIwlanDataServiceProvider.setTunnelState(
497                 dp,
498                 mMockDataServiceCallback,
499                 TunnelState.TUNNEL_IN_BRINGUP,
500                 null,
501                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
502                 1);
503 
504         mSpyIwlanDataServiceProvider
505                 .getIwlanTunnelCallback()
506                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
507 
508         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
509                 ArgumentCaptor.forClass(DataCallResponse.class);
510 
511         verify(mMockDataServiceCallback, times(1))
512                 .onSetupDataCallComplete(
513                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
514 
515         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
516         assertEquals(
517                 dataCallResponse.getHandoverFailureMode(),
518                 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL);
519         assertEquals(dataCallResponse.getCause(), DataFailCause.USER_AUTHENTICATION);
520         assertEquals(dataCallResponse.getRetryDurationMillis(), 5L);
521     }
522 
523     @Test
testHandoverFailureModeHandover()524     public void testHandoverFailureModeHandover() {
525         DataProfile dp = buildDataProfile();
526         int setupDataReason = DataService.REQUEST_REASON_HANDOVER;
527 
528         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
529                 .thenReturn(mMockErrorPolicyManager);
530         when(mMockErrorPolicyManager.getCurrentRetryTimeMs(eq(TEST_APN_NAME))).thenReturn(-1L);
531         when(mMockErrorPolicyManager.getDataFailCause(eq(TEST_APN_NAME)))
532                 .thenReturn(DataFailCause.ERROR_UNSPECIFIED);
533 
534         mSpyIwlanDataServiceProvider.setTunnelState(
535                 dp,
536                 mMockDataServiceCallback,
537                 TunnelState.TUNNEL_IN_BRINGUP,
538                 null,
539                 (setupDataReason == DataService.REQUEST_REASON_HANDOVER),
540                 1);
541 
542         mSpyIwlanDataServiceProvider
543                 .getIwlanTunnelCallback()
544                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
545 
546         ArgumentCaptor<DataCallResponse> dataCallResponseCaptor =
547                 ArgumentCaptor.forClass(DataCallResponse.class);
548 
549         verify(mMockDataServiceCallback, times(1))
550                 .onSetupDataCallComplete(
551                         eq(DataServiceCallback.RESULT_SUCCESS), dataCallResponseCaptor.capture());
552 
553         DataCallResponse dataCallResponse = dataCallResponseCaptor.getValue();
554         assertEquals(
555                 dataCallResponse.getHandoverFailureMode(),
556                 DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER);
557         assertEquals(dataCallResponse.getCause(), DataFailCause.ERROR_UNSPECIFIED);
558         assertEquals(dataCallResponse.getRetryDurationMillis(), -1L);
559     }
560 
561     @Test
testDnsPrefetching()562     public void testDnsPrefetching() throws Exception {
563         IwlanNetworkMonitorCallback mNetworkMonitorCallback =
564                 mIwlanDataService.getNetworkMonitorCallback();
565         /* Wifi is connected */
566         mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
567 
568         List<LinkAddress> linkAddresses = new ArrayList<>();
569         linkAddresses.add(mMockIPv4LinkAddress);
570 
571         when(mMockLinkProperties.getLinkAddresses()).thenReturn(linkAddresses);
572         mNetworkMonitorCallback.onLinkPropertiesChanged(mMockNetwork, mMockLinkProperties);
573 
574         mIwlanDataServiceProvider
575                 .mHandler
576                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
577                 .sendToTarget();
578         sleep(1000);
579 
580         mIwlanDataServiceProvider
581                 .mHandler
582                 .obtainMessage(IwlanEventListener.WIFI_CALLING_ENABLE_EVENT)
583                 .sendToTarget();
584         sleep(1000);
585 
586         linkAddresses.add(mMockIPv6LinkAddress);
587 
588         when(mMockLinkProperties.getLinkAddresses()).thenReturn(linkAddresses);
589         mNetworkMonitorCallback.onLinkPropertiesChanged(mMockNetwork, mMockLinkProperties);
590 
591         /* Prefetching will be triggered twice.
592            1. Network connected, CarrierConfig ready, WifiCallingSetting enabled
593            2. Connection ipFamily changed.
594         */
595         verify(mMockEpdgSelector, times(2))
596                 .getValidatedServerList(
597                         eq(0),
598                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
599                         eq(false),
600                         eq(false),
601                         eq(mMockNetwork),
602                         isNull());
603         verify(mMockEpdgSelector, times(2))
604                 .getValidatedServerList(
605                         eq(0),
606                         eq(EpdgSelector.PROTO_FILTER_IPV4V6),
607                         eq(false),
608                         eq(true),
609                         eq(mMockNetwork),
610                         isNull());
611     }
612 
sleep(long time)613     private void sleep(long time) {
614         try {
615             Thread.sleep(time);
616         } catch (Exception e) {
617             e.printStackTrace();
618         }
619     }
620 
buildDataProfile()621     private DataProfile buildDataProfile() {
622         DataProfile dp =
623                 new DataProfile.Builder()
624                         .setProfileId(1)
625                         .setApn(TEST_APN_NAME)
626                         .setProtocolType(ApnSetting.PROTOCOL_IPV4V6) // IPv4v6
627                         .setAuthType(0) // none
628                         .setUserName("")
629                         .setPassword("")
630                         .setType(1) // 3gpp
631                         // .setMaxConnectionsTime(1)
632                         // .setMaxConnections(3)
633                         // .setWaitTime(10)
634                         .enable(true)
635                         .setSupportedApnTypesBitmask(ApnSetting.TYPE_IMS)
636                         .setRoamingProtocolType(ApnSetting.PROTOCOL_IPV4V6) // IPv4v6
637                         .setBearerBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)
638                         .setPersistent(true)
639                         .setPreferred(true)
640                         .build();
641         return dp;
642     }
643 
644     @Test
testIwlanSetupDataCallWithCellularAndCstDisabled()645     public void testIwlanSetupDataCallWithCellularAndCstDisabled() {
646         DataProfile dp = buildDataProfile();
647 
648         /* Mobile is connected */
649         mIwlanDataService.setNetworkConnected(
650                 true, mMockNetwork, IwlanDataService.Transport.MOBILE);
651 
652         lenient()
653                 .when(
654                         IwlanHelper.isCrossSimCallingEnabled(
655                                 eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
656                 .thenReturn(false);
657         lenient()
658                 .when(IwlanHelper.isDefaultDataSlot(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
659                 .thenReturn(true);
660 
661         mIwlanDataServiceProvider.setupDataCall(
662                 AccessNetworkType.IWLAN, /* AccessNetworkType */
663                 dp, /* dataProfile */
664                 false, /* isRoaming */
665                 true, /* allowRoaming */
666                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
667                 null, /* LinkProperties */
668                 1, /* pdu session id */
669                 null, /* sliceInfo */
670                 null, /* trafficDescriptor */
671                 true, /* matchAllRuleAllowed */
672                 mMockDataServiceCallback);
673 
674         verify(mMockDataServiceCallback, timeout(1000).times(1))
675                 .onSetupDataCallComplete(
676                         eq(5 /* DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */), isNull());
677     }
678 
679     @Test
testIwlanSetupDataCallWithCellularAndCstEnabled()680     public void testIwlanSetupDataCallWithCellularAndCstEnabled() {
681         DataProfile dp = buildDataProfile();
682 
683         /* Clear state */
684         mIwlanDataService.setNetworkConnected(
685                 false, mMockNetwork, IwlanDataService.Transport.UNSPECIFIED_NETWORK);
686 
687         /* Mobile is connected */
688         mIwlanDataService.setNetworkConnected(
689                 true, mMockNetwork, IwlanDataService.Transport.MOBILE);
690 
691         doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
692 
693         lenient()
694                 .when(
695                         IwlanHelper.isCrossSimCallingEnabled(
696                                 eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
697                 .thenReturn(true);
698         lenient()
699                 .when(IwlanHelper.isDefaultDataSlot(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
700                 .thenReturn(false);
701 
702         mSpyIwlanDataServiceProvider.setupDataCall(
703                 AccessNetworkType.IWLAN, /* AccessNetworkType */
704                 dp, /* dataProfile */
705                 false, /* isRoaming */
706                 true, /* allowRoaming */
707                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
708                 null, /* LinkProperties */
709                 1, /* pduSessionId */
710                 null, /* sliceInfo */
711                 null, /* trafficDescriptor */
712                 true, /* matchAllRuleAllowed */
713                 mMockDataServiceCallback);
714 
715         /* Check bringUpTunnel() is called. */
716         verify(mMockEpdgTunnelManager, times(1))
717                 .bringUpTunnel(any(TunnelSetupRequest.class), any(IwlanTunnelCallback.class));
718 
719         /* Check callback result is RESULT_SUCCESS when onOpened() is called. */
720         mSpyIwlanDataServiceProvider
721                 .getIwlanTunnelCallback()
722                 .onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
723         verify(mMockDataServiceCallback, times(1))
724                 .onSetupDataCallComplete(
725                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
726     }
727 
728     @Test
testIwlanTunnelStatsFailureCounts()729     public void testIwlanTunnelStatsFailureCounts() {
730         DataProfile dp = buildDataProfile();
731 
732         mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
733         doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
734         when(ErrorPolicyManager.getInstance(eq(mMockContext), eq(DEFAULT_SLOT_INDEX)))
735                 .thenReturn(mMockErrorPolicyManager);
736 
737         long count = 3L;
738         for (int i = 0; i < count; i++) {
739             mockTunnelSetupFail(dp);
740             sleep(1000);
741         }
742 
743         IwlanDataServiceProvider.IwlanDataTunnelStats stats =
744                 mSpyIwlanDataServiceProvider.getTunnelStats();
745         long result = stats.mTunnelSetupFailureCounts.get(TEST_APN_NAME);
746         assertEquals(result, count);
747     }
748 
749     @Test
testIwlanTunnelStatsUnsolDownCounts()750     public void testIwlanTunnelStatsUnsolDownCounts() {
751         DataProfile dp = buildDataProfile();
752 
753         mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
754         doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
755 
756         long count = 3L;
757         for (int i = 0; i < count; i++) {
758             mockTunnelSetupSuccess(dp, 0);
759             mockUnsolTunnelDown();
760         }
761 
762         IwlanDataServiceProvider.IwlanDataTunnelStats stats =
763                 mSpyIwlanDataServiceProvider.getTunnelStats();
764         long result = stats.mUnsolTunnelDownCounts.get(TEST_APN_NAME);
765         assertEquals(result, count);
766     }
767 
768     @Test
testIwlanTunnelStats()769     public void testIwlanTunnelStats() {
770         DataProfile dp = buildDataProfile();
771 
772         mIwlanDataService.setNetworkConnected(true, mMockNetwork, IwlanDataService.Transport.WIFI);
773         doReturn(mMockEpdgTunnelManager).when(mSpyIwlanDataServiceProvider).getTunnelManager();
774 
775         LongSummaryStatistics tunnelSetupSuccessStats = new LongSummaryStatistics();
776         LongSummaryStatistics tunnelUpStats = new LongSummaryStatistics();
777 
778         Date beforeSetup = Calendar.getInstance().getTime();
779         mockTunnelSetupSuccess(dp, 0);
780         Date tunnelUp = Calendar.getInstance().getTime();
781         mockDeactivateTunnelDown(0);
782         Date tunnelDown = Calendar.getInstance().getTime();
783         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
784         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
785 
786         beforeSetup = Calendar.getInstance().getTime();
787         mockTunnelSetupSuccess(dp, 1000);
788         tunnelUp = Calendar.getInstance().getTime();
789         mockDeactivateTunnelDown(3000);
790         tunnelDown = Calendar.getInstance().getTime();
791         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
792         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
793 
794         beforeSetup = Calendar.getInstance().getTime();
795         mockTunnelSetupSuccess(dp, 600);
796         tunnelUp = Calendar.getInstance().getTime();
797         mockDeactivateTunnelDown(500);
798         tunnelDown = Calendar.getInstance().getTime();
799         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
800         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
801 
802         IwlanDataServiceProvider.IwlanDataTunnelStats stats =
803                 mSpyIwlanDataServiceProvider.getTunnelStats();
804         LongSummaryStatistics finalSetupStats = stats.mTunnelSetupSuccessStats.get(TEST_APN_NAME);
805         LongSummaryStatistics finalUpStats = stats.mTunnelUpStats.get(TEST_APN_NAME);
806 
807         assertEquals(finalSetupStats.getAverage(), tunnelSetupSuccessStats.getAverage(), 100);
808         assertEquals(finalSetupStats.getCount(), tunnelSetupSuccessStats.getCount());
809         assertEquals(finalSetupStats.getMax(), tunnelSetupSuccessStats.getMax(), 100);
810 
811         assertEquals(finalUpStats.getAverage(), tunnelUpStats.getAverage(), 100);
812         assertEquals(finalUpStats.getCount(), tunnelUpStats.getCount());
813         assertEquals(finalUpStats.getMax(), tunnelUpStats.getMax(), 100);
814     }
815 
mockTunnelSetupFail(DataProfile dp)816     private void mockTunnelSetupFail(DataProfile dp) {
817         mSpyIwlanDataServiceProvider.setupDataCall(
818                 AccessNetworkType.IWLAN, /* AccessNetworkType */
819                 dp, /* dataProfile */
820                 false, /* isRoaming */
821                 true, /* allowRoaming */
822                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
823                 null, /* LinkProperties */
824                 1, /* pduSessionId */
825                 null, /* sliceInfo */
826                 null, /* trafficDescriptor */
827                 true, /* matchAllRuleAllowed */
828                 mMockDataServiceCallback);
829         doReturn(true)
830                 .when(mMockEpdgTunnelManager)
831                 .bringUpTunnel(any(TunnelSetupRequest.class), any(IwlanTunnelCallback.class));
832 
833         mSpyIwlanDataServiceProvider
834                 .getIwlanTunnelCallback()
835                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION));
836         verify(mMockDataServiceCallback, atLeastOnce())
837                 .onSetupDataCallComplete(
838                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
839     }
840 
mockTunnelSetupSuccess(DataProfile dp, long sleepTime)841     private void mockTunnelSetupSuccess(DataProfile dp, long sleepTime) {
842         mSpyIwlanDataServiceProvider.setupDataCall(
843                 AccessNetworkType.IWLAN, /* AccessNetworkType */
844                 dp, /* dataProfile */
845                 false, /* isRoaming */
846                 true, /* allowRoaming */
847                 DataService.REQUEST_REASON_NORMAL, /* DataService.REQUEST_REASON_NORMAL */
848                 null, /* LinkProperties */
849                 1, /* pduSessionId */
850                 null, /* sliceInfo */
851                 null, /* trafficDescriptor */
852                 true, /* matchAllRuleAllowed */
853                 mMockDataServiceCallback);
854         doReturn(true)
855                 .when(mMockEpdgTunnelManager)
856                 .bringUpTunnel(any(TunnelSetupRequest.class), any(IwlanTunnelCallback.class));
857 
858         sleep(sleepTime);
859 
860         mSpyIwlanDataServiceProvider
861                 .getIwlanTunnelCallback()
862                 .onOpened(TEST_APN_NAME, mMockTunnelLinkProperties);
863         verify(mMockDataServiceCallback, atLeastOnce())
864                 .onSetupDataCallComplete(
865                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
866     }
867 
mockUnsolTunnelDown()868     private void mockUnsolTunnelDown() {
869         mSpyIwlanDataServiceProvider
870                 .getIwlanTunnelCallback()
871                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION));
872     }
873 
mockDeactivateTunnelDown(long sleepTime)874     private void mockDeactivateTunnelDown(long sleepTime) {
875         mSpyIwlanDataServiceProvider.deactivateDataCall(
876                 TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
877                 DataService.REQUEST_REASON_NORMAL /* DataService.REQUEST_REASON_NORMAL */,
878                 mMockDataServiceCallback);
879         verify(mMockEpdgTunnelManager, atLeastOnce()).closeTunnel(eq(TEST_APN_NAME), anyBoolean());
880 
881         sleep(sleepTime);
882 
883         mSpyIwlanDataServiceProvider
884                 .getIwlanTunnelCallback()
885                 .onClosed(TEST_APN_NAME, new IwlanError(IwlanError.NO_ERROR));
886         verify(mMockDataServiceCallback, atLeastOnce())
887                 .onDeactivateDataCallComplete(eq(DataServiceCallback.RESULT_SUCCESS));
888     }
889 }
890