1/* 2 * Copyright (C) 2012 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 17package com.android.server; 18 19import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 20import static android.net.ConnectivityManager.TYPE_MOBILE; 21import static android.net.ConnectivityManager.TYPE_WIFI; 22import static android.net.ConnectivityManager.getNetworkTypeName; 23import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 24import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 25import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 26import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 27import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 28import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 29import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 30import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 31import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 32import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 33import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 34import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 35import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 36import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 37import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; 38import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 39import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 40import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 41import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 42import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 43import static org.mockito.Matchers.anyInt; 44import static org.mockito.Matchers.eq; 45import static org.mockito.Matchers.isA; 46import static org.mockito.Mockito.doNothing; 47import static org.mockito.Mockito.doReturn; 48import static org.mockito.Mockito.doThrow; 49import static org.mockito.Mockito.mock; 50import static org.mockito.Mockito.reset; 51import static org.mockito.Mockito.verify; 52 53import android.app.PendingIntent; 54import android.content.BroadcastReceiver; 55import android.content.Context; 56import android.content.ContextWrapper; 57import android.content.Intent; 58import android.content.IntentFilter; 59import android.net.ConnectivityManager; 60import android.net.ConnectivityManager.NetworkCallback; 61import android.net.INetworkPolicyManager; 62import android.net.INetworkStatsService; 63import android.net.LinkProperties; 64import android.net.Network; 65import android.net.NetworkAgent; 66import android.net.NetworkCapabilities; 67import android.net.NetworkConfig; 68import android.net.NetworkFactory; 69import android.net.NetworkInfo; 70import android.net.NetworkInfo.DetailedState; 71import android.net.NetworkMisc; 72import android.net.NetworkRequest; 73import android.net.RouteInfo; 74import android.os.ConditionVariable; 75import android.os.Handler; 76import android.os.HandlerThread; 77import android.os.Looper; 78import android.os.INetworkManagementService; 79import android.test.AndroidTestCase; 80import android.test.suitebuilder.annotation.LargeTest; 81import android.util.Log; 82import android.util.LogPrinter; 83 84import com.android.server.connectivity.NetworkAgentInfo; 85import com.android.server.connectivity.NetworkMonitor; 86 87import org.mockito.ArgumentCaptor; 88 89import java.net.InetAddress; 90import java.util.concurrent.Future; 91import java.util.concurrent.atomic.AtomicBoolean; 92 93/** 94 * Tests for {@link ConnectivityService}. 95 * 96 * Build, install and run with: 97 * runtest frameworks-services -c com.android.server.ConnectivityServiceTest 98 */ 99public class ConnectivityServiceTest extends AndroidTestCase { 100 private static final String TAG = "ConnectivityServiceTest"; 101 102 private static final String MOBILE_IFACE = "rmnet3"; 103 private static final String WIFI_IFACE = "wlan6"; 104 105 private static final RouteInfo MOBILE_ROUTE_V4 = RouteInfo.makeHostRoute(parse("10.0.0.33"), 106 MOBILE_IFACE); 107 private static final RouteInfo MOBILE_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::33"), 108 MOBILE_IFACE); 109 110 private static final RouteInfo WIFI_ROUTE_V4 = RouteInfo.makeHostRoute(parse("192.168.0.66"), 111 parse("192.168.0.1"), 112 WIFI_IFACE); 113 private static final RouteInfo WIFI_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::66"), 114 parse("fd00::"), 115 WIFI_IFACE); 116 117 private INetworkManagementService mNetManager; 118 private INetworkStatsService mStatsService; 119 private INetworkPolicyManager mPolicyService; 120 121 private BroadcastInterceptingContext mServiceContext; 122 private WrappedConnectivityService mService; 123 private ConnectivityManager mCm; 124 private MockNetworkAgent mWiFiNetworkAgent; 125 private MockNetworkAgent mCellNetworkAgent; 126 127 private class MockContext extends BroadcastInterceptingContext { 128 MockContext(Context base) { 129 super(base); 130 } 131 132 @Override 133 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 134 // PendingIntents sent by the AlarmManager are not intercepted by 135 // BroadcastInterceptingContext so we must really register the receiver. 136 // This shouldn't effect the real NetworkMonitors as the action contains a random token. 137 if (filter.getAction(0).startsWith("android.net.netmon.lingerExpired")) { 138 return getBaseContext().registerReceiver(receiver, filter); 139 } else { 140 return super.registerReceiver(receiver, filter); 141 } 142 } 143 144 @Override 145 public Object getSystemService (String name) { 146 if (name == Context.CONNECTIVITY_SERVICE) return mCm; 147 return super.getSystemService(name); 148 } 149 } 150 151 private class MockNetworkAgent { 152 private final WrappedNetworkMonitor mWrappedNetworkMonitor; 153 private final NetworkInfo mNetworkInfo; 154 private final NetworkCapabilities mNetworkCapabilities; 155 private final Thread mThread; 156 private final ConditionVariable mDisconnected = new ConditionVariable(); 157 private int mScore; 158 private NetworkAgent mNetworkAgent; 159 160 MockNetworkAgent(int transport) { 161 final int type = transportToLegacyType(transport); 162 final String typeName = ConnectivityManager.getNetworkTypeName(type); 163 mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock"); 164 mNetworkCapabilities = new NetworkCapabilities(); 165 mNetworkCapabilities.addTransportType(transport); 166 switch (transport) { 167 case TRANSPORT_WIFI: 168 mScore = 60; 169 break; 170 case TRANSPORT_CELLULAR: 171 mScore = 50; 172 break; 173 default: 174 throw new UnsupportedOperationException("unimplemented network type"); 175 } 176 final ConditionVariable initComplete = new ConditionVariable(); 177 final ConditionVariable networkMonitorAvailable = mService.getNetworkMonitorCreatedCV(); 178 mThread = new Thread() { 179 public void run() { 180 Looper.prepare(); 181 mNetworkAgent = new NetworkAgent(Looper.myLooper(), mServiceContext, 182 "Mock" + typeName, mNetworkInfo, mNetworkCapabilities, 183 new LinkProperties(), mScore, new NetworkMisc()) { 184 public void unwanted() { mDisconnected.open(); } 185 }; 186 initComplete.open(); 187 Looper.loop(); 188 } 189 }; 190 mThread.start(); 191 waitFor(initComplete); 192 waitFor(networkMonitorAvailable); 193 mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor(); 194 } 195 196 public void adjustScore(int change) { 197 mScore += change; 198 mNetworkAgent.sendNetworkScore(mScore); 199 } 200 201 public void addCapability(int capability) { 202 mNetworkCapabilities.addCapability(capability); 203 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); 204 } 205 206 public void connectWithoutInternet() { 207 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null); 208 mNetworkAgent.sendNetworkInfo(mNetworkInfo); 209 } 210 211 /** 212 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. 213 * @param validated Indicate if network should pretend to be validated. 214 */ 215 public void connect(boolean validated) { 216 assertEquals(mNetworkInfo.getDetailedState(), DetailedState.IDLE); 217 assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)); 218 219 NetworkCallback callback = null; 220 final ConditionVariable validatedCv = new ConditionVariable(); 221 if (validated) { 222 mWrappedNetworkMonitor.gen204ProbeResult = 204; 223 NetworkRequest request = new NetworkRequest.Builder() 224 .addTransportType(mNetworkCapabilities.getTransportTypes()[0]) 225 .build(); 226 callback = new NetworkCallback() { 227 public void onCapabilitiesChanged(Network network, 228 NetworkCapabilities networkCapabilities) { 229 if (network.equals(getNetwork()) && 230 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 231 validatedCv.open(); 232 } 233 } 234 }; 235 mCm.registerNetworkCallback(request, callback); 236 } 237 addCapability(NET_CAPABILITY_INTERNET); 238 239 connectWithoutInternet(); 240 241 if (validated) { 242 // Wait for network to validate. 243 waitFor(validatedCv); 244 mWrappedNetworkMonitor.gen204ProbeResult = 500; 245 } 246 247 if (callback != null) mCm.unregisterNetworkCallback(callback); 248 } 249 250 public void connectWithCaptivePortal() { 251 mWrappedNetworkMonitor.gen204ProbeResult = 200; 252 connect(false); 253 waitFor(new Criteria() { public boolean get() { 254 NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork()); 255 return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} }); 256 mWrappedNetworkMonitor.gen204ProbeResult = 500; 257 } 258 259 public void disconnect() { 260 mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null); 261 mNetworkAgent.sendNetworkInfo(mNetworkInfo); 262 } 263 264 public Network getNetwork() { 265 return new Network(mNetworkAgent.netId); 266 } 267 268 public ConditionVariable getDisconnectedCV() { 269 return mDisconnected; 270 } 271 272 public WrappedNetworkMonitor getWrappedNetworkMonitor() { 273 return mWrappedNetworkMonitor; 274 } 275 } 276 277 private static class MockNetworkFactory extends NetworkFactory { 278 private final ConditionVariable mNetworkStartedCV = new ConditionVariable(); 279 private final ConditionVariable mNetworkStoppedCV = new ConditionVariable(); 280 private final ConditionVariable mNetworkRequestedCV = new ConditionVariable(); 281 private final ConditionVariable mNetworkReleasedCV = new ConditionVariable(); 282 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); 283 284 public MockNetworkFactory(Looper looper, Context context, String logTag, 285 NetworkCapabilities filter) { 286 super(looper, context, logTag, filter); 287 } 288 289 public int getMyRequestCount() { 290 return getRequestCount(); 291 } 292 293 protected void startNetwork() { 294 mNetworkStarted.set(true); 295 mNetworkStartedCV.open(); 296 } 297 298 protected void stopNetwork() { 299 mNetworkStarted.set(false); 300 mNetworkStoppedCV.open(); 301 } 302 303 public boolean getMyStartRequested() { 304 return mNetworkStarted.get(); 305 } 306 307 public ConditionVariable getNetworkStartedCV() { 308 mNetworkStartedCV.close(); 309 return mNetworkStartedCV; 310 } 311 312 public ConditionVariable getNetworkStoppedCV() { 313 mNetworkStoppedCV.close(); 314 return mNetworkStoppedCV; 315 } 316 317 protected void needNetworkFor(NetworkRequest networkRequest, int score) { 318 super.needNetworkFor(networkRequest, score); 319 mNetworkRequestedCV.open(); 320 } 321 322 protected void releaseNetworkFor(NetworkRequest networkRequest) { 323 super.releaseNetworkFor(networkRequest); 324 mNetworkReleasedCV.open(); 325 } 326 327 public ConditionVariable getNetworkRequestedCV() { 328 mNetworkRequestedCV.close(); 329 return mNetworkRequestedCV; 330 } 331 332 public ConditionVariable getNetworkReleasedCV() { 333 mNetworkReleasedCV.close(); 334 return mNetworkReleasedCV; 335 } 336 337 public void waitForNetworkRequests(final int count) { 338 waitFor(new Criteria() { public boolean get() { return count == getRequestCount(); } }); 339 } 340 } 341 342 // NetworkMonitor implementation allowing overriding of Internet connectivity probe result. 343 private class WrappedNetworkMonitor extends NetworkMonitor { 344 // HTTP response code fed back to NetworkMonitor for Internet connectivity probe. 345 public int gen204ProbeResult = 500; 346 347 public WrappedNetworkMonitor(Context context, Handler handler, 348 NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest) { 349 super(context, handler, networkAgentInfo, defaultRequest); 350 } 351 352 @Override 353 protected int isCaptivePortal() { 354 return gen204ProbeResult; 355 } 356 } 357 358 private class WrappedConnectivityService extends ConnectivityService { 359 private final ConditionVariable mNetworkMonitorCreated = new ConditionVariable(); 360 private WrappedNetworkMonitor mLastCreatedNetworkMonitor; 361 362 public WrappedConnectivityService(Context context, INetworkManagementService netManager, 363 INetworkStatsService statsService, INetworkPolicyManager policyManager) { 364 super(context, netManager, statsService, policyManager); 365 } 366 367 @Override 368 protected int getDefaultTcpRwnd() { 369 // Prevent wrapped ConnectivityService from trying to write to SystemProperties. 370 return 0; 371 } 372 373 @Override 374 protected int reserveNetId() { 375 while (true) { 376 final int netId = super.reserveNetId(); 377 378 // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks 379 // can have odd side-effects, like network validations succeeding. 380 final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks(); 381 boolean overlaps = false; 382 for (Network network : networks) { 383 if (netId == network.netId) { 384 overlaps = true; 385 break; 386 } 387 } 388 if (overlaps) continue; 389 390 return netId; 391 } 392 } 393 394 @Override 395 public NetworkMonitor createNetworkMonitor(Context context, Handler handler, 396 NetworkAgentInfo nai, NetworkRequest defaultRequest) { 397 final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(context, handler, nai, 398 defaultRequest); 399 mLastCreatedNetworkMonitor = monitor; 400 mNetworkMonitorCreated.open(); 401 return monitor; 402 } 403 404 public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() { 405 return mLastCreatedNetworkMonitor; 406 } 407 408 public ConditionVariable getNetworkMonitorCreatedCV() { 409 mNetworkMonitorCreated.close(); 410 return mNetworkMonitorCreated; 411 } 412 } 413 414 private interface Criteria { 415 public boolean get(); 416 } 417 418 /** 419 * Wait up to 500ms for {@code criteria.get()} to become true, polling. 420 * Fails if 500ms goes by before {@code criteria.get()} to become true. 421 */ 422 static private void waitFor(Criteria criteria) { 423 int delays = 0; 424 while (!criteria.get()) { 425 try { 426 Thread.sleep(100); 427 } catch (InterruptedException e) { 428 } 429 if (++delays == 5) fail(); 430 } 431 } 432 433 /** 434 * Wait up to 500ms for {@code conditonVariable} to open. 435 * Fails if 500ms goes by before {@code conditionVariable} opens. 436 */ 437 static private void waitFor(ConditionVariable conditionVariable) { 438 assertTrue(conditionVariable.block(500)); 439 } 440 441 /** 442 * This should only be used to verify that nothing happens, in other words that no unexpected 443 * changes occur. It should never be used to wait for a specific positive signal to occur. 444 */ 445 private void shortSleep() { 446 // TODO: Instead of sleeping, instead wait for all message loops to idle. 447 try { 448 Thread.sleep(500); 449 } catch (InterruptedException e) { 450 } 451 } 452 453 @Override 454 public void setUp() throws Exception { 455 super.setUp(); 456 457 mServiceContext = new MockContext(getContext()); 458 459 mNetManager = mock(INetworkManagementService.class); 460 mStatsService = mock(INetworkStatsService.class); 461 mPolicyService = mock(INetworkPolicyManager.class); 462 463 mService = new WrappedConnectivityService( 464 mServiceContext, mNetManager, mStatsService, mPolicyService); 465 mService.systemReady(); 466 mCm = new ConnectivityManager(getContext(), mService); 467 } 468 469 private int transportToLegacyType(int transport) { 470 switch (transport) { 471 case TRANSPORT_WIFI: 472 return TYPE_WIFI; 473 case TRANSPORT_CELLULAR: 474 return TYPE_MOBILE; 475 default: 476 throw new IllegalStateException("Unknown transport" + transport); 477 } 478 } 479 480 private void verifyActiveNetwork(int transport) { 481 // Test getActiveNetworkInfo() 482 assertNotNull(mCm.getActiveNetworkInfo()); 483 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); 484 // Test getActiveNetwork() 485 assertNotNull(mCm.getActiveNetwork()); 486 switch (transport) { 487 case TRANSPORT_WIFI: 488 assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork()); 489 break; 490 case TRANSPORT_CELLULAR: 491 assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork()); 492 break; 493 default: 494 throw new IllegalStateException("Unknown transport" + transport); 495 } 496 // Test getNetworkInfo(Network) 497 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); 498 assertEquals(transportToLegacyType(transport), mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); 499 // Test getNetworkCapabilities(Network) 500 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); 501 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); 502 } 503 504 private void verifyNoNetwork() { 505 // Test getActiveNetworkInfo() 506 assertNull(mCm.getActiveNetworkInfo()); 507 // Test getActiveNetwork() 508 assertNull(mCm.getActiveNetwork()); 509 // Test getAllNetworks() 510 assertEquals(0, mCm.getAllNetworks().length); 511 } 512 513 /** 514 * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION 515 * broadcasts are received. 516 */ 517 private ConditionVariable waitForConnectivityBroadcasts(final int count) { 518 final ConditionVariable cv = new ConditionVariable(); 519 mServiceContext.registerReceiver(new BroadcastReceiver() { 520 private int remaining = count; 521 public void onReceive(Context context, Intent intent) { 522 if (--remaining == 0) { 523 cv.open(); 524 mServiceContext.unregisterReceiver(this); 525 } 526 } 527 }, new IntentFilter(CONNECTIVITY_ACTION)); 528 return cv; 529 } 530 531 @LargeTest 532 public void testLingering() throws Exception { 533 // Decrease linger timeout to the minimum allowed by AlarmManagerService. 534 NetworkMonitor.SetDefaultLingerTime(5000); 535 verifyNoNetwork(); 536 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 537 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 538 assertNull(mCm.getActiveNetworkInfo()); 539 assertNull(mCm.getActiveNetwork()); 540 // Test bringing up validated cellular. 541 ConditionVariable cv = waitForConnectivityBroadcasts(1); 542 mCellNetworkAgent.connect(true); 543 waitFor(cv); 544 verifyActiveNetwork(TRANSPORT_CELLULAR); 545 assertEquals(2, mCm.getAllNetworks().length); 546 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 547 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 548 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) || 549 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork())); 550 // Test bringing up validated WiFi. 551 cv = waitForConnectivityBroadcasts(2); 552 mWiFiNetworkAgent.connect(true); 553 waitFor(cv); 554 verifyActiveNetwork(TRANSPORT_WIFI); 555 assertEquals(2, mCm.getAllNetworks().length); 556 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 557 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 558 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) || 559 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork())); 560 // Test cellular linger timeout. 561 try { 562 Thread.sleep(6000); 563 } catch (InterruptedException e) { 564 } 565 verifyActiveNetwork(TRANSPORT_WIFI); 566 assertEquals(1, mCm.getAllNetworks().length); 567 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); 568 // Test WiFi disconnect. 569 cv = waitForConnectivityBroadcasts(1); 570 mWiFiNetworkAgent.disconnect(); 571 waitFor(cv); 572 verifyNoNetwork(); 573 } 574 575 @LargeTest 576 public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { 577 // Test bringing up unvalidated WiFi 578 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 579 ConditionVariable cv = waitForConnectivityBroadcasts(1); 580 mWiFiNetworkAgent.connect(false); 581 waitFor(cv); 582 verifyActiveNetwork(TRANSPORT_WIFI); 583 // Test bringing up unvalidated cellular 584 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 585 mCellNetworkAgent.connect(false); 586 shortSleep(); 587 verifyActiveNetwork(TRANSPORT_WIFI); 588 // Test cellular disconnect. 589 mCellNetworkAgent.disconnect(); 590 shortSleep(); 591 verifyActiveNetwork(TRANSPORT_WIFI); 592 // Test bringing up validated cellular 593 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 594 cv = waitForConnectivityBroadcasts(2); 595 mCellNetworkAgent.connect(true); 596 waitFor(cv); 597 verifyActiveNetwork(TRANSPORT_CELLULAR); 598 // Test cellular disconnect. 599 cv = waitForConnectivityBroadcasts(2); 600 mCellNetworkAgent.disconnect(); 601 waitFor(cv); 602 verifyActiveNetwork(TRANSPORT_WIFI); 603 // Test WiFi disconnect. 604 cv = waitForConnectivityBroadcasts(1); 605 mWiFiNetworkAgent.disconnect(); 606 waitFor(cv); 607 verifyNoNetwork(); 608 } 609 610 @LargeTest 611 public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { 612 // Test bringing up unvalidated cellular. 613 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 614 ConditionVariable cv = waitForConnectivityBroadcasts(1); 615 mCellNetworkAgent.connect(false); 616 waitFor(cv); 617 verifyActiveNetwork(TRANSPORT_CELLULAR); 618 // Test bringing up unvalidated WiFi. 619 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 620 cv = waitForConnectivityBroadcasts(2); 621 mWiFiNetworkAgent.connect(false); 622 waitFor(cv); 623 verifyActiveNetwork(TRANSPORT_WIFI); 624 // Test WiFi disconnect. 625 cv = waitForConnectivityBroadcasts(2); 626 mWiFiNetworkAgent.disconnect(); 627 waitFor(cv); 628 verifyActiveNetwork(TRANSPORT_CELLULAR); 629 // Test cellular disconnect. 630 cv = waitForConnectivityBroadcasts(1); 631 mCellNetworkAgent.disconnect(); 632 waitFor(cv); 633 verifyNoNetwork(); 634 } 635 636 @LargeTest 637 public void testUnlingeringDoesNotValidate() throws Exception { 638 // Test bringing up unvalidated WiFi. 639 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 640 ConditionVariable cv = waitForConnectivityBroadcasts(1); 641 mWiFiNetworkAgent.connect(false); 642 waitFor(cv); 643 verifyActiveNetwork(TRANSPORT_WIFI); 644 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 645 NET_CAPABILITY_VALIDATED)); 646 // Test bringing up validated cellular. 647 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 648 cv = waitForConnectivityBroadcasts(2); 649 mCellNetworkAgent.connect(true); 650 waitFor(cv); 651 verifyActiveNetwork(TRANSPORT_CELLULAR); 652 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 653 NET_CAPABILITY_VALIDATED)); 654 // Test cellular disconnect. 655 cv = waitForConnectivityBroadcasts(2); 656 mCellNetworkAgent.disconnect(); 657 waitFor(cv); 658 verifyActiveNetwork(TRANSPORT_WIFI); 659 // Unlingering a network should not cause it to be marked as validated. 660 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 661 NET_CAPABILITY_VALIDATED)); 662 } 663 664 @LargeTest 665 public void testCellularOutscoresWeakWifi() throws Exception { 666 // Test bringing up validated cellular. 667 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 668 ConditionVariable cv = waitForConnectivityBroadcasts(1); 669 mCellNetworkAgent.connect(true); 670 waitFor(cv); 671 verifyActiveNetwork(TRANSPORT_CELLULAR); 672 // Test bringing up validated WiFi. 673 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 674 cv = waitForConnectivityBroadcasts(2); 675 mWiFiNetworkAgent.connect(true); 676 waitFor(cv); 677 verifyActiveNetwork(TRANSPORT_WIFI); 678 // Test WiFi getting really weak. 679 cv = waitForConnectivityBroadcasts(2); 680 mWiFiNetworkAgent.adjustScore(-11); 681 waitFor(cv); 682 verifyActiveNetwork(TRANSPORT_CELLULAR); 683 // Test WiFi restoring signal strength. 684 cv = waitForConnectivityBroadcasts(2); 685 mWiFiNetworkAgent.adjustScore(11); 686 waitFor(cv); 687 verifyActiveNetwork(TRANSPORT_WIFI); 688 mCellNetworkAgent.disconnect(); 689 mWiFiNetworkAgent.disconnect(); 690 } 691 692 @LargeTest 693 public void testReapingNetwork() throws Exception { 694 // Test bringing up WiFi without NET_CAPABILITY_INTERNET. 695 // Expect it to be torn down immediately because it satisfies no requests. 696 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 697 ConditionVariable cv = mWiFiNetworkAgent.getDisconnectedCV(); 698 mWiFiNetworkAgent.connectWithoutInternet(); 699 waitFor(cv); 700 // Test bringing up cellular without NET_CAPABILITY_INTERNET. 701 // Expect it to be torn down immediately because it satisfies no requests. 702 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 703 cv = mCellNetworkAgent.getDisconnectedCV(); 704 mCellNetworkAgent.connectWithoutInternet(); 705 waitFor(cv); 706 // Test bringing up validated WiFi. 707 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 708 cv = waitForConnectivityBroadcasts(1); 709 mWiFiNetworkAgent.connect(true); 710 waitFor(cv); 711 verifyActiveNetwork(TRANSPORT_WIFI); 712 // Test bringing up unvalidated cellular. 713 // Expect it to be torn down because it could never be the highest scoring network 714 // satisfying the default request even if it validated. 715 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 716 cv = mCellNetworkAgent.getDisconnectedCV(); 717 mCellNetworkAgent.connect(false); 718 waitFor(cv); 719 verifyActiveNetwork(TRANSPORT_WIFI); 720 cv = mWiFiNetworkAgent.getDisconnectedCV(); 721 mWiFiNetworkAgent.disconnect(); 722 waitFor(cv); 723 } 724 725 @LargeTest 726 public void testCellularFallback() throws Exception { 727 // Test bringing up validated cellular. 728 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 729 ConditionVariable cv = waitForConnectivityBroadcasts(1); 730 mCellNetworkAgent.connect(true); 731 waitFor(cv); 732 verifyActiveNetwork(TRANSPORT_CELLULAR); 733 // Test bringing up validated WiFi. 734 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 735 cv = waitForConnectivityBroadcasts(2); 736 mWiFiNetworkAgent.connect(true); 737 waitFor(cv); 738 verifyActiveNetwork(TRANSPORT_WIFI); 739 // Reevaluate WiFi (it'll instantly fail DNS). 740 cv = waitForConnectivityBroadcasts(2); 741 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 742 NET_CAPABILITY_VALIDATED)); 743 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork()); 744 // Should quickly fall back to Cellular. 745 waitFor(cv); 746 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 747 NET_CAPABILITY_VALIDATED)); 748 verifyActiveNetwork(TRANSPORT_CELLULAR); 749 // Reevaluate cellular (it'll instantly fail DNS). 750 cv = waitForConnectivityBroadcasts(2); 751 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 752 NET_CAPABILITY_VALIDATED)); 753 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 754 // Should quickly fall back to WiFi. 755 waitFor(cv); 756 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 757 NET_CAPABILITY_VALIDATED)); 758 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 759 NET_CAPABILITY_VALIDATED)); 760 verifyActiveNetwork(TRANSPORT_WIFI); 761 mCellNetworkAgent.disconnect(); 762 mWiFiNetworkAgent.disconnect(); 763 } 764 765 @LargeTest 766 public void testWiFiFallback() throws Exception { 767 // Test bringing up unvalidated WiFi. 768 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 769 ConditionVariable cv = waitForConnectivityBroadcasts(1); 770 mWiFiNetworkAgent.connect(false); 771 waitFor(cv); 772 verifyActiveNetwork(TRANSPORT_WIFI); 773 // Test bringing up validated cellular. 774 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 775 cv = waitForConnectivityBroadcasts(2); 776 mCellNetworkAgent.connect(true); 777 waitFor(cv); 778 verifyActiveNetwork(TRANSPORT_CELLULAR); 779 // Reevaluate cellular (it'll instantly fail DNS). 780 cv = waitForConnectivityBroadcasts(2); 781 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 782 NET_CAPABILITY_VALIDATED)); 783 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 784 // Should quickly fall back to WiFi. 785 waitFor(cv); 786 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 787 NET_CAPABILITY_VALIDATED)); 788 verifyActiveNetwork(TRANSPORT_WIFI); 789 mCellNetworkAgent.disconnect(); 790 mWiFiNetworkAgent.disconnect(); 791 } 792 793 enum CallbackState { 794 NONE, 795 AVAILABLE, 796 LOSING, 797 LOST 798 } 799 800 private class TestNetworkCallback extends NetworkCallback { 801 private final ConditionVariable mConditionVariable = new ConditionVariable(); 802 private CallbackState mLastCallback = CallbackState.NONE; 803 804 public void onAvailable(Network network) { 805 assertEquals(CallbackState.NONE, mLastCallback); 806 mLastCallback = CallbackState.AVAILABLE; 807 mConditionVariable.open(); 808 } 809 810 public void onLosing(Network network, int maxMsToLive) { 811 assertEquals(CallbackState.NONE, mLastCallback); 812 mLastCallback = CallbackState.LOSING; 813 mConditionVariable.open(); 814 } 815 816 public void onLost(Network network) { 817 assertEquals(CallbackState.NONE, mLastCallback); 818 mLastCallback = CallbackState.LOST; 819 mConditionVariable.open(); 820 } 821 822 ConditionVariable getConditionVariable() { 823 mLastCallback = CallbackState.NONE; 824 mConditionVariable.close(); 825 return mConditionVariable; 826 } 827 828 CallbackState getLastCallback() { 829 return mLastCallback; 830 } 831 } 832 833 @LargeTest 834 public void testStateChangeNetworkCallbacks() throws Exception { 835 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 836 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 837 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 838 .addTransportType(TRANSPORT_WIFI).build(); 839 final NetworkRequest cellRequest = new NetworkRequest.Builder() 840 .addTransportType(TRANSPORT_CELLULAR).build(); 841 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 842 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 843 844 // Test unvalidated networks 845 ConditionVariable cellCv = cellNetworkCallback.getConditionVariable(); 846 ConditionVariable wifiCv = wifiNetworkCallback.getConditionVariable(); 847 ConditionVariable cv = waitForConnectivityBroadcasts(1); 848 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 849 mCellNetworkAgent.connect(false); 850 waitFor(cellCv); 851 assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback()); 852 assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback()); 853 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 854 waitFor(cv); 855 856 cellCv = cellNetworkCallback.getConditionVariable(); 857 wifiCv = wifiNetworkCallback.getConditionVariable(); 858 // This should not trigger spurious onAvailable() callbacks, b/21762680. 859 mCellNetworkAgent.adjustScore(-1); 860 shortSleep(); 861 assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback()); 862 assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback()); 863 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 864 865 cellCv = cellNetworkCallback.getConditionVariable(); 866 wifiCv = wifiNetworkCallback.getConditionVariable(); 867 cv = waitForConnectivityBroadcasts(2); 868 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 869 mWiFiNetworkAgent.connect(false); 870 waitFor(wifiCv); 871 assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback()); 872 assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback()); 873 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 874 waitFor(cv); 875 876 cellCv = cellNetworkCallback.getConditionVariable(); 877 wifiCv = wifiNetworkCallback.getConditionVariable(); 878 cv = waitForConnectivityBroadcasts(2); 879 mWiFiNetworkAgent.disconnect(); 880 waitFor(wifiCv); 881 assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback()); 882 assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback()); 883 waitFor(cv); 884 885 cellCv = cellNetworkCallback.getConditionVariable(); 886 wifiCv = wifiNetworkCallback.getConditionVariable(); 887 cv = waitForConnectivityBroadcasts(1); 888 mCellNetworkAgent.disconnect(); 889 waitFor(cellCv); 890 assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback()); 891 assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback()); 892 waitFor(cv); 893 894 // Test validated networks 895 896 cellCv = cellNetworkCallback.getConditionVariable(); 897 wifiCv = wifiNetworkCallback.getConditionVariable(); 898 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 899 mCellNetworkAgent.connect(true); 900 waitFor(cellCv); 901 assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback()); 902 assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback()); 903 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 904 905 cellCv = cellNetworkCallback.getConditionVariable(); 906 wifiCv = wifiNetworkCallback.getConditionVariable(); 907 // This should not trigger spurious onAvailable() callbacks, b/21762680. 908 mCellNetworkAgent.adjustScore(-1); 909 shortSleep(); 910 assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback()); 911 assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback()); 912 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 913 914 cellCv = cellNetworkCallback.getConditionVariable(); 915 wifiCv = wifiNetworkCallback.getConditionVariable(); 916 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 917 mWiFiNetworkAgent.connect(true); 918 waitFor(wifiCv); 919 assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback()); 920 waitFor(cellCv); 921 assertEquals(CallbackState.LOSING, cellNetworkCallback.getLastCallback()); 922 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 923 924 cellCv = cellNetworkCallback.getConditionVariable(); 925 wifiCv = wifiNetworkCallback.getConditionVariable(); 926 mWiFiNetworkAgent.disconnect(); 927 waitFor(wifiCv); 928 assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback()); 929 assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback()); 930 931 cellCv = cellNetworkCallback.getConditionVariable(); 932 wifiCv = wifiNetworkCallback.getConditionVariable(); 933 mCellNetworkAgent.disconnect(); 934 waitFor(cellCv); 935 assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback()); 936 assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback()); 937 } 938 939 private void tryNetworkFactoryRequests(int capability) throws Exception { 940 // Verify NOT_RESTRICTED is set appropriately 941 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) 942 .build().networkCapabilities; 943 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN || 944 capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA || 945 capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS || 946 capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) { 947 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 948 } else { 949 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 950 } 951 952 NetworkCapabilities filter = new NetworkCapabilities(); 953 filter.addCapability(capability); 954 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 955 handlerThread.start(); 956 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 957 mServiceContext, "testFactory", filter); 958 testFactory.setScoreFilter(40); 959 ConditionVariable cv = testFactory.getNetworkStartedCV(); 960 testFactory.register(); 961 int expectedRequestCount = 1; 962 NetworkCallback networkCallback = null; 963 // For non-INTERNET capabilities we cannot rely on the default request being present, so 964 // add one. 965 if (capability != NET_CAPABILITY_INTERNET) { 966 testFactory.waitForNetworkRequests(1); 967 assertFalse(testFactory.getMyStartRequested()); 968 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); 969 networkCallback = new NetworkCallback(); 970 mCm.requestNetwork(request, networkCallback); 971 expectedRequestCount++; 972 } 973 waitFor(cv); 974 assertEquals(expectedRequestCount, testFactory.getMyRequestCount()); 975 assertTrue(testFactory.getMyStartRequested()); 976 977 // Now bring in a higher scored network. 978 MockNetworkAgent testAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 979 // Rather than create a validated network which complicates things by registering it's 980 // own NetworkRequest during startup, just bump up the score to cancel out the 981 // unvalidated penalty. 982 testAgent.adjustScore(40); 983 cv = testFactory.getNetworkStoppedCV(); 984 testAgent.connect(false); 985 testAgent.addCapability(capability); 986 waitFor(cv); 987 assertEquals(expectedRequestCount, testFactory.getMyRequestCount()); 988 assertFalse(testFactory.getMyStartRequested()); 989 990 // Bring in a bunch of requests. 991 ConnectivityManager.NetworkCallback[] networkCallbacks = 992 new ConnectivityManager.NetworkCallback[10]; 993 for (int i = 0; i< networkCallbacks.length; i++) { 994 networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); 995 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 996 builder.addCapability(capability); 997 mCm.requestNetwork(builder.build(), networkCallbacks[i]); 998 } 999 testFactory.waitForNetworkRequests(10 + expectedRequestCount); 1000 assertFalse(testFactory.getMyStartRequested()); 1001 1002 // Remove the requests. 1003 for (int i = 0; i < networkCallbacks.length; i++) { 1004 mCm.unregisterNetworkCallback(networkCallbacks[i]); 1005 } 1006 testFactory.waitForNetworkRequests(expectedRequestCount); 1007 assertFalse(testFactory.getMyStartRequested()); 1008 1009 // Drop the higher scored network. 1010 cv = testFactory.getNetworkStartedCV(); 1011 testAgent.disconnect(); 1012 waitFor(cv); 1013 assertEquals(expectedRequestCount, testFactory.getMyRequestCount()); 1014 assertTrue(testFactory.getMyStartRequested()); 1015 1016 testFactory.unregister(); 1017 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); 1018 handlerThread.quit(); 1019 } 1020 1021 @LargeTest 1022 public void testNetworkFactoryRequests() throws Exception { 1023 tryNetworkFactoryRequests(NET_CAPABILITY_MMS); 1024 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); 1025 tryNetworkFactoryRequests(NET_CAPABILITY_DUN); 1026 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); 1027 tryNetworkFactoryRequests(NET_CAPABILITY_IMS); 1028 tryNetworkFactoryRequests(NET_CAPABILITY_CBS); 1029 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); 1030 tryNetworkFactoryRequests(NET_CAPABILITY_IA); 1031 tryNetworkFactoryRequests(NET_CAPABILITY_RCS); 1032 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); 1033 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); 1034 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); 1035 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); 1036 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); 1037 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); 1038 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. 1039 } 1040 1041 @LargeTest 1042 public void testNoMutableNetworkRequests() throws Exception { 1043 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0); 1044 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 1045 builder.addCapability(NET_CAPABILITY_VALIDATED); 1046 try { 1047 mCm.requestNetwork(builder.build(), new NetworkCallback()); 1048 fail(); 1049 } catch (IllegalArgumentException expected) {} 1050 try { 1051 mCm.requestNetwork(builder.build(), pendingIntent); 1052 fail(); 1053 } catch (IllegalArgumentException expected) {} 1054 builder = new NetworkRequest.Builder(); 1055 builder.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 1056 try { 1057 mCm.requestNetwork(builder.build(), new NetworkCallback()); 1058 fail(); 1059 } catch (IllegalArgumentException expected) {} 1060 try { 1061 mCm.requestNetwork(builder.build(), pendingIntent); 1062 fail(); 1063 } catch (IllegalArgumentException expected) {} 1064 } 1065 1066 @LargeTest 1067 public void testMMSonWiFi() throws Exception { 1068 // Test bringing up cellular without MMS NetworkRequest gets reaped 1069 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 1070 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 1071 ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV(); 1072 mCellNetworkAgent.connectWithoutInternet(); 1073 waitFor(cv); 1074 waitFor(new Criteria() { 1075 public boolean get() { return mCm.getAllNetworks().length == 0; } }); 1076 verifyNoNetwork(); 1077 // Test bringing up validated WiFi. 1078 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 1079 cv = waitForConnectivityBroadcasts(1); 1080 mWiFiNetworkAgent.connect(true); 1081 waitFor(cv); 1082 verifyActiveNetwork(TRANSPORT_WIFI); 1083 // Register MMS NetworkRequest 1084 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 1085 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1086 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 1087 mCm.requestNetwork(builder.build(), networkCallback); 1088 // Test bringing up unvalidated cellular with MMS 1089 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 1090 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 1091 cv = networkCallback.getConditionVariable(); 1092 mCellNetworkAgent.connectWithoutInternet(); 1093 waitFor(cv); 1094 assertEquals(CallbackState.AVAILABLE, networkCallback.getLastCallback()); 1095 verifyActiveNetwork(TRANSPORT_WIFI); 1096 // Test releasing NetworkRequest disconnects cellular with MMS 1097 cv = mCellNetworkAgent.getDisconnectedCV(); 1098 mCm.unregisterNetworkCallback(networkCallback); 1099 waitFor(cv); 1100 verifyActiveNetwork(TRANSPORT_WIFI); 1101 } 1102 1103 @LargeTest 1104 public void testMMSonCell() throws Exception { 1105 // Test bringing up cellular without MMS 1106 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 1107 ConditionVariable cv = waitForConnectivityBroadcasts(1); 1108 mCellNetworkAgent.connect(false); 1109 waitFor(cv); 1110 verifyActiveNetwork(TRANSPORT_CELLULAR); 1111 // Register MMS NetworkRequest 1112 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 1113 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1114 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 1115 mCm.requestNetwork(builder.build(), networkCallback); 1116 // Test bringing up MMS cellular network 1117 cv = networkCallback.getConditionVariable(); 1118 MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); 1119 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); 1120 mmsNetworkAgent.connectWithoutInternet(); 1121 waitFor(cv); 1122 assertEquals(CallbackState.AVAILABLE, networkCallback.getLastCallback()); 1123 verifyActiveNetwork(TRANSPORT_CELLULAR); 1124 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent 1125 cv = mmsNetworkAgent.getDisconnectedCV(); 1126 mCm.unregisterNetworkCallback(networkCallback); 1127 waitFor(cv); 1128 verifyActiveNetwork(TRANSPORT_CELLULAR); 1129 } 1130 1131 @LargeTest 1132 public void testCaptivePortal() { 1133 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 1134 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 1135 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 1136 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 1137 1138 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 1139 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 1140 .addCapability(NET_CAPABILITY_VALIDATED).build(); 1141 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 1142 ConditionVariable validatedCv = validatedCallback.getConditionVariable(); 1143 1144 // Bring up a network with a captive portal. 1145 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 1146 ConditionVariable cv = captivePortalCallback.getConditionVariable(); 1147 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 1148 mWiFiNetworkAgent.connectWithCaptivePortal(); 1149 waitFor(cv); 1150 assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback()); 1151 1152 // Take down network. 1153 // Expect onLost callback. 1154 cv = captivePortalCallback.getConditionVariable(); 1155 mWiFiNetworkAgent.disconnect(); 1156 waitFor(cv); 1157 assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback()); 1158 1159 // Bring up a network with a captive portal. 1160 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 1161 cv = captivePortalCallback.getConditionVariable(); 1162 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); 1163 mWiFiNetworkAgent.connectWithCaptivePortal(); 1164 waitFor(cv); 1165 assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback()); 1166 1167 // Make captive portal disappear then revalidate. 1168 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. 1169 cv = captivePortalCallback.getConditionVariable(); 1170 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204; 1171 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 1172 waitFor(cv); 1173 assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback()); 1174 1175 // Expect NET_CAPABILITY_VALIDATED onAvailable callback. 1176 waitFor(validatedCv); 1177 assertEquals(CallbackState.AVAILABLE, validatedCallback.getLastCallback()); 1178 1179 // Break network connectivity. 1180 // Expect NET_CAPABILITY_VALIDATED onLost callback. 1181 validatedCv = validatedCallback.getConditionVariable(); 1182 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500; 1183 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 1184 waitFor(validatedCv); 1185 assertEquals(CallbackState.LOST, validatedCallback.getLastCallback()); 1186 } 1187 1188// @Override 1189// public void tearDown() throws Exception { 1190// super.tearDown(); 1191// } 1192// 1193// public void testMobileConnectedAddedRoutes() throws Exception { 1194// Future<?> nextConnBroadcast; 1195// 1196// // bring up mobile network 1197// mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null); 1198// mMobile.link.setInterfaceName(MOBILE_IFACE); 1199// mMobile.link.addRoute(MOBILE_ROUTE_V4); 1200// mMobile.link.addRoute(MOBILE_ROUTE_V6); 1201// mMobile.doReturnDefaults(); 1202// 1203// cv = waitForConnectivityBroadcasts(1); 1204// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); 1205// waitFor(cv); 1206// 1207// // verify that both routes were added 1208// int mobileNetId = mMobile.tracker.getNetwork().netId; 1209// verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4)); 1210// verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6)); 1211// } 1212// 1213// public void testMobileWifiHandoff() throws Exception { 1214// Future<?> nextConnBroadcast; 1215// 1216// // bring up mobile network 1217// mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null); 1218// mMobile.link.setInterfaceName(MOBILE_IFACE); 1219// mMobile.link.addRoute(MOBILE_ROUTE_V4); 1220// mMobile.link.addRoute(MOBILE_ROUTE_V6); 1221// mMobile.doReturnDefaults(); 1222// 1223// cv = waitForConnectivityBroadcasts(1); 1224// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); 1225// waitFor(cv); 1226// 1227// reset(mNetManager); 1228// 1229// // now bring up wifi network 1230// mWifi.info.setDetailedState(DetailedState.CONNECTED, null, null); 1231// mWifi.link.setInterfaceName(WIFI_IFACE); 1232// mWifi.link.addRoute(WIFI_ROUTE_V4); 1233// mWifi.link.addRoute(WIFI_ROUTE_V6); 1234// mWifi.doReturnDefaults(); 1235// 1236// // expect that mobile will be torn down 1237// doReturn(true).when(mMobile.tracker).teardown(); 1238// 1239// cv = waitForConnectivityBroadcasts(1); 1240// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget(); 1241// waitFor(cv); 1242// 1243// // verify that wifi routes added, and teardown requested 1244// int wifiNetId = mWifi.tracker.getNetwork().netId; 1245// verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V4)); 1246// verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V6)); 1247// verify(mMobile.tracker).teardown(); 1248// 1249// int mobileNetId = mMobile.tracker.getNetwork().netId; 1250// 1251// reset(mNetManager, mMobile.tracker); 1252// 1253// // tear down mobile network, as requested 1254// mMobile.info.setDetailedState(DetailedState.DISCONNECTED, null, null); 1255// mMobile.link.clear(); 1256// mMobile.doReturnDefaults(); 1257// 1258// cv = waitForConnectivityBroadcasts(1); 1259// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); 1260// waitFor(cv); 1261// 1262// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4)); 1263// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6)); 1264// 1265// } 1266 1267 private static InetAddress parse(String addr) { 1268 return InetAddress.parseNumericAddress(addr); 1269 } 1270 1271} 1272