• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.android.internal.telephony.dataconnection;
18 
19 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
20 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
21 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
22 
23 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
24 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
25 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
26 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
27 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
28 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
29 
30 import static org.junit.Assert.assertEquals;
31 import static org.junit.Assert.assertFalse;
32 import static org.junit.Assert.assertTrue;
33 import static org.mockito.ArgumentMatchers.anyString;
34 import static org.mockito.Matchers.argThat;
35 import static org.mockito.Mockito.any;
36 import static org.mockito.Mockito.anyBoolean;
37 import static org.mockito.Mockito.anyInt;
38 import static org.mockito.Mockito.atLeastOnce;
39 import static org.mockito.Mockito.doAnswer;
40 import static org.mockito.Mockito.doReturn;
41 import static org.mockito.Mockito.eq;
42 import static org.mockito.Mockito.mock;
43 import static org.mockito.Mockito.times;
44 import static org.mockito.Mockito.verify;
45 
46 import android.net.InetAddresses;
47 import android.net.KeepalivePacketData;
48 import android.net.LinkAddress;
49 import android.net.LinkProperties;
50 import android.net.NattKeepalivePacketData;
51 import android.net.Network;
52 import android.net.NetworkCapabilities;
53 import android.os.AsyncResult;
54 import android.os.Handler;
55 import android.os.HandlerThread;
56 import android.os.Message;
57 import android.telephony.AccessNetworkConstants;
58 import android.telephony.AccessNetworkConstants.AccessNetworkType;
59 import android.telephony.CarrierConfigManager;
60 import android.telephony.ServiceState;
61 import android.telephony.ServiceState.RegState;
62 import android.telephony.ServiceState.RilRadioTechnology;
63 import android.telephony.data.ApnSetting;
64 import android.telephony.data.DataCallResponse;
65 import android.telephony.data.DataProfile;
66 import android.telephony.data.DataService;
67 import android.telephony.data.DataServiceCallback;
68 import android.telephony.data.TrafficDescriptor;
69 import android.test.suitebuilder.annotation.MediumTest;
70 import android.test.suitebuilder.annotation.SmallTest;
71 import android.util.Pair;
72 
73 import com.android.internal.R;
74 import com.android.internal.telephony.PhoneConstants;
75 import com.android.internal.telephony.RetryManager;
76 import com.android.internal.telephony.TelephonyTest;
77 import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams;
78 import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams;
79 import com.android.internal.telephony.dataconnection.DataConnection.SetupResult;
80 import com.android.internal.telephony.metrics.DataCallSessionStats;
81 
82 import org.junit.After;
83 import org.junit.Before;
84 import org.junit.Test;
85 import org.mockito.ArgumentCaptor;
86 import org.mockito.Mock;
87 
88 import java.lang.reflect.Field;
89 import java.lang.reflect.Method;
90 import java.util.ArrayList;
91 import java.util.Arrays;
92 import java.util.Collections;
93 import java.util.function.Consumer;
94 
95 public class DataConnectionTest extends TelephonyTest {
96     private static final int DEFAULT_DC_CID = 10;
97 
98     @Mock
99     DcTesterFailBringUpAll mDcTesterFailBringUpAll;
100     @Mock
101     ConnectionParams mCp;
102     @Mock
103     DisconnectParams mDcp;
104     @Mock
105     ApnContext mApnContext;
106     @Mock
107     ApnContext mEnterpriseApnContext;
108     @Mock
109     DcFailBringUp mDcFailBringUp;
110     @Mock
111     DataCallSessionStats mDataCallSessionStats;
112     @Mock
113     DataConnection mDefaultDc;
114     @Mock
115     DataServiceManager mDataServiceManager;
116 
117     private DataConnection mDc;
118     private DataConnectionTestHandler mDataConnectionTestHandler;
119     private DcController mDcc;
120 
121     private ApnSetting mApn1 = ApnSetting.makeApnSetting(
122             2163,                   // id
123             "44010",                // numeric
124             "sp-mode",              // name
125             "spmode.ne.jp",         // apn
126             null,                   // proxy
127             -1,                     // port
128             null,                   // mmsc
129             null,                   // mmsproxy
130             -1,                     // mmsport
131             "",                     // user
132             "",                     // password
133             -1,                     // authtype
134             ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
135             ApnSetting.PROTOCOL_IP, // protocol
136             ApnSetting.PROTOCOL_IP, // roaming_protocol
137             true,                   // carrier_enabled
138             0,                      // networktype_bitmask
139             0,                      // profile_id
140             false,                  // modem_cognitive
141             0,                      // max_conns
142             0,                      // wait_time
143             0,                      // max_conns_time
144             0,                      // mtu
145             -1,                     // mvno_type
146             "");                    // mnvo_match_data
147 
148     private ApnSetting mApn2 = ApnSetting.makeApnSetting(
149             2164,                   // id
150             "44010",                // numeric
151             "sp-mode",              // name
152             "spmode.ne.jp",         // apn
153             null,                   // proxy
154             -1,                     // port
155             null,                   // mmsc
156             null,                   // mmsproxy
157             -1,                     // mmsport
158             "",                     // user
159             "",                     // password
160             -1,                     // authtype
161             ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN, // types
162             ApnSetting.PROTOCOL_IP, // protocol
163             ApnSetting.PROTOCOL_IP, // roaming_protocol
164             true,                   // carrier_enabled
165             0,                      // networktype_bitmask
166             0,                      // profile_id
167             false,                  // modem_cognitive
168             0,                      // max_conns
169             0,                      // wait_time
170             0,                      // max_conns_time
171             0,                      // mtu
172             -1,                     // mvno_type
173             "");                    // mnvo_match_data
174 
175     private ApnSetting mApn3 = ApnSetting.makeApnSetting(
176             2165,                   // id
177             "44010",                // numeric
178             "sp-mode",              // name
179             "spmode.ne.jp",         // apn
180             null,                   // proxy
181             -1,                     // port
182             null,                   // mmsc
183             null,                   // mmsproxy
184             -1,                     // mmsport
185             "",                     // user
186             "",                     // password
187             -1,                     // authtype
188             ApnSetting.TYPE_DEFAULT, // types
189             ApnSetting.PROTOCOL_IPV6, // protocol
190             ApnSetting.PROTOCOL_IP, // roaming_protocol
191             true,                   // carrier_enabled
192             0,                      // networktype_bitmask
193             0,                      // profile_id
194             false,                  // modem_cognitive
195             0,                      // max_conns
196             0,                      // wait_time
197             0,                      // max_conns_time
198             0,                      // mtu
199             -1,                     // mvno_type
200             "",                     // mnvo_match_data
201             0,                      // apn_set_id
202             -1,                     // carrier_id
203             1);                     // skip_464xlat
204 
205     private ApnSetting mApn4 = ApnSetting.makeApnSetting(
206             2166,                   // id
207             "44010",                // numeric
208             "sp-mode",              // name
209             "spmode.ne.jp",         // apn
210             null,                   // proxy
211             -1,                     // port
212             null,                   // mmsc
213             null,                   // mmsproxy
214             -1,                     // mmsport
215             "",                     // user
216             "",                     // password
217             -1,                     // authtype
218             ApnSetting.TYPE_IMS,    // types
219             ApnSetting.PROTOCOL_IPV6, // protocol
220             ApnSetting.PROTOCOL_IP, // roaming_protocol
221             true,                   // carrier_enabled
222             0,                      // networktype_bitmask
223             0,                      // profile_id
224             false,                  // modem_cognitive
225             0,                      // max_conns
226             0,                      // wait_time
227             0,                      // max_conns_time
228             0,                      // mtu
229             -1,                     // mvno_type
230             "");                    // mnvo_match_data
231 
232     private ApnSetting mApn5 = ApnSetting.makeApnSetting(
233             2167,                   // id
234             "44010",                // numeric
235             "sp-mode",              // name
236             "spmode.ne.jp",         // apn
237             null,                   // proxy
238             -1,                     // port
239             null,                   // mmsc
240             null,                   // mmsproxy
241             -1,                     // mmsport
242             "",                     // user
243             "",                     // password
244             -1,                     // authtype
245             ApnSetting.TYPE_IMS,    // types
246             ApnSetting.PROTOCOL_IPV6, // protocol
247             ApnSetting.PROTOCOL_IP, // roaming_protocol
248             true,                   // carrier_enabled
249             0,                      // networktype_bitmask
250             0,                      // profile_id
251             false,                  // modem_cognitive
252             0,                      // max_conns
253             0,                      // wait_time
254             0,                      // max_conns_time
255             0,                      // mtu
256             -1,                     // mvno_type
257             "",                     // mnvo_match_data
258             0,                      // apn_set_id
259             -1,                     // carrier_id
260             0);                     // skip_464xlat
261 
262     private ApnSetting mApn6 = ApnSetting.makeApnSetting(
263             2168,                   // id
264             "44010",                // numeric
265             "sp-mode",              // name
266             "spmode.ne.jp",         // apn
267             null,                   // proxy
268             -1,                     // port
269             null,                   // mmsc
270             null,                   // mmsproxy
271             -1,                     // mmsport
272             "",                     // user
273             "",                     // password
274             -1,                     // authtype
275             ApnSetting.TYPE_EMERGENCY, // types
276             ApnSetting.PROTOCOL_IP, // protocol
277             ApnSetting.PROTOCOL_IP, // roaming_protocol
278             true,                   // carrier_enabled
279             0,                      // networktype_bitmask
280             0,                      // profile_id
281             false,                  // modem_cognitive
282             0,                      // max_conns
283             0,                      // wait_time
284             0,                      // max_conns_time
285             0,                      // mtu
286             -1,                     // mvno_type
287             "");                    // mnvo_match_data
288 
289     private class DataConnectionTestHandler extends HandlerThread {
290 
DataConnectionTestHandler(String name)291         private DataConnectionTestHandler(String name) {
292             super(name);
293         }
294 
295         @Override
onLooperPrepared()296         public void onLooperPrepared() {
297             Handler h = new Handler();
298             mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, h.getLooper(), "");
299             mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDataServiceManager,
300                     mDcTesterFailBringUpAll, mDcc, true);
301         }
302     }
303 
setSuccessfulSetupDataResponse(int cid)304     private void setSuccessfulSetupDataResponse(int cid) {
305         doAnswer(invocation -> {
306             final Message msg = (Message) invocation.getArguments()[10];
307 
308             DataCallResponse response = new DataCallResponse.Builder()
309                     .setCause(0)
310                     .setRetryDurationMillis(-1L)
311                     .setId(cid)
312                     .setLinkStatus(2)
313                     .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
314                     .setInterfaceName("ifname")
315                     .setAddresses(Arrays.asList(
316                             new LinkAddress(InetAddresses.parseNumericAddress("10.0.2.15"), 32),
317                             new LinkAddress("2607:fb90:a620:651d:eabe:f8da:c107:44be/64")))
318                     .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
319                             InetAddresses.parseNumericAddress("fd00:976a::9")))
320                     .setGatewayAddresses(Arrays.asList(
321                             InetAddresses.parseNumericAddress("10.0.2.15"),
322                             InetAddresses.parseNumericAddress("fe80::2")))
323                     .setPcscfAddresses(Arrays.asList(
324                             InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
325                             InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
326                             InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
327                     .setMtu(1500)
328                     .setMtuV4(1500)
329                     .setMtuV6(1500)
330                     .setPduSessionId(1)
331                     .setQosBearerSessions(new ArrayList<>())
332                     .setTrafficDescriptors(new ArrayList<>())
333                     .build();
334             msg.getData().putParcelable("data_call_response", response);
335             msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
336             msg.sendToTarget();
337             return null;
338         }).when(mDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
339                 anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
340                 any(Message.class));
341     }
342 
setFailedSetupDataResponse(@ataServiceCallback.ResultCode int resultCode)343     private void setFailedSetupDataResponse(@DataServiceCallback.ResultCode int resultCode) {
344         doAnswer(invocation -> {
345             final Message msg = (Message) invocation.getArguments()[10];
346             msg.arg1 = resultCode;
347             msg.sendToTarget();
348             return null;
349         }).when(mDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
350                 anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
351                 any(Message.class));
352     }
353 
354     @Before
setUp()355     public void setUp() throws Exception {
356         super.setUp(getClass().getSimpleName());
357         logd("+Setup!");
358         doReturn("fake.action_detached").when(mPhone).getActionDetached();
359         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
360         replaceInstance(ConnectionParams.class, "mRilRat", mCp,
361                 ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
362         doReturn(mApn1).when(mApnContext).getApnSetting();
363         doReturn(ApnSetting.TYPE_DEFAULT_STRING).when(mApnContext).getApnType();
364         doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask();
365 
366         mDcFailBringUp.saveParameters(0, 0, -2);
367         doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp();
368 
369         mContextFixture.putStringArrayResource(com.android.internal.R.array
370                 .config_mobile_tcp_buffers, new String[]{
371                 "umts:131072,262144,1452032,4096,16384,399360",
372                 "hspa:131072,262144,2441216,4096,16384,399360",
373                 "hsupa:131072,262144,2441216,4096,16384,399360",
374                 "hsdpa:131072,262144,2441216,4096,16384,399360",
375                 "hspap:131072,262144,2441216,4096,16384,399360",
376                 "edge:16384,32768,131072,4096,16384,65536",
377                 "gprs:4096,8192,24576,4096,8192,24576",
378                 "1xrtt:16384,32768,131070,4096,16384,102400",
379                 "evdo:131072,262144,1048576,4096,16384,524288",
380                 "lte:524288,1048576,8388608,262144,524288,4194304"});
381 
382         mContextFixture.putResource(R.string.config_wwan_data_service_package,
383                 "com.android.phone");
384 
385         mDcp.mApnContext = mApnContext;
386 
387         setSuccessfulSetupDataResponse(DEFAULT_DC_CID);
388 
389         doAnswer(invocation -> {
390             final Message msg = (Message) invocation.getArguments()[2];
391             msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
392             msg.sendToTarget();
393             return null;
394         }).when(mDataServiceManager).deactivateDataCall(anyInt(), anyInt(), any(Message.class));
395 
396         doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mDataServiceManager)
397                 .getTransportType();
398 
399         mDataConnectionTestHandler = new DataConnectionTestHandler(getClass().getSimpleName());
400         mDataConnectionTestHandler.start();
401 
402         waitForMs(200);
403         mDc.setDataCallSessionStats(mDataCallSessionStats);
404 
405         logd("-Setup!");
406     }
407 
408     @After
tearDown()409     public void tearDown() throws Exception {
410         logd("tearDown");
411         mDc = null;
412         mDcc = null;
413         mDataConnectionTestHandler.quit();
414         mDataConnectionTestHandler.join();
415         super.tearDown();
416     }
417 
getSuggestedRetryDelay(DataCallResponse response)418     private long getSuggestedRetryDelay(DataCallResponse response) throws Exception {
419         Class[] cArgs = new Class[1];
420         cArgs[0] = DataCallResponse.class;
421         Method method = DataConnection.class.getDeclaredMethod("getSuggestedRetryDelay", cArgs);
422         method.setAccessible(true);
423         return (long) method.invoke(mDc, response);
424     }
425 
isUnmeteredUseOnly()426     private boolean isUnmeteredUseOnly() throws Exception {
427         Method method = DataConnection.class.getDeclaredMethod("isUnmeteredUseOnly");
428         method.setAccessible(true);
429         return (boolean) method.invoke(mDc);
430     }
431 
isEnterpriseUse()432     private boolean isEnterpriseUse() throws Exception {
433         Method method = DataConnection.class.getDeclaredMethod("isEnterpriseUse");
434         method.setAccessible(true);
435         return (boolean) method.invoke(mDc);
436     }
437 
isSuspended()438     private boolean isSuspended() throws Exception {
439         Field field = DataConnection.class.getDeclaredField("mIsSuspended");
440         field.setAccessible(true);
441         return field.getBoolean(mDc);
442     }
443 
setLinkProperties(DataCallResponse response, LinkProperties linkProperties)444     private SetupResult setLinkProperties(DataCallResponse response, LinkProperties linkProperties)
445             throws Exception {
446         Class[] cArgs = new Class[2];
447         cArgs[0] = DataCallResponse.class;
448         cArgs[1] = LinkProperties.class;
449         Method method = DataConnection.class.getDeclaredMethod("setLinkProperties", cArgs);
450         method.setAccessible(true);
451         return (SetupResult) method.invoke(mDc, response, linkProperties);
452     }
453 
454     @Test
455     @SmallTest
testConnectEvent()456     public void testConnectEvent() {
457         assertTrue(mDc.isInactive());
458         connectEvent(true);
459 
460         verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class),
461                 eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null));
462         verify(mCT, times(1)).registerForVoiceCallEnded(any(Handler.class),
463                 eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED), eq(null));
464         verify(mSimulatedCommandsVerifier, times(1))
465                 .registerForNattKeepaliveStatus(any(Handler.class),
466                         eq(DataConnection.EVENT_KEEPALIVE_STATUS), eq(null));
467         verify(mSimulatedCommandsVerifier, times(1))
468                 .registerForLceInfo(any(Handler.class),
469                         eq(DataConnection.EVENT_LINK_CAPACITY_CHANGED), eq(null));
470         verify(mVcnManager, atLeastOnce())
471                 .applyVcnNetworkPolicy(
472                         argThat(caps ->
473                                 caps.hasCapability(
474                                         NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)),
475                         any());
476 
477         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
478         ArgumentCaptor<TrafficDescriptor> tdCaptor =
479                 ArgumentCaptor.forClass(TrafficDescriptor.class);
480         verify(mDataServiceManager, times(1)).setupDataCall(
481                 eq(AccessNetworkType.UTRAN), dpCaptor.capture(), eq(false),
482                 eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
483                 anyInt(), any(), tdCaptor.capture(), anyBoolean(), any(Message.class));
484 
485         verify(mSimulatedCommandsVerifier, times(1))
486                 .allocatePduSessionId(any());
487 
488         assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn());
489         if (tdCaptor.getValue() != null) {
490             if (mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
491                 assertEquals(null, tdCaptor.getValue().getDataNetworkName());
492                 assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
493                         tdCaptor.getValue().getOsAppId()));
494             } else {
495                 assertEquals("spmode.ne.jp", tdCaptor.getValue().getDataNetworkName());
496                 assertEquals(null, tdCaptor.getValue().getOsAppId());
497             }
498         }
499         assertTrue(mDc.isActive());
500 
501         assertEquals(mDc.getPduSessionId(), 1);
502         assertEquals(3, mDc.getPcscfAddresses().length);
503         assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::8"::equals));
504         assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c202:1d::7"::equals));
505         assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::5"::equals));
506     }
507 
508     @Test
testConnectEventDuplicateContextIds()509     public void testConnectEventDuplicateContextIds() throws Exception {
510         setUpDefaultData(DEFAULT_DC_CID);
511 
512         // Try to connect ENTERPRISE with the same CID as default
513         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
514         doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
515         doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
516         doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
517 
518         // Verify that ENTERPRISE wasn't set up
519         connectEvent(false);
520         assertTrue(mDc.isInactive());
521 
522         // Change the CID
523         setSuccessfulSetupDataResponse(DEFAULT_DC_CID + 1);
524 
525         // Verify that ENTERPRISE was set up
526         connectEvent(true);
527         assertTrue(mDc.getNetworkCapabilities().hasCapability(
528                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
529     }
530 
531     @Test
testConnectEventNoDefaultData()532     public void testConnectEventNoDefaultData() throws Exception {
533         assertFalse(mDefaultDc.isActive());
534 
535         // Try to connect ENTERPRISE when default data doesn't exist
536         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
537         doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
538         doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
539         doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
540 
541         // Verify that ENTERPRISE wasn't set up
542         connectEvent(false);
543         assertTrue(mDc.isInactive());
544 
545         // Set up default data
546         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
547         setUpDefaultData(1);
548 
549         // Verify that ENTERPRISE was set up
550         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
551         connectEvent(true);
552         assertTrue(mDc.getNetworkCapabilities().hasCapability(
553                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
554     }
555 
setUpDefaultData(int cid)556     private void setUpDefaultData(int cid) throws Exception {
557         replaceInstance(DataConnection.class, "mCid", mDefaultDc, cid);
558         doReturn(true).when(mDefaultDc).isActive();
559         doReturn(Arrays.asList(mApnContext)).when(mDefaultDc).getApnContexts();
560         mDcc.addActiveDcByCid(mDefaultDc);
561         assertTrue(mDefaultDc.getApnContexts().stream()
562                 .anyMatch(apn -> apn.getApnTypeBitmask() == ApnSetting.TYPE_DEFAULT));
563     }
564 
565     @Test
566     @SmallTest
testDisconnectEvent()567     public void testDisconnectEvent() {
568         testConnectEvent();
569 
570         mDc.setPduSessionId(5);
571         disconnectEvent();
572 
573         verify(mSimulatedCommandsVerifier, times(1)).unregisterForLceInfo(any(Handler.class));
574         verify(mSimulatedCommandsVerifier, times(1))
575                 .unregisterForNattKeepaliveStatus(any(Handler.class));
576         verify(mDataServiceManager, times(1)).deactivateDataCall(eq(DEFAULT_DC_CID),
577                 eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
578         verify(mSimulatedCommandsVerifier, times(1))
579                 .releasePduSessionId(any(), eq(5));
580 
581         assertTrue(mDc.isInactive());
582     }
583 
584     @Test
585     @SmallTest
testModemSuggestRetry()586     public void testModemSuggestRetry() throws Exception {
587         DataCallResponse response = new DataCallResponse.Builder()
588                 .setCause(0)
589                 .setRetryDurationMillis(0)
590                 .setId(1)
591                 .setLinkStatus(2)
592                 .setProtocolType(ApnSetting.PROTOCOL_IP)
593                 .setInterfaceName(FAKE_IFNAME)
594                 .setAddresses(Arrays.asList(
595                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
596                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
597                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
598                 .setPcscfAddresses(
599                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
600                 .setMtuV4(1440)
601                 .setMtuV6(1440)
602                 .build();
603         assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
604 
605         response = new DataCallResponse.Builder()
606                 .setCause(0)
607                 .setRetryDurationMillis(1000)
608                 .setId(1)
609                 .setLinkStatus(2)
610                 .setProtocolType(ApnSetting.PROTOCOL_IP)
611                 .setInterfaceName(FAKE_IFNAME)
612                 .setAddresses(Arrays.asList(
613                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
614                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
615                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
616                 .setPcscfAddresses(
617                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
618                 .setMtuV4(1440)
619                 .setMtuV6(1440)
620                 .build();
621         assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
622 
623         response = new DataCallResponse.Builder()
624                 .setCause(0)
625                 .setRetryDurationMillis(9999)
626                 .setId(1)
627                 .setLinkStatus(2)
628                 .setProtocolType(ApnSetting.PROTOCOL_IP)
629                 .setInterfaceName(FAKE_IFNAME)
630                 .setAddresses(Arrays.asList(
631                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
632                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
633                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
634                 .setPcscfAddresses(
635                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
636                 .setMtuV4(1440)
637                 .setMtuV6(1440)
638                 .build();
639         assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
640     }
641 
642     @Test
643     @SmallTest
testModemNotSuggestRetry()644     public void testModemNotSuggestRetry() throws Exception {
645         DataCallResponse response = new DataCallResponse.Builder()
646                 .setCause(0)
647                 .setRetryDurationMillis(-1)
648                 .setId(1)
649                 .setLinkStatus(2)
650                 .setProtocolType(ApnSetting.PROTOCOL_IP)
651                 .setInterfaceName(FAKE_IFNAME)
652                 .setAddresses(Arrays.asList(
653                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
654                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
655                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
656                 .setPcscfAddresses(
657                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
658                 .setMtuV4(1440)
659                 .setMtuV6(1440)
660                 .build();
661         assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
662 
663         response = new DataCallResponse.Builder()
664                 .setCause(0)
665                 .setRetryDurationMillis(-5)
666                 .setId(1)
667                 .setLinkStatus(2)
668                 .setProtocolType(ApnSetting.PROTOCOL_IP)
669                 .setInterfaceName(FAKE_IFNAME)
670                 .setAddresses(Arrays.asList(
671                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
672                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
673                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
674                 .setPcscfAddresses(
675                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
676                 .setMtuV4(1440)
677                 .setMtuV6(1440)
678                 .build();
679         assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
680 
681         response = new DataCallResponse.Builder()
682                 .setCause(0)
683                 .setRetryDurationMillis(Long.MIN_VALUE)
684                 .setId(1)
685                 .setLinkStatus(2)
686                 .setProtocolType(ApnSetting.PROTOCOL_IP)
687                 .setInterfaceName(FAKE_IFNAME)
688                 .setAddresses(Arrays.asList(
689                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
690                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
691                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
692                 .setPcscfAddresses(
693                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
694                 .setMtuV4(1440)
695                 .setMtuV6(1440)
696                 .build();
697         assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
698     }
699 
700     @Test
701     @SmallTest
testModemSuggestNoRetry()702     public void testModemSuggestNoRetry() throws Exception {
703         DataCallResponse response = new DataCallResponse.Builder()
704                 .setCause(0)
705                 .setRetryDurationMillis(Long.MAX_VALUE)
706                 .setId(1)
707                 .setLinkStatus(2)
708                 .setProtocolType(ApnSetting.PROTOCOL_IP)
709                 .setInterfaceName(FAKE_IFNAME)
710                 .setAddresses(Arrays.asList(
711                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
712                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
713                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
714                 .setPcscfAddresses(
715                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
716                 .setMtuV4(1440)
717                 .setMtuV6(1440)
718                 .build();
719         assertEquals(RetryManager.NO_RETRY, getSuggestedRetryDelay(response));
720     }
721 
getNetworkCapabilities()722     private NetworkCapabilities getNetworkCapabilities() throws Exception {
723         Method method = DataConnection.class.getDeclaredMethod("getNetworkCapabilities");
724         method.setAccessible(true);
725         return (NetworkCapabilities) method.invoke(mDc);
726     }
727 
getDisallowedApnTypes()728     private int getDisallowedApnTypes() throws Exception {
729         Method method = DataConnection.class.getDeclaredMethod("getDisallowedApnTypes");
730         method.setAccessible(true);
731         return (int) method.invoke(mDc);
732     }
733 
734     @Test
735     @SmallTest
testNetworkCapability()736     public void testNetworkCapability() throws Exception {
737         mContextFixture.getCarrierConfigBundle().putStringArray(
738                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
739                 new String[] { "default" });
740         doReturn(mApn2).when(mApnContext).getApnSetting();
741         testConnectEvent();
742 
743         assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
744                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN));
745         assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
746                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
747         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
748                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS));
749         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
750                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
751 
752         mContextFixture.getCarrierConfigBundle().putStringArray(
753                 CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
754                 new String[] {"supl"});
755 
756         disconnectEvent();
757         doReturn(mApn1).when(mApnContext).getApnSetting();
758         connectEvent(true);
759 
760         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
761                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN));
762         assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
763                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
764         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
765                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL));
766         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
767                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
768     }
769 
770     @Test
771     @SmallTest
testEnterpriseNetworkCapability()772     public void testEnterpriseNetworkCapability() throws Exception {
773         mContextFixture.getCarrierConfigBundle().putStringArray(
774                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
775                 new String[] { "default" });
776         doReturn(mApn2).when(mApnContext).getApnSetting();
777         testConnectEvent();
778 
779         assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
780                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN));
781         assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
782                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
783         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
784                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS));
785         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
786                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
787 
788         disconnectEvent();
789         setUpDefaultData(1);
790         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
791         doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
792         doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
793         doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
794         connectEvent(true);
795 
796         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
797                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN));
798         assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
799                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
800         assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
801                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL));
802         assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
803                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
804     }
805 
806     @Test
807     @SmallTest
testMeteredCapability()808     public void testMeteredCapability() throws Exception {
809 
810         mContextFixture.getCarrierConfigBundle().
811                 putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
812                 new String[] {"default"});
813 
814         testConnectEvent();
815 
816         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
817     }
818 
819     @Test
820     @SmallTest
testNonMeteredCapability()821     public void testNonMeteredCapability() throws Exception {
822 
823         doReturn(2819).when(mPhone).getSubId();
824         mContextFixture.getCarrierConfigBundle().
825                 putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
826                         new String[] {"mms"});
827 
828         testConnectEvent();
829 
830         assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
831     }
832 
833     @Test
testOverrideUnmetered()834     public void testOverrideUnmetered() throws Exception {
835         mContextFixture.getCarrierConfigBundle().putStringArray(
836                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
837                 new String[] { "default" });
838         testConnectEvent();
839 
840         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
841         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
842         assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
843 
844         mDc.onMeterednessChanged(true);
845         waitForMs(100);
846 
847         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
848         assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
849         assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
850 
851         mDc.onMeterednessChanged(false);
852         waitForMs(100);
853 
854         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
855         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
856         assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
857     }
858 
859     @Test
testOverrideCongested()860     public void testOverrideCongested() throws Exception {
861         mContextFixture.getCarrierConfigBundle().putStringArray(
862                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
863                 new String[] { "default" });
864         testConnectEvent();
865 
866         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
867         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
868         assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
869 
870         mDc.onCongestednessChanged(true);
871         waitForMs(100);
872 
873         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
874         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
875         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
876 
877         mDc.onCongestednessChanged(false);
878         waitForMs(100);
879 
880         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
881         assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
882         assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
883     }
884 
885     @Test
testSubscriptionIds()886     public void testSubscriptionIds() throws Exception {
887         mContextFixture.getCarrierConfigBundle().putStringArray(
888                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
889                 new String[] { "default" });
890         testConnectEvent();
891 
892         assertEquals(Collections.singleton(0), getNetworkCapabilities().getSubscriptionIds());
893     }
894 
895     @Test
testShouldSkip464Xlat()896     public void testShouldSkip464Xlat() throws Exception {
897         assertFalse(testShouldSkip464XlatEvent(mApn1));
898         disconnectEvent();
899 
900         assertTrue(testShouldSkip464XlatEvent(mApn3));
901         disconnectEvent();
902 
903         assertTrue(testShouldSkip464XlatEvent(mApn4));
904         disconnectEvent();
905 
906         assertFalse(testShouldSkip464XlatEvent(mApn5));
907         disconnectEvent();
908     }
909 
testShouldSkip464XlatEvent(ApnSetting apn)910     private boolean testShouldSkip464XlatEvent(ApnSetting apn) throws Exception {
911         Method method = DataConnection.class.getDeclaredMethod("shouldSkip464Xlat");
912         method.setAccessible(true);
913 
914         doReturn(apn).when(mApnContext).getApnSetting();
915         doReturn(apn.getApnTypeBitmask()).when(mApnContext).getApnTypeBitmask();
916         connectEvent(true);
917         logd(getNetworkCapabilities().toString());
918 
919         return (Boolean) method.invoke(mDc);
920     }
921 
connectEvent(boolean validate)922     private void connectEvent(boolean validate) {
923         mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
924         waitForMs(200);
925         if (validate) {
926             assertTrue(mDc.isActive());
927         }
928     }
929 
disconnectEvent()930     private void disconnectEvent() {
931         mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
932         waitForMs(100);
933         assertTrue(mDc.isInactive());
934     }
935 
serviceStateChangedEvent(@egState int dataRegState, @RilRadioTechnology int rat)936     private void serviceStateChangedEvent(@RegState int dataRegState, @RilRadioTechnology int rat) {
937         mDc.obtainMessage(DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED,
938                 new AsyncResult(null, new Pair<>(dataRegState, rat), null)).sendToTarget();
939         waitForMs(100);
940     }
941 
942     @Test
943     @SmallTest
testIsIpAddress()944     public void testIsIpAddress() {
945         // IPv4
946         assertTrue(DataConnection.isIpAddress("1.2.3.4"));
947         assertTrue(DataConnection.isIpAddress("127.0.0.1"));
948 
949         // IPv6
950         assertTrue(DataConnection.isIpAddress("::1"));
951         assertTrue(DataConnection.isIpAddress("2001:4860:800d::68"));
952     }
953 
954     @Test
955     @SmallTest
testSetLinkProperties()956     public void testSetLinkProperties() throws Exception {
957         DataCallResponse response = new DataCallResponse.Builder()
958                 .setCause(0)
959                 .setRetryDurationMillis(-1)
960                 .setId(1)
961                 .setLinkStatus(2)
962                 .setProtocolType(ApnSetting.PROTOCOL_IP)
963                 .setInterfaceName(FAKE_IFNAME)
964                 .setAddresses(Arrays.asList(
965                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
966                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
967                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
968                 .setPcscfAddresses(
969                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
970                 .setMtuV4(1440)
971                 .setMtuV6(1440)
972                 .build();
973 
974         LinkProperties linkProperties = new LinkProperties();
975         assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties));
976         logd(linkProperties.toString());
977         assertEquals(response.getInterfaceName(), linkProperties.getInterfaceName());
978         assertEquals(response.getAddresses().size(), linkProperties.getAddresses().size());
979         for (int i = 0; i < response.getAddresses().size(); ++i) {
980             assertEquals(response.getAddresses().get(i).getAddress(),
981                     InetAddresses.parseNumericAddress(linkProperties.getLinkAddresses().get(i)
982                             .getAddress().getHostAddress()));
983         }
984 
985         assertEquals(response.getDnsAddresses().size(), linkProperties.getDnsServers().size());
986         for (int i = 0; i < response.getDnsAddresses().size(); ++i) {
987             assertEquals("i = " + i, response.getDnsAddresses().get(i),
988                     InetAddresses.parseNumericAddress(
989                             linkProperties.getDnsServers().get(i).getHostAddress()));
990         }
991 
992         assertEquals(response.getGatewayAddresses().size(), linkProperties.getRoutes().size());
993         for (int i = 0; i < response.getGatewayAddresses().size(); ++i) {
994             assertEquals("i = " + i, response.getGatewayAddresses().get(i),
995                     InetAddresses.parseNumericAddress(linkProperties.getRoutes().get(i)
996                             .getGateway().getHostAddress()));
997         }
998 
999         assertEquals(response.getPcscfAddresses().size(), linkProperties.getPcscfServers().size());
1000         for (int i = 0; i < response.getPcscfAddresses().size(); ++i) {
1001             assertEquals("i = " + i, response.getPcscfAddresses().get(i),
1002                     InetAddresses.parseNumericAddress(linkProperties.getPcscfServers().get(i)
1003                             .getHostAddress()));
1004         }
1005 
1006         assertEquals(response.getMtu(), linkProperties.getMtu());
1007     }
1008 
1009     @Test
1010     @SmallTest
testSetLinkPropertiesEmptyAddress()1011     public void testSetLinkPropertiesEmptyAddress() throws Exception {
1012         // 224.224.224.224 is an invalid address.
1013         DataCallResponse response = new DataCallResponse.Builder()
1014                 .setCause(0)
1015                 .setRetryDurationMillis(-1)
1016                 .setId(1)
1017                 .setLinkStatus(2)
1018                 .setProtocolType(ApnSetting.PROTOCOL_IP)
1019                 .setInterfaceName(FAKE_IFNAME)
1020                 .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
1021                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
1022                 .setPcscfAddresses(
1023                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
1024                 .setMtuV4(1440)
1025                 .setMtuV6(1440)
1026                 .build();
1027 
1028         LinkProperties linkProperties = new LinkProperties();
1029         assertEquals(SetupResult.ERROR_INVALID_ARG, setLinkProperties(response, linkProperties));
1030     }
1031 
1032     @Test
1033     @SmallTest
testSetLinkPropertiesEmptyDns()1034     public void testSetLinkPropertiesEmptyDns() throws Exception {
1035         // Empty dns entry.
1036         DataCallResponse response = new DataCallResponse.Builder()
1037                 .setCause(0)
1038                 .setRetryDurationMillis(-1)
1039                 .setId(1)
1040                 .setLinkStatus(2)
1041                 .setProtocolType(ApnSetting.PROTOCOL_IP)
1042                 .setInterfaceName(FAKE_IFNAME)
1043                 .setAddresses(Arrays.asList(
1044                         new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
1045                 .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
1046                 .setPcscfAddresses(
1047                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
1048                 .setMtuV4(1440)
1049                 .setMtuV6(1440)
1050                 .build();
1051 
1052         // Make sure no exception was thrown
1053         LinkProperties linkProperties = new LinkProperties();
1054         assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties));
1055     }
1056 
1057     @Test
1058     @SmallTest
testStartKeepaliveWLAN()1059     public void testStartKeepaliveWLAN() throws Exception {
1060         testConnectEvent();
1061         waitForMs(200);
1062 
1063         Field field = DataConnection.class.getDeclaredField("mTransportType");
1064         field.setAccessible(true);
1065         field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
1066 
1067         final int sessionHandle = 0xF00;
1068         final int slotId = 3;
1069         final int interval = 10; // seconds
1070         // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
1071         // and check that the packet is sent to the RIL.
1072         KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
1073                 InetAddresses.parseNumericAddress("1.2.3.4"),
1074                 1234,
1075                 InetAddresses.parseNumericAddress("8.8.8.8"),
1076                 4500);
1077         mDc.obtainMessage(
1078                 DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget();
1079         waitForMs(100);
1080         // testStartStopNattKeepalive() verifies that this request is passed with WWAN.
1081         // Thus, even though we can't see the response in NetworkAgent, we can verify that the
1082         // CommandsInterface never receives a request and infer that it was dropped due to WLAN.
1083         verify(mSimulatedCommandsVerifier, times(0))
1084                 .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
1085     }
1086 
checkStartStopNattKeepalive(boolean useCondensedFlow)1087     public void checkStartStopNattKeepalive(boolean useCondensedFlow) throws Exception {
1088         testConnectEvent();
1089         waitForMs(200);
1090 
1091         final int sessionHandle = 0xF00;
1092         final int slotId = 3;
1093         final int interval = 10; // seconds
1094         // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
1095         // and check that the packet is sent to the RIL.
1096         KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
1097                 InetAddresses.parseNumericAddress("1.2.3.4"),
1098                 1234,
1099                 InetAddresses.parseNumericAddress("8.8.8.8"),
1100                 4500);
1101         mDc.obtainMessage(
1102                 DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget();
1103         waitForMs(100);
1104         verify(mSimulatedCommandsVerifier, times(1))
1105                 .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
1106 
1107         Message kaStarted = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STARTED, slotId, 0);
1108         if (useCondensedFlow) {
1109             // Send a singled condensed response that a keepalive have been requested and the
1110             // activation is completed. This flow should be used if the keepalive offload request
1111             // is handled by a high-priority signalling path.
1112             AsyncResult.forMessage(
1113                     kaStarted, new KeepaliveStatus(
1114                             sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
1115             kaStarted.sendToTarget();
1116         } else {
1117             // Send the sequential responses indicating first that the request was received and
1118             // then that the keepalive is running. This should create an active record of the
1119             // keepalive in DataConnection while permitting the status from a low priority or other
1120             // high-latency handler to activate the keepalive without blocking a request.
1121             AsyncResult.forMessage(
1122                     kaStarted, new KeepaliveStatus(
1123                             sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
1124             kaStarted.sendToTarget();
1125             Message kaRunning = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STATUS);
1126             AsyncResult.forMessage(
1127                     kaRunning, new KeepaliveStatus(
1128                             sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
1129             kaRunning.sendToTarget();
1130         }
1131         waitForMs(100);
1132 
1133         // Verify that we can stop the connection, which checks that the record in DataConnection
1134         // has a valid mapping between slotId (from network agent) to sessionHandle (from Radio).
1135         mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget();
1136         waitForMs(100);
1137         verify(mSimulatedCommandsVerifier, times(1))
1138                 .stopNattKeepalive(eq(sessionHandle), any(Message.class));
1139 
1140         Message kaStopped = mDc.obtainMessage(
1141                 DataConnection.EVENT_KEEPALIVE_STOPPED, sessionHandle, slotId);
1142         AsyncResult.forMessage(kaStopped);
1143         kaStopped.sendToTarget();
1144         // Verify that after the connection is stopped, the mapping for a Keepalive Session is
1145         // removed. Thus, subsequent calls to stop the same keepalive are ignored.
1146         mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget();
1147         waitForMs(100);
1148         // Check that the mock has not been called subsequent to the previous invocation
1149         // while avoiding the use of reset()
1150         verify(mSimulatedCommandsVerifier, times(1))
1151                 .stopNattKeepalive(anyInt(), any(Message.class));
1152     }
1153 
1154     @Test
1155     @MediumTest
testStartStopNattKeepalive()1156     public void testStartStopNattKeepalive() throws Exception {
1157         checkStartStopNattKeepalive(false);
1158     }
1159 
1160     @Test
1161     @MediumTest
testStartStopNattKeepaliveCondensed()1162     public void testStartStopNattKeepaliveCondensed() throws Exception {
1163         checkStartStopNattKeepalive(true);
1164     }
1165 
checkStartNattKeepaliveFail(boolean useCondensedFlow)1166     public void checkStartNattKeepaliveFail(boolean useCondensedFlow) throws Exception {
1167         testConnectEvent();
1168         waitForMs(200);
1169 
1170         final int sessionHandle = 0xF00;
1171         final int slotId = 3;
1172         final int interval = 10; // seconds
1173         // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
1174         // and check that the packet is sent to the RIL.
1175         KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
1176                 InetAddresses.parseNumericAddress("1.2.3.4"),
1177                 1234,
1178                 InetAddresses.parseNumericAddress("8.8.8.8"),
1179                 4500);
1180         mDc.obtainMessage(
1181                 DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget();
1182         waitForMs(100);
1183         verify(mSimulatedCommandsVerifier, times(1))
1184                 .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
1185 
1186         Message kaStarted = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STARTED, slotId, 0);
1187         if (useCondensedFlow) {
1188             // Indicate in the response that the keepalive has failed.
1189             AsyncResult.forMessage(
1190                     kaStarted, new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED), null);
1191             kaStarted.sendToTarget();
1192         } else {
1193             // Indicate that the keepalive is queued, and then signal a failure from the modem
1194             // such that a pending keepalive fails to activate.
1195             AsyncResult.forMessage(
1196                     kaStarted, new KeepaliveStatus(
1197                             sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
1198             kaStarted.sendToTarget();
1199             Message kaRunning = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STATUS);
1200             AsyncResult.forMessage(
1201                     kaRunning, new KeepaliveStatus(
1202                             sessionHandle, KeepaliveStatus.STATUS_INACTIVE), null);
1203             kaRunning.sendToTarget();
1204         }
1205         waitForMs(100);
1206         // Verify that a failed connection request cannot be stopped due to no record in
1207         // the DataConnection.
1208         mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget();
1209         waitForMs(100);
1210         verify(mSimulatedCommandsVerifier, times(0))
1211                 .stopNattKeepalive(anyInt(), any(Message.class));
1212     }
1213 
1214     @Test
1215     @SmallTest
testStartNattKeepaliveFail()1216     public void testStartNattKeepaliveFail() throws Exception {
1217         checkStartNattKeepaliveFail(false);
1218     }
1219 
1220     @Test
1221     @SmallTest
testStartNattKeepaliveFailCondensed()1222     public void testStartNattKeepaliveFailCondensed() throws Exception {
1223         checkStartNattKeepaliveFail(true);
1224     }
1225 
1226     @Test
1227     @SmallTest
testIsUnmeteredUseOnly()1228     public void testIsUnmeteredUseOnly() throws Exception {
1229         Field field = DataConnection.class.getDeclaredField("mTransportType");
1230         field.setAccessible(true);
1231         field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
1232 
1233         assertFalse(isUnmeteredUseOnly());
1234 
1235         field = DataConnection.class.getDeclaredField("mTransportType");
1236         field.setAccessible(true);
1237         field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1238 
1239         doReturn(false).when(mDataEnabledSettings).isDataEnabled();
1240         doReturn(false).when(mServiceState).getDataRoaming();
1241         doReturn(ApnSetting.TYPE_MMS).when(mApnContext).getApnTypeBitmask();
1242 
1243         mContextFixture.getCarrierConfigBundle().putStringArray(
1244                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
1245                 new String[] { "default" });
1246 
1247         assertTrue(isUnmeteredUseOnly());
1248     }
1249 
1250     @Test
testIsEnterpriseUse()1251     public void testIsEnterpriseUse() throws Exception {
1252         assertFalse(isEnterpriseUse());
1253         assertFalse(mDc.getNetworkCapabilities().hasCapability(
1254                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
1255 
1256         setUpDefaultData(1);
1257         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
1258         doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
1259         doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
1260         doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
1261         connectEvent(true);
1262 
1263         assertTrue(isEnterpriseUse());
1264         assertTrue(mDc.getNetworkCapabilities().hasCapability(
1265                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
1266     }
1267 
1268     @Test
1269     @SmallTest
testGetDisallowedApnTypes()1270     public void testGetDisallowedApnTypes() throws Exception {
1271         mContextFixture.getCarrierConfigBundle().putStringArray(
1272                 CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
1273                 new String[] { "mms", "supl", "fota" });
1274         testConnectEvent();
1275 
1276         assertEquals(ApnSetting.TYPE_MMS | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA,
1277                 getDisallowedApnTypes());
1278     }
1279 
1280     @Test
testIsSuspended()1281     public void testIsSuspended() throws Exception {
1282         // Return false if not active state
1283         assertTrue(mDc.isInactive());
1284         assertFalse(isSuspended());
1285 
1286         // Return false for emergency APN
1287         doReturn(mApn6).when(mApnContext).getApnSetting();
1288         doReturn(ApnSetting.TYPE_EMERGENCY).when(mApnContext).getApnTypeBitmask();
1289         connectEvent(true);
1290         assertFalse(isSuspended());
1291 
1292         // Back to DEFAULT APN
1293         disconnectEvent();
1294         assertTrue(mDc.isInactive());
1295         doReturn(mApn1).when(mApnContext).getApnSetting();
1296         doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask();
1297         doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
1298         connectEvent(true);
1299 
1300         // Before getting any service state event, the connection should not be suspended.
1301         assertFalse(isSuspended());
1302 
1303         // Return true if combined reg state is not in service
1304         serviceStateChangedEvent(ServiceState.STATE_OUT_OF_SERVICE,
1305                 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
1306         assertTrue(isSuspended());
1307 
1308         // Return false if in service and concurrent voice and data is allowed
1309         serviceStateChangedEvent(ServiceState.STATE_IN_SERVICE,
1310                 ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
1311         assertFalse(isSuspended());
1312 
1313         // Return false if in service and concurrent voice/data not allowed but call state is idle
1314         doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
1315         doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
1316         mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED);
1317         waitForMs(100);
1318         assertFalse(isSuspended());
1319 
1320         // Return true if in service, concurrent voice/data not allowed, and call state not idle
1321         doReturn(PhoneConstants.State.RINGING).when(mCT).getState();
1322         mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED);
1323         waitForMs(100);
1324         assertTrue(isSuspended());
1325     }
1326 
1327     @Test
testDataCreatedWhenOutOfService()1328     public void testDataCreatedWhenOutOfService() throws Exception {
1329         serviceStateChangedEvent(ServiceState.STATE_OUT_OF_SERVICE,
1330                 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
1331         ArgumentCaptor<NetworkCapabilities> ncCaptor =
1332                 ArgumentCaptor.forClass(NetworkCapabilities.class);
1333         doReturn(mock(Network.class)).when(mConnectivityManager).registerNetworkAgent(
1334                 any(), any(), any(), ncCaptor.capture(), any(), any(), anyInt());
1335 
1336         doReturn(mApn1).when(mApnContext).getApnSetting();
1337         doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask();
1338         doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
1339         connectEvent(true);
1340         waitForMs(100);
1341 
1342         NetworkCapabilities nc = ncCaptor.getValue();
1343         // The network must be created with NOT_SUSPENDED capability.
1344         assertTrue(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED));
1345 
1346         // But it's final state must be suspended.
1347         assertTrue(isSuspended());
1348     }
1349 
1350     @Test
testDataServiceTempUnavailable()1351     public void testDataServiceTempUnavailable() throws Exception {
1352         setFailedSetupDataResponse(DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE);
1353         replaceInstance(ConnectionParams.class, "mRequestType", mCp,
1354                 DcTracker.REQUEST_TYPE_NORMAL);
1355         // Verify that no data was setup
1356         connectEvent(false);
1357         assertTrue(mDc.isInactive());
1358 
1359         // Verify that data service did not suggest any retry (i.e. Frameworks uses configured
1360         // retry timer).
1361         verify(mDataThrottler).setRetryTime(eq(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL),
1362                 eq(RetryManager.NO_SUGGESTED_RETRY_DELAY), eq(DcTracker.REQUEST_TYPE_NORMAL));
1363     }
1364 
1365     @Test
testDataHandoverFailed()1366     public void testDataHandoverFailed() throws Exception {
1367         doReturn(mDefaultDc).when(mDcTracker).getDataConnectionByApnType(anyString());
1368 
1369         doAnswer(invocation -> {
1370             final Consumer<Integer> consumer = (Consumer<Integer>) invocation.getArguments()[0];
1371             consumer.accept(DataServiceCallback.RESULT_SUCCESS);
1372             return null;
1373         }).when(mDefaultDc).startHandover(any(Consumer.class));
1374 
1375         replaceInstance(ConnectionParams.class, "mRequestType", mCp,
1376                 DcTracker.REQUEST_TYPE_HANDOVER);
1377         assertTrue(mDc.isInactive());
1378         connectEvent(false);
1379 
1380         // Make sure the data connection is still in inactive state
1381         assertTrue(mDc.isInactive());
1382     }
1383 }
1384