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.NetworkPolicyManager.OVERRIDE_CONGESTED; 22 import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED; 23 24 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 25 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS; 26 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS; 27 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY; 28 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME; 29 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS; 30 31 import static org.junit.Assert.assertEquals; 32 import static org.junit.Assert.assertFalse; 33 import static org.junit.Assert.assertTrue; 34 import static org.mockito.ArgumentMatchers.any; 35 import static org.mockito.ArgumentMatchers.anyInt; 36 import static org.mockito.ArgumentMatchers.eq; 37 import static org.mockito.Mockito.doReturn; 38 import static org.mockito.Mockito.mock; 39 import static org.mockito.Mockito.times; 40 import static org.mockito.Mockito.verify; 41 42 import android.content.IntentFilter; 43 import android.content.pm.ServiceInfo; 44 import android.net.KeepalivePacketData; 45 import android.net.LinkAddress; 46 import android.net.LinkProperties; 47 import android.net.NetworkCapabilities; 48 import android.net.NetworkInfo; 49 import android.net.NetworkUtils; 50 import android.os.AsyncResult; 51 import android.os.Handler; 52 import android.os.HandlerThread; 53 import android.os.Message; 54 import android.telephony.AccessNetworkConstants.AccessNetworkType; 55 import android.telephony.AccessNetworkConstants.TransportType; 56 import android.telephony.CarrierConfigManager; 57 import android.telephony.ServiceState; 58 import android.telephony.data.DataCallResponse; 59 import android.telephony.data.DataProfile; 60 import android.telephony.data.DataService; 61 import android.test.suitebuilder.annotation.MediumTest; 62 import android.test.suitebuilder.annotation.SmallTest; 63 64 import com.android.internal.R; 65 import com.android.internal.telephony.PhoneConstants; 66 import com.android.internal.telephony.RetryManager; 67 import com.android.internal.telephony.TelephonyTest; 68 import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams; 69 import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams; 70 import com.android.internal.telephony.dataconnection.DataConnection.SetupResult; 71 import com.android.internal.util.IState; 72 import com.android.internal.util.StateMachine; 73 import com.android.server.pm.PackageManagerService; 74 75 import org.junit.After; 76 import org.junit.Before; 77 import org.junit.Test; 78 import org.mockito.ArgumentCaptor; 79 import org.mockito.Mock; 80 81 import java.lang.reflect.Field; 82 import java.lang.reflect.Method; 83 import java.util.Arrays; 84 85 public class DataConnectionTest extends TelephonyTest { 86 87 @Mock 88 DcTesterFailBringUpAll mDcTesterFailBringUpAll; 89 @Mock 90 ConnectionParams mCp; 91 @Mock 92 DisconnectParams mDcp; 93 @Mock 94 ApnContext mApnContext; 95 @Mock 96 DcFailBringUp mDcFailBringUp; 97 @Mock 98 PackageManagerService mMockPackageManagerInternal; 99 100 private DataConnection mDc; 101 private DataConnectionTestHandler mDataConnectionTestHandler; 102 private DcController mDcc; 103 104 private ApnSetting mApn1 = new ApnSetting( 105 2163, // id 106 "44010", // numeric 107 "sp-mode", // name 108 "spmode.ne.jp", // apn 109 "", // proxy 110 "", // port 111 "", // mmsc 112 "", // mmsproxy 113 "", // mmsport 114 "", // user 115 "", // password 116 -1, // authtype 117 new String[]{"default", "supl"}, // types 118 "IP", // protocol 119 "IP", // roaming_protocol 120 true, // carrier_enabled 121 0, // bearer 122 0, // bearer_bitmask 123 0, // profile_id 124 false, // modem_cognitive 125 0, // max_conns 126 0, // wait_time 127 0, // max_conns_time 128 0, // mtu 129 "", // mvno_type 130 ""); // mnvo_match_data 131 132 private ApnSetting mApn2 = new ApnSetting( 133 2164, // id 134 "44010", // numeric 135 "sp-mode", // name 136 "spmode.ne.jp", // apn 137 "", // proxy 138 "", // port 139 "", // mmsc 140 "", // mmsproxy 141 "", // mmsport 142 "", // user 143 "", // password 144 -1, // authtype 145 new String[]{"default", "dun"}, // types 146 "IP", // protocol 147 "IP", // roaming_protocol 148 true, // carrier_enabled 149 0, // bearer 150 0, // bearer_bitmask 151 0, // profile_id 152 false, // modem_cognitive 153 0, // max_conns 154 0, // wait_time 155 0, // max_conns_time 156 0, // mtu 157 "", // mvno_type 158 ""); // mnvo_match_data 159 160 private class DataConnectionTestHandler extends HandlerThread { 161 162 private DataConnectionTestHandler(String name) { 163 super(name); 164 } 165 166 @Override 167 public void onLooperPrepared() { 168 Handler h = new Handler(); 169 170 DataServiceManager manager = new DataServiceManager(mPhone, TransportType.WWAN); 171 mDcc = DcController.makeDcc(mPhone, mDcTracker, manager, h); 172 mDcc.start(); 173 mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, manager, 174 mDcTesterFailBringUpAll, mDcc); 175 } 176 } 177 178 private void addDataService() { 179 CellularDataService cellularDataService = new CellularDataService(); 180 ServiceInfo serviceInfo = new ServiceInfo(); 181 serviceInfo.packageName = "com.android.phone"; 182 serviceInfo.permission = "android.permission.BIND_DATA_SERVICE"; 183 IntentFilter filter = new IntentFilter(); 184 mContextFixture.addService( 185 DataService.DATA_SERVICE_INTERFACE, 186 null, 187 "com.android.phone", 188 cellularDataService.mBinder, 189 serviceInfo, 190 filter); 191 } 192 193 194 @Before 195 public void setUp() throws Exception { 196 logd("+Setup!"); 197 super.setUp(getClass().getSimpleName()); 198 mServiceManagerMockedServices.put("package", mMockPackageManagerInternal); 199 doReturn("fake.action_detached").when(mPhone).getActionDetached(); 200 replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext); 201 replaceInstance(ConnectionParams.class, "mRilRat", mCp, 202 ServiceState.RIL_RADIO_TECHNOLOGY_UMTS); 203 doReturn(mApn1).when(mApnContext).getApnSetting(); 204 doReturn(PhoneConstants.APN_TYPE_DEFAULT).when(mApnContext).getApnType(); 205 doReturn(true).when(mDcTracker).isDataEnabled(); 206 207 mDcFailBringUp.saveParameters(0, 0, -2); 208 doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp(); 209 210 mContextFixture.putStringArrayResource(com.android.internal.R.array. 211 config_mobile_tcp_buffers, new String[]{ 212 "umts:131072,262144,1452032,4096,16384,399360", 213 "hspa:131072,262144,2441216,4096,16384,399360", 214 "hsupa:131072,262144,2441216,4096,16384,399360", 215 "hsdpa:131072,262144,2441216,4096,16384,399360", 216 "hspap:131072,262144,2441216,4096,16384,399360", 217 "edge:16384,32768,131072,4096,16384,65536", 218 "gprs:4096,8192,24576,4096,8192,24576", 219 "1xrtt:16384,32768,131070,4096,16384,102400", 220 "evdo:131072,262144,1048576,4096,16384,524288", 221 "lte:524288,1048576,8388608,262144,524288,4194304"}); 222 223 mContextFixture.putResource(R.string.config_wwan_data_service_package, 224 "com.android.phone"); 225 226 mDcp.mApnContext = mApnContext; 227 228 addDataService(); 229 230 mDataConnectionTestHandler = new DataConnectionTestHandler(getClass().getSimpleName()); 231 mDataConnectionTestHandler.start(); 232 233 waitForMs(200); 234 logd("-Setup!"); 235 } 236 237 @After 238 public void tearDown() throws Exception { 239 logd("tearDown"); 240 mDc = null; 241 mDcc = null; 242 mDataConnectionTestHandler.quit(); 243 super.tearDown(); 244 } 245 246 private IState getCurrentState() throws Exception { 247 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 248 method.setAccessible(true); 249 return (IState) method.invoke(mDc); 250 } 251 252 private long getSuggestedRetryDelay(DataCallResponse response) throws Exception { 253 Class[] cArgs = new Class[1]; 254 cArgs[0] = DataCallResponse.class; 255 Method method = DataConnection.class.getDeclaredMethod("getSuggestedRetryDelay", cArgs); 256 method.setAccessible(true); 257 return (long) method.invoke(mDc, response); 258 } 259 260 private SetupResult setLinkProperties(DataCallResponse response, 261 LinkProperties linkProperties) 262 throws Exception { 263 Class[] cArgs = new Class[2]; 264 cArgs[0] = DataCallResponse.class; 265 cArgs[1] = LinkProperties.class; 266 Method method = DataConnection.class.getDeclaredMethod("setLinkProperties", cArgs); 267 method.setAccessible(true); 268 return (SetupResult) method.invoke(mDc, response, linkProperties); 269 } 270 271 @Test 272 @SmallTest 273 public void testSanity() throws Exception { 274 assertEquals("DcInactiveState", getCurrentState().getName()); 275 } 276 277 @Test 278 @SmallTest 279 public void testConnectEvent() throws Exception { 280 testSanity(); 281 282 mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp); 283 waitForMs(200); 284 285 verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class), 286 eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null)); 287 verify(mCT, times(1)).registerForVoiceCallEnded(any(Handler.class), 288 eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED), eq(null)); 289 verify(mSimulatedCommandsVerifier, times(1)) 290 .registerForNattKeepaliveStatus(any(Handler.class), 291 eq(DataConnection.EVENT_KEEPALIVE_STATUS), eq(null)); 292 verify(mSimulatedCommandsVerifier, times(1)) 293 .registerForLceInfo(any(Handler.class), 294 eq(DataConnection.EVENT_LINK_CAPACITY_CHANGED), eq(null)); 295 296 ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class); 297 verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( 298 eq(AccessNetworkType.UTRAN), dpCaptor.capture(), eq(false), 299 eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(), any(Message.class)); 300 301 assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn()); 302 303 assertEquals("DcActiveState", getCurrentState().getName()); 304 } 305 306 @Test 307 @SmallTest 308 public void testDisconnectEvent() throws Exception { 309 testConnectEvent(); 310 311 mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp); 312 waitForMs(100); 313 314 verify(mSimulatedCommandsVerifier, times(1)).unregisterForLceInfo(any(Handler.class)); 315 verify(mSimulatedCommandsVerifier, times(1)) 316 .unregisterForNattKeepaliveStatus(any(Handler.class)); 317 verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(eq(1), 318 eq(DataService.REQUEST_REASON_NORMAL), any(Message.class)); 319 320 assertEquals("DcInactiveState", getCurrentState().getName()); 321 } 322 323 @Test 324 @SmallTest 325 public void testModemSuggestRetry() throws Exception { 326 DataCallResponse response = new DataCallResponse(0, 0, 1, 2, "IP", FAKE_IFNAME, 327 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 328 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 329 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 330 Arrays.asList(FAKE_PCSCF_ADDRESS), 331 1440); 332 333 assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response)); 334 335 response = new DataCallResponse(0, 1000, 1, 2, "IP", FAKE_IFNAME, 336 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 337 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 338 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 339 Arrays.asList(FAKE_PCSCF_ADDRESS), 340 1440); 341 assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response)); 342 343 response = new DataCallResponse(0, 9999, 1, 2, "IP", FAKE_IFNAME, 344 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 345 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 346 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 347 Arrays.asList(FAKE_PCSCF_ADDRESS), 348 1440); 349 assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response)); 350 } 351 352 @Test 353 @SmallTest 354 public void testModemNotSuggestRetry() throws Exception { 355 DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME, 356 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 357 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 358 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 359 Arrays.asList(FAKE_PCSCF_ADDRESS), 360 1440); 361 362 assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response)); 363 364 response = new DataCallResponse(0, -5, 1, 2, "IP", FAKE_IFNAME, 365 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 366 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 367 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 368 Arrays.asList(FAKE_PCSCF_ADDRESS), 369 1440); 370 assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response)); 371 372 response = new DataCallResponse(0, Integer.MIN_VALUE, 1, 2, "IP", FAKE_IFNAME, 373 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 374 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 375 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 376 Arrays.asList(FAKE_PCSCF_ADDRESS), 377 1440); 378 assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response)); 379 } 380 381 @Test 382 @SmallTest 383 public void testModemSuggestNoRetry() throws Exception { 384 DataCallResponse response = new DataCallResponse(0, Integer.MAX_VALUE, 1, 2, "IP", 385 FAKE_IFNAME, 386 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 387 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 388 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 389 Arrays.asList(FAKE_PCSCF_ADDRESS), 390 1440); 391 assertEquals(RetryManager.NO_RETRY, getSuggestedRetryDelay(response)); 392 } 393 394 private NetworkInfo getNetworkInfo() throws Exception { 395 Field f = DataConnection.class.getDeclaredField("mNetworkInfo"); 396 f.setAccessible(true); 397 return (NetworkInfo) f.get(mDc); 398 } 399 400 private NetworkCapabilities getNetworkCapabilities() throws Exception { 401 Method method = DataConnection.class.getDeclaredMethod("getNetworkCapabilities"); 402 method.setAccessible(true); 403 return (NetworkCapabilities) method.invoke(mDc); 404 } 405 406 @Test 407 @SmallTest 408 public void testNetworkCapability() throws Exception { 409 mContextFixture.getCarrierConfigBundle().putStringArray( 410 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, 411 new String[] { "default" }); 412 doReturn(mApn2).when(mApnContext).getApnSetting(); 413 testConnectEvent(); 414 415 assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities() 416 .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)); 417 assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities() 418 .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 419 assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities() 420 .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)); 421 422 mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp); 423 waitForMs(100); 424 doReturn(mApn1).when(mApnContext).getApnSetting(); 425 mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp); 426 waitForMs(200); 427 428 assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities() 429 .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)); 430 assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities() 431 .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 432 assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities() 433 .hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)); 434 } 435 436 @Test 437 @SmallTest 438 public void testMeteredCapability() throws Exception { 439 440 mContextFixture.getCarrierConfigBundle(). 441 putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, 442 new String[] {"default"}); 443 444 testConnectEvent(); 445 446 assertFalse(getNetworkCapabilities() 447 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 448 } 449 450 @Test 451 @SmallTest 452 public void testNonMeteredCapability() throws Exception { 453 454 doReturn(2819).when(mPhone).getSubId(); 455 mContextFixture.getCarrierConfigBundle(). 456 putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, 457 new String[] {"mms"}); 458 459 testConnectEvent(); 460 461 assertTrue(getNetworkCapabilities() 462 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 463 } 464 465 @Test 466 public void testOverrideUnmetered() throws Exception { 467 mContextFixture.getCarrierConfigBundle().putStringArray( 468 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, 469 new String[] { "default" }); 470 testConnectEvent(); 471 472 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)); 473 assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 474 475 mDc.onSubscriptionOverride(OVERRIDE_UNMETERED, OVERRIDE_UNMETERED); 476 477 assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)); 478 assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 479 480 mDc.onSubscriptionOverride(OVERRIDE_UNMETERED, 0); 481 482 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)); 483 assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 484 } 485 486 @Test 487 public void testOverrideCongested() throws Exception { 488 mContextFixture.getCarrierConfigBundle().putStringArray( 489 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, 490 new String[] { "default" }); 491 testConnectEvent(); 492 493 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)); 494 assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 495 496 mDc.onSubscriptionOverride(OVERRIDE_CONGESTED, OVERRIDE_CONGESTED); 497 498 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)); 499 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 500 501 mDc.onSubscriptionOverride(OVERRIDE_CONGESTED, 0); 502 503 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)); 504 assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 505 } 506 507 @SmallTest 508 public void testIsIpAddress() throws Exception { 509 // IPv4 510 assertTrue(DataConnection.isIpAddress("1.2.3.4")); 511 assertTrue(DataConnection.isIpAddress("127.0.0.1")); 512 513 // IPv6 514 assertTrue(DataConnection.isIpAddress("::1")); 515 assertTrue(DataConnection.isIpAddress("2001:4860:800d::68")); 516 } 517 518 @Test 519 @SmallTest 520 public void testSetLinkProperties() throws Exception { 521 522 DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME, 523 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 524 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 525 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 526 Arrays.asList(FAKE_PCSCF_ADDRESS), 527 1440); 528 529 LinkProperties linkProperties = new LinkProperties(); 530 assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties)); 531 logd(linkProperties.toString()); 532 assertEquals(response.getIfname(), linkProperties.getInterfaceName()); 533 assertEquals(response.getAddresses().size(), linkProperties.getAddresses().size()); 534 for (int i = 0; i < response.getAddresses().size(); ++i) { 535 assertEquals(response.getAddresses().get(i).getAddress(), 536 NetworkUtils.numericToInetAddress(linkProperties.getLinkAddresses().get(i) 537 .getAddress().getHostAddress())); 538 } 539 540 assertEquals(response.getDnses().size(), linkProperties.getDnsServers().size()); 541 for (int i = 0; i < response.getDnses().size(); ++i) { 542 assertEquals("i = " + i, response.getDnses().get(i), NetworkUtils.numericToInetAddress( 543 linkProperties.getDnsServers().get(i).getHostAddress())); 544 } 545 546 assertEquals(response.getGateways().size(), linkProperties.getRoutes().size()); 547 for (int i = 0; i < response.getGateways().size(); ++i) { 548 assertEquals("i = " + i, response.getGateways().get(i), 549 NetworkUtils.numericToInetAddress(linkProperties.getRoutes().get(i) 550 .getGateway().getHostAddress())); 551 } 552 553 assertEquals(response.getMtu(), linkProperties.getMtu()); 554 } 555 556 @Test 557 @SmallTest 558 public void testSetLinkPropertiesEmptyAddress() throws Exception { 559 560 // 224.224.224.224 is an invalid address. 561 DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME, 562 null, 563 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)), 564 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 565 Arrays.asList(FAKE_PCSCF_ADDRESS), 566 1440); 567 568 LinkProperties linkProperties = new LinkProperties(); 569 assertEquals(SetupResult.ERROR_INVALID_ARG, 570 setLinkProperties(response, linkProperties)); 571 } 572 573 @Test 574 @SmallTest 575 public void testSetLinkPropertiesEmptyDns() throws Exception { 576 577 // Empty dns entry. 578 DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME, 579 Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)), 580 null, 581 Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)), 582 Arrays.asList(FAKE_PCSCF_ADDRESS), 583 1440); 584 585 // Make sure no exception was thrown 586 LinkProperties linkProperties = new LinkProperties(); 587 assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties)); 588 } 589 590 @Test 591 @SmallTest 592 public void testStartKeepaliveWLAN() throws Exception { 593 testConnectEvent(); 594 waitForMs(200); 595 596 DataServiceManager mockDsm = mock(DataServiceManager.class); 597 doReturn(TransportType.WLAN).when(mockDsm).getTransportType(); 598 replaceInstance(DataConnection.class, "mDataServiceManager", mDc, mockDsm); 599 600 final int sessionHandle = 0xF00; 601 final int slotId = 3; 602 final int interval = 10; // seconds 603 // Construct a new KeepalivePacketData request as we would receive from a Network Agent, 604 // and check that the packet is sent to the RIL. 605 KeepalivePacketData kd = KeepalivePacketData.nattKeepalivePacket( 606 NetworkUtils.numericToInetAddress("1.2.3.4"), 607 1234, 608 NetworkUtils.numericToInetAddress("8.8.8.8"), 609 4500); 610 mDc.obtainMessage( 611 DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget(); 612 waitForMs(100); 613 // testStartStopNattKeepalive() verifies that this request is passed with WWAN. 614 // Thus, even though we can't see the response in NetworkAgent, we can verify that the 615 // CommandsInterface never receives a request and infer that it was dropped due to WLAN. 616 verify(mSimulatedCommandsVerifier, times(0)) 617 .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class)); 618 } 619 620 public void checkStartStopNattKeepalive(boolean useCondensedFlow) throws Exception { 621 testConnectEvent(); 622 waitForMs(200); 623 624 final int sessionHandle = 0xF00; 625 final int slotId = 3; 626 final int interval = 10; // seconds 627 // Construct a new KeepalivePacketData request as we would receive from a Network Agent, 628 // and check that the packet is sent to the RIL. 629 KeepalivePacketData kd = KeepalivePacketData.nattKeepalivePacket( 630 NetworkUtils.numericToInetAddress("1.2.3.4"), 631 1234, 632 NetworkUtils.numericToInetAddress("8.8.8.8"), 633 4500); 634 mDc.obtainMessage( 635 DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget(); 636 waitForMs(100); 637 verify(mSimulatedCommandsVerifier, times(1)) 638 .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class)); 639 640 Message kaStarted = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STARTED, slotId, 0); 641 if (useCondensedFlow) { 642 // Send a singled condensed response that a keepalive have been requested and the 643 // activation is completed. This flow should be used if the keepalive offload request 644 // is handled by a high-priority signalling path. 645 AsyncResult.forMessage( 646 kaStarted, new KeepaliveStatus( 647 sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null); 648 kaStarted.sendToTarget(); 649 } else { 650 // Send the sequential responses indicating first that the request was received and 651 // then that the keepalive is running. This should create an active record of the 652 // keepalive in DataConnection while permitting the status from a low priority or other 653 // high-latency handler to activate the keepalive without blocking a request. 654 AsyncResult.forMessage( 655 kaStarted, new KeepaliveStatus( 656 sessionHandle, KeepaliveStatus.STATUS_PENDING), null); 657 kaStarted.sendToTarget(); 658 Message kaRunning = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STATUS); 659 AsyncResult.forMessage( 660 kaRunning, new KeepaliveStatus( 661 sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null); 662 kaRunning.sendToTarget(); 663 } 664 waitForMs(100); 665 666 // Verify that we can stop the connection, which checks that the record in DataConnection 667 // has a valid mapping between slotId (from network agent) to sessionHandle (from Radio). 668 mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget(); 669 waitForMs(100); 670 verify(mSimulatedCommandsVerifier, times(1)) 671 .stopNattKeepalive(eq(sessionHandle), any(Message.class)); 672 673 Message kaStopped = mDc.obtainMessage( 674 DataConnection.EVENT_KEEPALIVE_STOPPED, sessionHandle, slotId); 675 AsyncResult.forMessage(kaStopped); 676 kaStopped.sendToTarget(); 677 // Verify that after the connection is stopped, the mapping for a Keepalive Session is 678 // removed. Thus, subsequent calls to stop the same keepalive are ignored. 679 mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget(); 680 waitForMs(100); 681 // Check that the mock has not been called subsequent to the previous invocation 682 // while avoiding the use of reset() 683 verify(mSimulatedCommandsVerifier, times(1)) 684 .stopNattKeepalive(anyInt(), any(Message.class)); 685 } 686 687 @Test 688 @MediumTest 689 public void testStartStopNattKeepalive() throws Exception { 690 checkStartStopNattKeepalive(false); 691 } 692 693 @Test 694 @MediumTest 695 public void testStartStopNattKeepaliveCondensed() throws Exception { 696 checkStartStopNattKeepalive(true); 697 } 698 699 public void checkStartNattKeepaliveFail(boolean useCondensedFlow) throws Exception { 700 testConnectEvent(); 701 waitForMs(200); 702 703 final int sessionHandle = 0xF00; 704 final int slotId = 3; 705 final int interval = 10; // seconds 706 // Construct a new KeepalivePacketData request as we would receive from a Network Agent, 707 // and check that the packet is sent to the RIL. 708 KeepalivePacketData kd = KeepalivePacketData.nattKeepalivePacket( 709 NetworkUtils.numericToInetAddress("1.2.3.4"), 710 1234, 711 NetworkUtils.numericToInetAddress("8.8.8.8"), 712 4500); 713 mDc.obtainMessage( 714 DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget(); 715 waitForMs(100); 716 verify(mSimulatedCommandsVerifier, times(1)) 717 .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class)); 718 719 Message kaStarted = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STARTED, slotId, 0); 720 if (useCondensedFlow) { 721 // Indicate in the response that the keepalive has failed. 722 AsyncResult.forMessage( 723 kaStarted, new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED), null); 724 kaStarted.sendToTarget(); 725 } else { 726 // Indicate that the keepalive is queued, and then signal a failure from the modem 727 // such that a pending keepalive fails to activate. 728 AsyncResult.forMessage( 729 kaStarted, new KeepaliveStatus( 730 sessionHandle, KeepaliveStatus.STATUS_PENDING), null); 731 kaStarted.sendToTarget(); 732 Message kaRunning = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STATUS); 733 AsyncResult.forMessage( 734 kaRunning, new KeepaliveStatus( 735 sessionHandle, KeepaliveStatus.STATUS_INACTIVE), null); 736 kaRunning.sendToTarget(); 737 } 738 waitForMs(100); 739 // Verify that a failed connection request cannot be stopped due to no record in 740 // the DataConnection. 741 mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget(); 742 waitForMs(100); 743 verify(mSimulatedCommandsVerifier, times(0)) 744 .stopNattKeepalive(anyInt(), any(Message.class)); 745 } 746 747 @Test 748 @SmallTest 749 public void testStartNattKeepaliveFail() throws Exception { 750 checkStartNattKeepaliveFail(false); 751 } 752 753 @Test 754 @SmallTest 755 public void testStartNattKeepaliveFailCondensed() throws Exception { 756 checkStartNattKeepaliveFail(true); 757 } 758 } 759