2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.server;
19 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
20 import static android.net.ConnectivityManager.TYPE_MOBILE;
21 import static android.net.ConnectivityManager.TYPE_WIFI;
22 import static android.net.ConnectivityManager.getNetworkTypeName;
23 import static android.net.NetworkCapabilities.*;
25 import static org.mockito.Mockito.mock;
27 import android.app.PendingIntent;
28 import android.content.BroadcastReceiver;
29 import android.content.Context;
30 import android.content.ContextWrapper;
31 import android.content.Intent;
32 import android.content.IntentFilter;
33 import android.net.ConnectivityManager;
34 import android.net.ConnectivityManager.NetworkCallback;
35 import android.net.ConnectivityManager.PacketKeepalive;
36 import android.net.ConnectivityManager.PacketKeepaliveCallback;
37 import android.net.INetworkPolicyManager;
38 import android.net.INetworkStatsService;
39 import android.net.IpPrefix;
40 import android.net.LinkAddress;
41 import android.net.LinkProperties;
42 import android.net.Network;
43 import android.net.NetworkAgent;
44 import android.net.NetworkCapabilities;
45 import android.net.NetworkConfig;
46 import android.net.NetworkFactory;
47 import android.net.NetworkInfo;
48 import android.net.NetworkInfo.DetailedState;
49 import android.net.NetworkMisc;
50 import android.net.NetworkRequest;
51 import android.net.RouteInfo;
52 import android.os.ConditionVariable;
53 import android.os.Handler;
54 import android.os.HandlerThread;
55 import android.os.IBinder;
56 import android.os.INetworkManagementService;
57 import android.os.Looper;
58 import android.os.Message;
59 import android.os.MessageQueue;
60 import android.os.Messenger;
61 import android.os.MessageQueue.IdleHandler;
62 import android.os.Process;
63 import android.os.SystemClock;
64 import android.test.AndroidTestCase;
65 import android.test.suitebuilder.annotation.LargeTest;
66 import android.test.suitebuilder.annotation.SmallTest;
67 import android.util.Log;
68 import android.util.LogPrinter;
70 import com.android.internal.util.WakeupMessage;
71 import com.android.server.connectivity.NetworkAgentInfo;
72 import com.android.server.connectivity.NetworkMonitor;
73 import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
74 import com.android.server.net.NetworkPinner;
76 import java.net.InetAddress;
77 import java.util.ArrayList;
78 import java.util.concurrent.CountDownLatch;
79 import java.util.concurrent.LinkedBlockingQueue;
80 import java.util.concurrent.TimeUnit;
81 import java.util.concurrent.atomic.AtomicBoolean;
84 * Tests for {@link ConnectivityService}.
86 * Build, install and run with:
87 * runtest frameworks-services -c com.android.server.ConnectivityServiceTest
89 public class ConnectivityServiceTest extends AndroidTestCase {
90 private static final String TAG = "ConnectivityServiceTest";
92 private static final int TIMEOUT_MS = 500;
94 private BroadcastInterceptingContext mServiceContext;
95 private WrappedConnectivityService mService;
96 private WrappedConnectivityManager mCm;
97 private MockNetworkAgent mWiFiNetworkAgent;
98 private MockNetworkAgent mCellNetworkAgent;
100 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
101 // do not go through ConnectivityService but talk to netd directly, so they don't automatically
102 // reflect the state of our test ConnectivityService.
103 private class WrappedConnectivityManager extends ConnectivityManager {
104 private Network mFakeBoundNetwork;
106 public synchronized boolean bindProcessToNetwork(Network network) {
107 mFakeBoundNetwork = network;
111 public synchronized Network getBoundNetworkForProcess() {
112 return mFakeBoundNetwork;
115 public WrappedConnectivityManager(Context context, ConnectivityService service) {
116 super(context, service);
120 private class MockContext extends BroadcastInterceptingContext {
121 MockContext(Context base) {
126 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
127 // PendingIntents sent by the AlarmManager are not intercepted by
128 // BroadcastInterceptingContext so we must really register the receiver.
129 // This shouldn't effect the real NetworkMonitors as the action contains a random token.
130 if (filter.getAction(0).startsWith("android.net.netmon.lingerExpired")) {
131 return getBaseContext().registerReceiver(receiver, filter);
133 return super.registerReceiver(receiver, filter);
138 public Object getSystemService (String name) {
139 if (name == Context.CONNECTIVITY_SERVICE) return mCm;
140 return super.getSystemService(name);
145 * A subclass of HandlerThread that allows callers to wait for it to become idle. waitForIdle
146 * will return immediately if the handler is already idle.
148 private class IdleableHandlerThread extends HandlerThread {
149 private IdleHandler mIdleHandler;
151 public IdleableHandlerThread(String name) {
155 public void waitForIdle(int timeoutMs) {
156 final ConditionVariable cv = new ConditionVariable();
157 final MessageQueue queue = getLooper().getQueue();
159 synchronized (queue) {
160 if (queue.isIdle()) {
164 assertNull("BUG: only one idle handler allowed", mIdleHandler);
165 mIdleHandler = new IdleHandler() {
166 public boolean queueIdle() {
167 synchronized (queue) {
170 return false; // Remove the handler.
174 queue.addIdleHandler(mIdleHandler);
177 if (!cv.block(timeoutMs)) {
178 fail("HandlerThread " + getName() +
179 " did not become idle after " + timeoutMs + " ms");
180 queue.removeIdleHandler(mIdleHandler);
185 // Tests that IdleableHandlerThread works as expected.
186 public void testIdleableHandlerThread() {
187 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
189 // Tests that waitForIdle returns immediately if the service is already idle.
190 for (int i = 0; i < attempts; i++) {
191 mService.waitForIdle();
194 // Bring up a network that we can use to send messages to ConnectivityService.
195 ConditionVariable cv = waitForConnectivityBroadcasts(1);
196 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
197 mWiFiNetworkAgent.connect(false);
199 Network n = mWiFiNetworkAgent.getNetwork();
202 // Tests that calling waitForIdle waits for messages to be processed.
203 for (int i = 0; i < attempts; i++) {
204 mWiFiNetworkAgent.setSignalStrength(i);
205 mService.waitForIdle();
206 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
209 // Ensure that not calling waitForIdle causes a race condition.
210 for (int i = 0; i < attempts; i++) {
211 mWiFiNetworkAgent.setSignalStrength(i);
212 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
213 // We hit a race condition, as expected. Pass the test.
218 // No race? There is a bug in this test.
219 fail("expected race condition at least once in " + attempts + " attempts");
222 private class MockNetworkAgent {
223 private final WrappedNetworkMonitor mWrappedNetworkMonitor;
224 private final NetworkInfo mNetworkInfo;
225 private final NetworkCapabilities mNetworkCapabilities;
226 private final IdleableHandlerThread mHandlerThread;
227 private final ConditionVariable mDisconnected = new ConditionVariable();
228 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
230 private NetworkAgent mNetworkAgent;
231 private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
232 private int mStopKeepaliveError = PacketKeepalive.NO_KEEPALIVE;
233 private Integer mExpectedKeepaliveSlot = null;
234 // Contains the redirectUrl from networkStatus(). Before reading, wait for
235 // mNetworkStatusReceived.
236 private String mRedirectUrl;
238 MockNetworkAgent(int transport) {
239 final int type = transportToLegacyType(transport);
240 final String typeName = ConnectivityManager.getNetworkTypeName(type);
241 mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
242 mNetworkCapabilities = new NetworkCapabilities();
243 mNetworkCapabilities.addTransportType(transport);
248 case TRANSPORT_CELLULAR:
252 throw new UnsupportedOperationException("unimplemented network type");
254 mHandlerThread = new IdleableHandlerThread("Mock-" + typeName);
255 mHandlerThread.start();
256 mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
257 "Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
258 new LinkProperties(), mScore, new NetworkMisc()) {
260 public void unwanted() { mDisconnected.open(); }
263 public void startPacketKeepalive(Message msg) {
265 if (mExpectedKeepaliveSlot != null) {
266 assertEquals((int) mExpectedKeepaliveSlot, slot);
268 onPacketKeepaliveEvent(slot, mStartKeepaliveError);
272 public void stopPacketKeepalive(Message msg) {
273 onPacketKeepaliveEvent(msg.arg1, mStopKeepaliveError);
277 public void networkStatus(int status, String redirectUrl) {
278 mRedirectUrl = redirectUrl;
279 mNetworkStatusReceived.open();
282 // Waits for the NetworkAgent to be registered, which includes the creation of the
284 mService.waitForIdle();
285 mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor();
288 public void waitForIdle(int timeoutMs) {
289 mHandlerThread.waitForIdle(timeoutMs);
292 public void waitForIdle() {
293 waitForIdle(TIMEOUT_MS);
296 public void adjustScore(int change) {
298 mNetworkAgent.sendNetworkScore(mScore);
301 public void addCapability(int capability) {
302 mNetworkCapabilities.addCapability(capability);
303 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
306 public void setSignalStrength(int signalStrength) {
307 mNetworkCapabilities.setSignalStrength(signalStrength);
308 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
311 public void connectWithoutInternet() {
312 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
313 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
317 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET.
318 * @param validated Indicate if network should pretend to be validated.
320 public void connect(boolean validated) {
321 assertEquals(mNetworkInfo.getDetailedState(), DetailedState.IDLE);
322 assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET));
324 NetworkCallback callback = null;
325 final ConditionVariable validatedCv = new ConditionVariable();
327 mWrappedNetworkMonitor.gen204ProbeResult = 204;
328 NetworkRequest request = new NetworkRequest.Builder()
329 .addTransportType(mNetworkCapabilities.getTransportTypes()[0])
331 callback = new NetworkCallback() {
332 public void onCapabilitiesChanged(Network network,
333 NetworkCapabilities networkCapabilities) {
334 if (network.equals(getNetwork()) &&
335 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
340 mCm.registerNetworkCallback(request, callback);
342 addCapability(NET_CAPABILITY_INTERNET);
344 connectWithoutInternet();
347 // Wait for network to validate.
348 waitFor(validatedCv);
349 mWrappedNetworkMonitor.gen204ProbeResult = 500;
352 if (callback != null) mCm.unregisterNetworkCallback(callback);
355 public void connectWithCaptivePortal(String redirectUrl) {
356 mWrappedNetworkMonitor.gen204ProbeResult = 200;
357 mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl;
359 waitFor(new Criteria() { public boolean get() {
360 NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork());
361 return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} });
362 mWrappedNetworkMonitor.gen204ProbeResult = 500;
363 mWrappedNetworkMonitor.gen204ProbeRedirectUrl = null;
366 public void disconnect() {
367 mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
368 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
371 public Network getNetwork() {
372 return new Network(mNetworkAgent.netId);
375 public ConditionVariable getDisconnectedCV() {
376 return mDisconnected;
379 public WrappedNetworkMonitor getWrappedNetworkMonitor() {
380 return mWrappedNetworkMonitor;
383 public void sendLinkProperties(LinkProperties lp) {
384 mNetworkAgent.sendLinkProperties(lp);
387 public void setStartKeepaliveError(int error) {
388 mStartKeepaliveError = error;
391 public void setStopKeepaliveError(int error) {
392 mStopKeepaliveError = error;
395 public void setExpectedKeepaliveSlot(Integer slot) {
396 mExpectedKeepaliveSlot = slot;
399 public String waitForRedirectUrl() {
400 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
406 * A NetworkFactory that allows tests to wait until any in-flight NetworkRequest add or remove
407 * operations have been processed. Before ConnectivityService can add or remove any requests,
408 * the factory must be told to expect those operations by calling expectAddRequests or
409 * expectRemoveRequests.
411 private static class MockNetworkFactory extends NetworkFactory {
412 private final ConditionVariable mNetworkStartedCV = new ConditionVariable();
413 private final ConditionVariable mNetworkStoppedCV = new ConditionVariable();
414 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
416 // Used to expect that requests be removed or added on a separate thread, without sleeping.
417 // Callers can call either expectAddRequests() or expectRemoveRequests() exactly once, then
418 // cause some other thread to add or remove requests, then call waitForRequests(). We can
419 // either expect requests to be added or removed, but not both, because CountDownLatch can
420 // only count in one direction.
421 private CountDownLatch mExpectations;
423 // Whether we are currently expecting requests to be added or removed. Valid only if
424 // mExpectations is non-null.
425 private boolean mExpectingAdditions;
427 public MockNetworkFactory(Looper looper, Context context, String logTag,
428 NetworkCapabilities filter) {
429 super(looper, context, logTag, filter);
432 public int getMyRequestCount() {
433 return getRequestCount();
436 protected void startNetwork() {
437 mNetworkStarted.set(true);
438 mNetworkStartedCV.open();
441 protected void stopNetwork() {
442 mNetworkStarted.set(false);
443 mNetworkStoppedCV.open();
446 public boolean getMyStartRequested() {
447 return mNetworkStarted.get();
450 public ConditionVariable getNetworkStartedCV() {
451 mNetworkStartedCV.close();
452 return mNetworkStartedCV;
455 public ConditionVariable getNetworkStoppedCV() {
456 mNetworkStoppedCV.close();
457 return mNetworkStoppedCV;
461 protected void handleAddRequest(NetworkRequest request, int score) {
462 // If we're expecting anything, we must be expecting additions.
463 if (mExpectations != null && !mExpectingAdditions) {
464 fail("Can't add requests while expecting requests to be removed");
468 super.handleAddRequest(request, score);
470 // Reduce the number of request additions we're waiting for.
471 if (mExpectingAdditions) {
472 assertTrue("Added more requests than expected", mExpectations.getCount() > 0);
473 mExpectations.countDown();
478 protected void handleRemoveRequest(NetworkRequest request) {
479 // If we're expecting anything, we must be expecting removals.
480 if (mExpectations != null && mExpectingAdditions) {
481 fail("Can't remove requests while expecting requests to be added");
484 // Remove the request.
485 super.handleRemoveRequest(request);
487 // Reduce the number of request removals we're waiting for.
488 if (!mExpectingAdditions) {
489 assertTrue("Removed more requests than expected", mExpectations.getCount() > 0);
490 mExpectations.countDown();
494 private void assertNoExpectations() {
495 if (mExpectations != null) {
496 fail("Can't add expectation, " + mExpectations.getCount() + " already pending");
500 // Expects that count requests will be added.
501 public void expectAddRequests(final int count) {
502 assertNoExpectations();
503 mExpectingAdditions = true;
504 mExpectations = new CountDownLatch(count);
507 // Expects that count requests will be removed.
508 public void expectRemoveRequests(final int count) {
509 assertNoExpectations();
510 mExpectingAdditions = false;
511 mExpectations = new CountDownLatch(count);
514 // Waits for the expected request additions or removals to happen within a timeout.
515 public void waitForRequests() throws InterruptedException {
516 assertNotNull("Nothing to wait for", mExpectations);
517 mExpectations.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
518 final long count = mExpectations.getCount();
519 final String msg = count + " requests still not " +
520 (mExpectingAdditions ? "added" : "removed") +
521 " after " + TIMEOUT_MS + " ms";
522 assertEquals(msg, 0, count);
523 mExpectations = null;
526 public void waitForNetworkRequests(final int count) throws InterruptedException {
528 assertEquals(count, getMyRequestCount());
532 private class FakeWakeupMessage extends WakeupMessage {
533 private static final int UNREASONABLY_LONG_WAIT = 1000;
535 public FakeWakeupMessage(Context context, Handler handler, String cmdName, int cmd) {
536 super(context, handler, cmdName, cmd);
540 public void schedule(long when) {
541 long delayMs = when - SystemClock.elapsedRealtime();
542 if (delayMs < 0) delayMs = 0;
543 if (delayMs > UNREASONABLY_LONG_WAIT) {
544 fail("Attempting to send msg more than " + UNREASONABLY_LONG_WAIT +
545 "ms into the future: " + delayMs);
547 mHandler.sendEmptyMessageDelayed(mCmd, delayMs);
551 public void cancel() {
552 mHandler.removeMessages(mCmd);
556 public void onAlarm() {
557 throw new AssertionError("Should never happen. Update this fake.");
561 // NetworkMonitor implementation allowing overriding of Internet connectivity probe result.
562 private class WrappedNetworkMonitor extends NetworkMonitor {
563 // HTTP response code fed back to NetworkMonitor for Internet connectivity probe.
564 public int gen204ProbeResult = 500;
565 public String gen204ProbeRedirectUrl = null;
567 public WrappedNetworkMonitor(Context context, Handler handler,
568 NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest) {
569 super(context, handler, networkAgentInfo, defaultRequest);
573 protected CaptivePortalProbeResult isCaptivePortal() {
574 return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl);
578 protected WakeupMessage makeWakeupMessage(
579 Context context, Handler handler, String cmdName, int cmd) {
580 return new FakeWakeupMessage(context, handler, cmdName, cmd);
584 private class WrappedConnectivityService extends ConnectivityService {
585 private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
587 public WrappedConnectivityService(Context context, INetworkManagementService netManager,
588 INetworkStatsService statsService, INetworkPolicyManager policyManager) {
589 super(context, netManager, statsService, policyManager);
593 protected HandlerThread createHandlerThread() {
594 return new IdleableHandlerThread("WrappedConnectivityService");
598 protected int getDefaultTcpRwnd() {
599 // Prevent wrapped ConnectivityService from trying to write to SystemProperties.
604 protected int reserveNetId() {
606 final int netId = super.reserveNetId();
608 // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks
609 // can have odd side-effects, like network validations succeeding.
610 final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks();
611 boolean overlaps = false;
612 for (Network network : networks) {
613 if (netId == network.netId) {
618 if (overlaps) continue;
625 public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
626 NetworkAgentInfo nai, NetworkRequest defaultRequest) {
627 final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(context, handler, nai,
629 mLastCreatedNetworkMonitor = monitor;
633 public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
634 return mLastCreatedNetworkMonitor;
637 public void waitForIdle(int timeoutMs) {
638 ((IdleableHandlerThread) mHandlerThread).waitForIdle(timeoutMs);
641 public void waitForIdle() {
642 waitForIdle(TIMEOUT_MS);
647 private interface Criteria {
648 public boolean get();
652 * Wait up to 500ms for {@code criteria.get()} to become true, polling.
653 * Fails if 500ms goes by before {@code criteria.get()} to become true.
655 static private void waitFor(Criteria criteria) {
657 while (!criteria.get()) {
660 } catch (InterruptedException e) {
662 if (++delays == 10) fail();
667 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open.
668 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens.
670 static private void waitFor(ConditionVariable conditionVariable) {
671 assertTrue(conditionVariable.block(TIMEOUT_MS));
675 public void setUp() throws Exception {
678 NetworkMonitor.SetDefaultLingerTime(120);
680 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
681 // http://b/25897652 .
682 if (Looper.myLooper() == null) {
686 mServiceContext = new MockContext(getContext());
687 mService = new WrappedConnectivityService(mServiceContext,
688 mock(INetworkManagementService.class),
689 mock(INetworkStatsService.class),
690 mock(INetworkPolicyManager.class));
692 mService.systemReady();
693 mCm = new WrappedConnectivityManager(getContext(), mService);
694 mCm.bindProcessToNetwork(null);
697 private int transportToLegacyType(int transport) {
701 case TRANSPORT_CELLULAR:
704 throw new IllegalStateException("Unknown transport" + transport);
708 private void verifyActiveNetwork(int transport) {
709 // Test getActiveNetworkInfo()
710 assertNotNull(mCm.getActiveNetworkInfo());
711 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType());
712 // Test getActiveNetwork()
713 assertNotNull(mCm.getActiveNetwork());
714 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid()));
717 assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
719 case TRANSPORT_CELLULAR:
720 assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork());
723 throw new IllegalStateException("Unknown transport" + transport);
725 // Test getNetworkInfo(Network)
726 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork()));
727 assertEquals(transportToLegacyType(transport), mCm.getNetworkInfo(mCm.getActiveNetwork()).getType());
728 // Test getNetworkCapabilities(Network)
729 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork()));
730 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport));
733 private void verifyNoNetwork() {
734 // Test getActiveNetworkInfo()
735 assertNull(mCm.getActiveNetworkInfo());
736 // Test getActiveNetwork()
737 assertNull(mCm.getActiveNetwork());
738 assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
739 // Test getAllNetworks()
740 assertEquals(0, mCm.getAllNetworks().length);
744 * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION
745 * broadcasts are received.
747 private ConditionVariable waitForConnectivityBroadcasts(final int count) {
748 final ConditionVariable cv = new ConditionVariable();
749 mServiceContext.registerReceiver(new BroadcastReceiver() {
750 private int remaining = count;
751 public void onReceive(Context context, Intent intent) {
752 if (--remaining == 0) {
754 mServiceContext.unregisterReceiver(this);
757 }, new IntentFilter(CONNECTIVITY_ACTION));
762 public void testLingering() throws Exception {
764 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
765 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
766 assertNull(mCm.getActiveNetworkInfo());
767 assertNull(mCm.getActiveNetwork());
768 // Test bringing up validated cellular.
769 ConditionVariable cv = waitForConnectivityBroadcasts(1);
770 mCellNetworkAgent.connect(true);
772 verifyActiveNetwork(TRANSPORT_CELLULAR);
773 assertEquals(2, mCm.getAllNetworks().length);
774 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
775 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
776 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) ||
777 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork()));
778 // Test bringing up validated WiFi.
779 cv = waitForConnectivityBroadcasts(2);
780 mWiFiNetworkAgent.connect(true);
782 verifyActiveNetwork(TRANSPORT_WIFI);
783 assertEquals(2, mCm.getAllNetworks().length);
784 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
785 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
786 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) ||
787 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork()));
788 // Test cellular linger timeout.
789 waitFor(new Criteria() {
790 public boolean get() { return mCm.getAllNetworks().length == 1; } });
791 verifyActiveNetwork(TRANSPORT_WIFI);
792 assertEquals(1, mCm.getAllNetworks().length);
793 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork());
794 // Test WiFi disconnect.
795 cv = waitForConnectivityBroadcasts(1);
796 mWiFiNetworkAgent.disconnect();
802 public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
803 // Test bringing up unvalidated WiFi
804 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
805 ConditionVariable cv = waitForConnectivityBroadcasts(1);
806 mWiFiNetworkAgent.connect(false);
808 verifyActiveNetwork(TRANSPORT_WIFI);
809 // Test bringing up unvalidated cellular
810 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
811 mCellNetworkAgent.connect(false);
812 mService.waitForIdle();
813 verifyActiveNetwork(TRANSPORT_WIFI);
814 // Test cellular disconnect.
815 mCellNetworkAgent.disconnect();
816 mService.waitForIdle();
817 verifyActiveNetwork(TRANSPORT_WIFI);
818 // Test bringing up validated cellular
819 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
820 cv = waitForConnectivityBroadcasts(2);
821 mCellNetworkAgent.connect(true);
823 verifyActiveNetwork(TRANSPORT_CELLULAR);
824 // Test cellular disconnect.
825 cv = waitForConnectivityBroadcasts(2);
826 mCellNetworkAgent.disconnect();
828 verifyActiveNetwork(TRANSPORT_WIFI);
829 // Test WiFi disconnect.
830 cv = waitForConnectivityBroadcasts(1);
831 mWiFiNetworkAgent.disconnect();
837 public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
838 // Test bringing up unvalidated cellular.
839 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
840 ConditionVariable cv = waitForConnectivityBroadcasts(1);
841 mCellNetworkAgent.connect(false);
843 verifyActiveNetwork(TRANSPORT_CELLULAR);
844 // Test bringing up unvalidated WiFi.
845 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
846 cv = waitForConnectivityBroadcasts(2);
847 mWiFiNetworkAgent.connect(false);
849 verifyActiveNetwork(TRANSPORT_WIFI);
850 // Test WiFi disconnect.
851 cv = waitForConnectivityBroadcasts(2);
852 mWiFiNetworkAgent.disconnect();
854 verifyActiveNetwork(TRANSPORT_CELLULAR);
855 // Test cellular disconnect.
856 cv = waitForConnectivityBroadcasts(1);
857 mCellNetworkAgent.disconnect();
863 public void testUnlingeringDoesNotValidate() throws Exception {
864 // Test bringing up unvalidated WiFi.
865 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
866 ConditionVariable cv = waitForConnectivityBroadcasts(1);
867 mWiFiNetworkAgent.connect(false);
869 verifyActiveNetwork(TRANSPORT_WIFI);
870 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
871 NET_CAPABILITY_VALIDATED));
872 // Test bringing up validated cellular.
873 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
874 cv = waitForConnectivityBroadcasts(2);
875 mCellNetworkAgent.connect(true);
877 verifyActiveNetwork(TRANSPORT_CELLULAR);
878 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
879 NET_CAPABILITY_VALIDATED));
880 // Test cellular disconnect.
881 cv = waitForConnectivityBroadcasts(2);
882 mCellNetworkAgent.disconnect();
884 verifyActiveNetwork(TRANSPORT_WIFI);
885 // Unlingering a network should not cause it to be marked as validated.
886 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
887 NET_CAPABILITY_VALIDATED));
891 public void testCellularOutscoresWeakWifi() throws Exception {
892 // Test bringing up validated cellular.
893 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
894 ConditionVariable cv = waitForConnectivityBroadcasts(1);
895 mCellNetworkAgent.connect(true);
897 verifyActiveNetwork(TRANSPORT_CELLULAR);
898 // Test bringing up validated WiFi.
899 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
900 cv = waitForConnectivityBroadcasts(2);
901 mWiFiNetworkAgent.connect(true);
903 verifyActiveNetwork(TRANSPORT_WIFI);
904 // Test WiFi getting really weak.
905 cv = waitForConnectivityBroadcasts(2);
906 mWiFiNetworkAgent.adjustScore(-11);
908 verifyActiveNetwork(TRANSPORT_CELLULAR);
909 // Test WiFi restoring signal strength.
910 cv = waitForConnectivityBroadcasts(2);
911 mWiFiNetworkAgent.adjustScore(11);
913 verifyActiveNetwork(TRANSPORT_WIFI);
914 mCellNetworkAgent.disconnect();
915 mWiFiNetworkAgent.disconnect();
919 public void testReapingNetwork() throws Exception {
920 // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
921 // Expect it to be torn down immediately because it satisfies no requests.
922 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
923 ConditionVariable cv = mWiFiNetworkAgent.getDisconnectedCV();
924 mWiFiNetworkAgent.connectWithoutInternet();
926 // Test bringing up cellular without NET_CAPABILITY_INTERNET.
927 // Expect it to be torn down immediately because it satisfies no requests.
928 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
929 cv = mCellNetworkAgent.getDisconnectedCV();
930 mCellNetworkAgent.connectWithoutInternet();
932 // Test bringing up validated WiFi.
933 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
934 cv = waitForConnectivityBroadcasts(1);
935 mWiFiNetworkAgent.connect(true);
937 verifyActiveNetwork(TRANSPORT_WIFI);
938 // Test bringing up unvalidated cellular.
939 // Expect it to be torn down because it could never be the highest scoring network
940 // satisfying the default request even if it validated.
941 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
942 cv = mCellNetworkAgent.getDisconnectedCV();
943 mCellNetworkAgent.connect(false);
945 verifyActiveNetwork(TRANSPORT_WIFI);
946 cv = mWiFiNetworkAgent.getDisconnectedCV();
947 mWiFiNetworkAgent.disconnect();
952 public void testCellularFallback() throws Exception {
953 // Test bringing up validated cellular.
954 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
955 ConditionVariable cv = waitForConnectivityBroadcasts(1);
956 mCellNetworkAgent.connect(true);
958 verifyActiveNetwork(TRANSPORT_CELLULAR);
959 // Test bringing up validated WiFi.
960 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
961 cv = waitForConnectivityBroadcasts(2);
962 mWiFiNetworkAgent.connect(true);
964 verifyActiveNetwork(TRANSPORT_WIFI);
965 // Reevaluate WiFi (it'll instantly fail DNS).
966 cv = waitForConnectivityBroadcasts(2);
967 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
968 NET_CAPABILITY_VALIDATED));
969 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork());
970 // Should quickly fall back to Cellular.
972 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
973 NET_CAPABILITY_VALIDATED));
974 verifyActiveNetwork(TRANSPORT_CELLULAR);
975 // Reevaluate cellular (it'll instantly fail DNS).
976 cv = waitForConnectivityBroadcasts(2);
977 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
978 NET_CAPABILITY_VALIDATED));
979 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
980 // Should quickly fall back to WiFi.
982 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
983 NET_CAPABILITY_VALIDATED));
984 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
985 NET_CAPABILITY_VALIDATED));
986 verifyActiveNetwork(TRANSPORT_WIFI);
987 mCellNetworkAgent.disconnect();
988 mWiFiNetworkAgent.disconnect();
992 public void testWiFiFallback() throws Exception {
993 // Test bringing up unvalidated WiFi.
994 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
995 ConditionVariable cv = waitForConnectivityBroadcasts(1);
996 mWiFiNetworkAgent.connect(false);
998 verifyActiveNetwork(TRANSPORT_WIFI);
999 // Test bringing up validated cellular.
1000 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1001 cv = waitForConnectivityBroadcasts(2);
1002 mCellNetworkAgent.connect(true);
1004 verifyActiveNetwork(TRANSPORT_CELLULAR);
1005 // Reevaluate cellular (it'll instantly fail DNS).
1006 cv = waitForConnectivityBroadcasts(2);
1007 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1008 NET_CAPABILITY_VALIDATED));
1009 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
1010 // Should quickly fall back to WiFi.
1012 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1013 NET_CAPABILITY_VALIDATED));
1014 verifyActiveNetwork(TRANSPORT_WIFI);
1015 mCellNetworkAgent.disconnect();
1016 mWiFiNetworkAgent.disconnect();
1019 enum CallbackState {
1027 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks
1028 * this class receives, by calling expectCallback() exactly once each time a callback is
1029 * received. assertNoCallback may be called at any time.
1031 private class TestNetworkCallback extends NetworkCallback {
1032 private final ConditionVariable mConditionVariable = new ConditionVariable();
1033 private CallbackState mLastCallback = CallbackState.NONE;
1034 private Network mLastNetwork;
1036 public void onAvailable(Network network) {
1037 assertEquals(CallbackState.NONE, mLastCallback);
1038 mLastCallback = CallbackState.AVAILABLE;
1039 mLastNetwork = network;
1040 mConditionVariable.open();
1043 public void onLosing(Network network, int maxMsToLive) {
1044 assertEquals(CallbackState.NONE, mLastCallback);
1045 mLastCallback = CallbackState.LOSING;
1046 mLastNetwork = network;
1047 mConditionVariable.open();
1050 public void onLost(Network network) {
1051 assertEquals(CallbackState.NONE, mLastCallback);
1052 mLastCallback = CallbackState.LOST;
1053 mLastNetwork = network;
1054 mConditionVariable.open();
1057 void expectCallback(CallbackState state) {
1058 expectCallback(state, null);
1061 void expectCallback(CallbackState state, MockNetworkAgent mockAgent) {
1062 waitFor(mConditionVariable);
1063 assertEquals(state, mLastCallback);
1064 if (mockAgent != null) {
1065 assertEquals(mockAgent.getNetwork(), mLastNetwork);
1067 mLastCallback = CallbackState.NONE;
1068 mLastNetwork = null;
1069 mConditionVariable.close();
1072 void assertNoCallback() {
1073 assertEquals(CallbackState.NONE, mLastCallback);
1078 public void testStateChangeNetworkCallbacks() throws Exception {
1079 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
1080 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
1081 final NetworkRequest wifiRequest = new NetworkRequest.Builder()
1082 .addTransportType(TRANSPORT_WIFI).build();
1083 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1084 .addTransportType(TRANSPORT_CELLULAR).build();
1085 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
1086 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
1088 // Test unvalidated networks
1089 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1090 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1091 mCellNetworkAgent.connect(false);
1092 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
1093 wifiNetworkCallback.assertNoCallback();
1094 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1097 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1098 mCellNetworkAgent.adjustScore(-1);
1099 mService.waitForIdle();
1100 wifiNetworkCallback.assertNoCallback();
1101 cellNetworkCallback.assertNoCallback();
1102 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1104 cv = waitForConnectivityBroadcasts(2);
1105 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1106 mWiFiNetworkAgent.connect(false);
1107 wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE);
1108 cellNetworkCallback.assertNoCallback();
1109 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1112 cv = waitForConnectivityBroadcasts(2);
1113 mWiFiNetworkAgent.disconnect();
1114 wifiNetworkCallback.expectCallback(CallbackState.LOST);
1115 cellNetworkCallback.assertNoCallback();
1118 cv = waitForConnectivityBroadcasts(1);
1119 mCellNetworkAgent.disconnect();
1120 cellNetworkCallback.expectCallback(CallbackState.LOST);
1121 wifiNetworkCallback.assertNoCallback();
1124 // Test validated networks
1125 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1126 mCellNetworkAgent.connect(true);
1127 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
1128 wifiNetworkCallback.assertNoCallback();
1129 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1131 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1132 mCellNetworkAgent.adjustScore(-1);
1133 mService.waitForIdle();
1134 wifiNetworkCallback.assertNoCallback();
1135 cellNetworkCallback.assertNoCallback();
1136 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1138 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1139 mWiFiNetworkAgent.connect(true);
1140 wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE);
1141 cellNetworkCallback.expectCallback(CallbackState.LOSING);
1142 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1144 mWiFiNetworkAgent.disconnect();
1145 wifiNetworkCallback.expectCallback(CallbackState.LOST);
1146 cellNetworkCallback.assertNoCallback();
1148 mCellNetworkAgent.disconnect();
1149 cellNetworkCallback.expectCallback(CallbackState.LOST);
1150 wifiNetworkCallback.assertNoCallback();
1153 private void tryNetworkFactoryRequests(int capability) throws Exception {
1154 // Verify NOT_RESTRICTED is set appropriately
1155 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
1156 .build().networkCapabilities;
1157 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
1158 capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
1159 capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
1160 capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
1161 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1163 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1166 NetworkCapabilities filter = new NetworkCapabilities();
1167 filter.addCapability(capability);
1168 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
1169 handlerThread.start();
1170 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
1171 mServiceContext, "testFactory", filter);
1172 testFactory.setScoreFilter(40);
1173 ConditionVariable cv = testFactory.getNetworkStartedCV();
1174 testFactory.expectAddRequests(1);
1175 testFactory.register();
1176 testFactory.waitForNetworkRequests(1);
1177 int expectedRequestCount = 1;
1178 NetworkCallback networkCallback = null;
1179 // For non-INTERNET capabilities we cannot rely on the default request being present, so
1181 if (capability != NET_CAPABILITY_INTERNET) {
1182 assertFalse(testFactory.getMyStartRequested());
1183 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
1184 networkCallback = new NetworkCallback();
1185 testFactory.expectAddRequests(1);
1186 mCm.requestNetwork(request, networkCallback);
1187 expectedRequestCount++;
1188 testFactory.waitForNetworkRequests(expectedRequestCount);
1191 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1192 assertTrue(testFactory.getMyStartRequested());
1194 // Now bring in a higher scored network.
1195 MockNetworkAgent testAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1196 // Rather than create a validated network which complicates things by registering it's
1197 // own NetworkRequest during startup, just bump up the score to cancel out the
1198 // unvalidated penalty.
1199 testAgent.adjustScore(40);
1200 cv = testFactory.getNetworkStoppedCV();
1202 // When testAgent connects, ConnectivityService will re-send us all current requests with
1203 // the new score. There are expectedRequestCount such requests, and we must wait for all of
1205 testFactory.expectAddRequests(expectedRequestCount);
1206 testAgent.connect(false);
1207 testAgent.addCapability(capability);
1209 testFactory.waitForNetworkRequests(expectedRequestCount);
1210 assertFalse(testFactory.getMyStartRequested());
1212 // Bring in a bunch of requests.
1213 testFactory.expectAddRequests(10);
1214 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1215 ConnectivityManager.NetworkCallback[] networkCallbacks =
1216 new ConnectivityManager.NetworkCallback[10];
1217 for (int i = 0; i< networkCallbacks.length; i++) {
1218 networkCallbacks[i] = new ConnectivityManager.NetworkCallback();
1219 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1220 builder.addCapability(capability);
1221 mCm.requestNetwork(builder.build(), networkCallbacks[i]);
1223 testFactory.waitForNetworkRequests(10 + expectedRequestCount);
1224 assertFalse(testFactory.getMyStartRequested());
1226 // Remove the requests.
1227 testFactory.expectRemoveRequests(10);
1228 for (int i = 0; i < networkCallbacks.length; i++) {
1229 mCm.unregisterNetworkCallback(networkCallbacks[i]);
1231 testFactory.waitForNetworkRequests(expectedRequestCount);
1232 assertFalse(testFactory.getMyStartRequested());
1234 // Drop the higher scored network.
1235 cv = testFactory.getNetworkStartedCV();
1236 testAgent.disconnect();
1238 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1239 assertTrue(testFactory.getMyStartRequested());
1241 testFactory.unregister();
1242 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback);
1243 handlerThread.quit();
1247 public void testNetworkFactoryRequests() throws Exception {
1248 tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
1249 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
1250 tryNetworkFactoryRequests(NET_CAPABILITY_DUN);
1251 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA);
1252 tryNetworkFactoryRequests(NET_CAPABILITY_IMS);
1253 tryNetworkFactoryRequests(NET_CAPABILITY_CBS);
1254 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P);
1255 tryNetworkFactoryRequests(NET_CAPABILITY_IA);
1256 tryNetworkFactoryRequests(NET_CAPABILITY_RCS);
1257 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP);
1258 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS);
1259 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED);
1260 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET);
1261 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED);
1262 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN);
1263 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
1267 public void testNoMutableNetworkRequests() throws Exception {
1268 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
1269 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1270 builder.addCapability(NET_CAPABILITY_VALIDATED);
1272 mCm.requestNetwork(builder.build(), new NetworkCallback());
1274 } catch (IllegalArgumentException expected) {}
1276 mCm.requestNetwork(builder.build(), pendingIntent);
1278 } catch (IllegalArgumentException expected) {}
1279 builder = new NetworkRequest.Builder();
1280 builder.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
1282 mCm.requestNetwork(builder.build(), new NetworkCallback());
1284 } catch (IllegalArgumentException expected) {}
1286 mCm.requestNetwork(builder.build(), pendingIntent);
1288 } catch (IllegalArgumentException expected) {}
1292 public void testMMSonWiFi() throws Exception {
1293 // Test bringing up cellular without MMS NetworkRequest gets reaped
1294 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1295 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1296 ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV();
1297 mCellNetworkAgent.connectWithoutInternet();
1299 waitFor(new Criteria() {
1300 public boolean get() { return mCm.getAllNetworks().length == 0; } });
1302 // Test bringing up validated WiFi.
1303 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1304 cv = waitForConnectivityBroadcasts(1);
1305 mWiFiNetworkAgent.connect(true);
1307 verifyActiveNetwork(TRANSPORT_WIFI);
1308 // Register MMS NetworkRequest
1309 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1310 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1311 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1312 mCm.requestNetwork(builder.build(), networkCallback);
1313 // Test bringing up unvalidated cellular with MMS
1314 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1315 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1316 mCellNetworkAgent.connectWithoutInternet();
1317 networkCallback.expectCallback(CallbackState.AVAILABLE);
1318 verifyActiveNetwork(TRANSPORT_WIFI);
1319 // Test releasing NetworkRequest disconnects cellular with MMS
1320 cv = mCellNetworkAgent.getDisconnectedCV();
1321 mCm.unregisterNetworkCallback(networkCallback);
1323 verifyActiveNetwork(TRANSPORT_WIFI);
1327 public void testMMSonCell() throws Exception {
1328 // Test bringing up cellular without MMS
1329 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1330 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1331 mCellNetworkAgent.connect(false);
1333 verifyActiveNetwork(TRANSPORT_CELLULAR);
1334 // Register MMS NetworkRequest
1335 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1336 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1337 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1338 mCm.requestNetwork(builder.build(), networkCallback);
1339 // Test bringing up MMS cellular network
1340 MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1341 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1342 mmsNetworkAgent.connectWithoutInternet();
1343 networkCallback.expectCallback(CallbackState.AVAILABLE);
1344 verifyActiveNetwork(TRANSPORT_CELLULAR);
1345 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
1346 cv = mmsNetworkAgent.getDisconnectedCV();
1347 mCm.unregisterNetworkCallback(networkCallback);
1349 verifyActiveNetwork(TRANSPORT_CELLULAR);
1353 public void testCaptivePortal() {
1354 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1355 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1356 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1357 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1359 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1360 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1361 .addCapability(NET_CAPABILITY_VALIDATED).build();
1362 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
1364 // Bring up a network with a captive portal.
1365 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
1366 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1367 String firstRedirectUrl = "http://example.com/firstPath";
1368 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
1369 captivePortalCallback.expectCallback(CallbackState.AVAILABLE);
1370 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
1372 // Take down network.
1373 // Expect onLost callback.
1374 mWiFiNetworkAgent.disconnect();
1375 captivePortalCallback.expectCallback(CallbackState.LOST);
1377 // Bring up a network with a captive portal.
1378 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
1379 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1380 String secondRedirectUrl = "http://example.com/secondPath";
1381 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
1382 captivePortalCallback.expectCallback(CallbackState.AVAILABLE);
1383 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl);
1385 // Make captive portal disappear then revalidate.
1386 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
1387 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
1388 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
1389 captivePortalCallback.expectCallback(CallbackState.LOST);
1391 // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
1392 validatedCallback.expectCallback(CallbackState.AVAILABLE);
1394 // Break network connectivity.
1395 // Expect NET_CAPABILITY_VALIDATED onLost callback.
1396 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
1397 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
1398 validatedCallback.expectCallback(CallbackState.LOST);
1402 public void testInvalidNetworkSpecifier() {
1403 boolean execptionCalled = true;
1406 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1407 builder.setNetworkSpecifier(MATCH_ALL_REQUESTS_NETWORK_SPECIFIER);
1408 execptionCalled = false;
1409 } catch (IllegalArgumentException e) {
1410 // do nothing - should get here
1413 assertTrue("NetworkReqeuest builder with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
1417 NetworkCapabilities networkCapabilities = new NetworkCapabilities();
1418 networkCapabilities.addTransportType(TRANSPORT_WIFI)
1419 .setNetworkSpecifier(NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER);
1420 mService.requestNetwork(networkCapabilities, null, 0, null,
1421 ConnectivityManager.TYPE_WIFI);
1422 execptionCalled = false;
1423 } catch (IllegalArgumentException e) {
1424 // do nothing - should get here
1427 assertTrue("ConnectivityService requestNetwork with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
1432 public void testRegisterDefaultNetworkCallback() throws Exception {
1433 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
1434 mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
1435 defaultNetworkCallback.assertNoCallback();
1437 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up
1438 // whenever Wi-Fi is up. Without this, the mobile network agent is
1439 // reaped before any other activity can take place.
1440 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
1441 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1442 .addTransportType(TRANSPORT_CELLULAR).build();
1443 mCm.requestNetwork(cellRequest, cellNetworkCallback);
1444 cellNetworkCallback.assertNoCallback();
1446 // Bring up cell and expect CALLBACK_AVAILABLE.
1447 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1448 mCellNetworkAgent.connect(true);
1449 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1450 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1452 // Bring up wifi and expect CALLBACK_AVAILABLE.
1453 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1454 mWiFiNetworkAgent.connect(true);
1455 cellNetworkCallback.assertNoCallback();
1456 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1458 // Bring down cell. Expect no default network callback, since it wasn't the default.
1459 mCellNetworkAgent.disconnect();
1460 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1461 defaultNetworkCallback.assertNoCallback();
1463 // Bring up cell. Expect no default network callback, since it won't be the default.
1464 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1465 mCellNetworkAgent.connect(true);
1466 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1467 defaultNetworkCallback.assertNoCallback();
1469 // Bring down wifi. Expect the default network callback to notified of LOST wifi
1470 // followed by AVAILABLE cell.
1471 mWiFiNetworkAgent.disconnect();
1472 cellNetworkCallback.assertNoCallback();
1473 defaultNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1474 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1475 mCellNetworkAgent.disconnect();
1476 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1477 defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1480 private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
1482 public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
1484 private class CallbackValue {
1485 public CallbackType callbackType;
1488 public CallbackValue(CallbackType type) {
1489 this.callbackType = type;
1490 this.error = PacketKeepalive.SUCCESS;
1491 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR);
1494 public CallbackValue(CallbackType type, int error) {
1495 this.callbackType = type;
1497 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR);
1501 public boolean equals(Object o) {
1502 return o instanceof CallbackValue &&
1503 this.callbackType == ((CallbackValue) o).callbackType &&
1504 this.error == ((CallbackValue) o).error;
1508 public String toString() {
1509 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error);
1513 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>();
1516 public void onStarted() {
1517 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED));
1521 public void onStopped() {
1522 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED));
1526 public void onError(int error) {
1527 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
1530 private void expectCallback(CallbackValue callbackValue) {
1534 mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
1535 } catch (InterruptedException e) {
1536 fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
1540 public void expectStarted() {
1541 expectCallback(new CallbackValue(CallbackType.ON_STARTED));
1544 public void expectStopped() {
1545 expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
1548 public void expectError(int error) {
1549 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
1553 private Network connectKeepaliveNetwork(LinkProperties lp) {
1554 // Ensure the network is disconnected before we do anything.
1555 if (mWiFiNetworkAgent != null) {
1556 assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
1559 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1560 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1561 mWiFiNetworkAgent.connect(true);
1563 verifyActiveNetwork(TRANSPORT_WIFI);
1564 mWiFiNetworkAgent.sendLinkProperties(lp);
1565 mService.waitForIdle();
1566 return mWiFiNetworkAgent.getNetwork();
1569 public void testPacketKeepalives() throws Exception {
1570 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
1571 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
1572 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
1573 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
1574 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888");
1576 LinkProperties lp = new LinkProperties();
1577 lp.setInterfaceName("wlan12");
1578 lp.addLinkAddress(new LinkAddress(myIPv6, 64));
1579 lp.addLinkAddress(new LinkAddress(myIPv4, 25));
1580 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234")));
1581 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
1583 Network notMyNet = new Network(61234);
1584 Network myNet = connectKeepaliveNetwork(lp);
1586 TestKeepaliveCallback callback = new TestKeepaliveCallback();
1589 // Attempt to start keepalives with invalid parameters and check for errors.
1590 ka = mCm.startNattKeepalive(notMyNet, 25, callback, myIPv4, 1234, dstIPv4);
1591 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
1593 ka = mCm.startNattKeepalive(myNet, 19, callback, notMyIPv4, 1234, dstIPv4);
1594 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL);
1596 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 1234, dstIPv6);
1597 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
1599 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv4);
1600 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
1602 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv6);
1603 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); // NAT-T is IPv4-only.
1605 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
1606 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
1608 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
1609 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
1611 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
1612 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
1614 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
1615 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
1617 // Check that a started keepalive can be stopped.
1618 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
1619 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
1620 callback.expectStarted();
1621 mWiFiNetworkAgent.setStopKeepaliveError(PacketKeepalive.SUCCESS);
1623 callback.expectStopped();
1625 // Check that deleting the IP address stops the keepalive.
1626 LinkProperties bogusLp = new LinkProperties(lp);
1627 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
1628 callback.expectStarted();
1629 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25));
1630 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25));
1631 mWiFiNetworkAgent.sendLinkProperties(bogusLp);
1632 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
1633 mWiFiNetworkAgent.sendLinkProperties(lp);
1635 // Check that a started keepalive is stopped correctly when the network disconnects.
1636 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
1637 callback.expectStarted();
1638 mWiFiNetworkAgent.disconnect();
1639 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
1641 // ... and that stopping it after that has no adverse effects.
1642 assertNull(mCm.getNetworkCapabilities(myNet));
1646 myNet = connectKeepaliveNetwork(lp);
1647 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
1649 // Check things work as expected when the keepalive is stopped and the network disconnects.
1650 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
1651 callback.expectStarted();
1653 mWiFiNetworkAgent.disconnect();
1654 mService.waitForIdle();
1655 callback.expectStopped();
1658 myNet = connectKeepaliveNetwork(lp);
1659 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
1661 // Check that keepalive slots start from 1 and increment. The first one gets slot 1.
1662 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
1663 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
1664 callback.expectStarted();
1666 // The second one gets slot 2.
1667 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
1668 TestKeepaliveCallback callback2 = new TestKeepaliveCallback();
1669 PacketKeepalive ka2 = mCm.startNattKeepalive(myNet, 25, callback2, myIPv4, 6789, dstIPv4);
1670 callback2.expectStarted();
1672 // Now stop the first one and create a third. This also gets slot 1.
1674 callback.expectStopped();
1676 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
1677 TestKeepaliveCallback callback3 = new TestKeepaliveCallback();
1678 PacketKeepalive ka3 = mCm.startNattKeepalive(myNet, 25, callback3, myIPv4, 9876, dstIPv4);
1679 callback3.expectStarted();
1682 callback2.expectStopped();
1685 callback3.expectStopped();
1689 public void testGetCaptivePortalServerUrl() throws Exception {
1690 String url = mCm.getCaptivePortalServerUrl();
1691 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url);
1694 private static class TestNetworkPinner extends NetworkPinner {
1695 public static boolean awaitPin(int timeoutMs) {
1696 synchronized(sLock) {
1697 if (sNetwork == null) {
1699 sLock.wait(timeoutMs);
1700 } catch (InterruptedException e) {}
1702 return sNetwork != null;
1706 public static boolean awaitUnpin(int timeoutMs) {
1707 synchronized(sLock) {
1708 if (sNetwork != null) {
1710 sLock.wait(timeoutMs);
1711 } catch (InterruptedException e) {}
1713 return sNetwork == null;
1718 private void assertPinnedToWifiWithCellDefault() {
1719 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
1720 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1723 private void assertPinnedToWifiWithWifiDefault() {
1724 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
1725 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1728 private void assertNotPinnedToWifi() {
1729 assertNull(mCm.getBoundNetworkForProcess());
1730 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1734 public void testNetworkPinner() {
1735 NetworkRequest wifiRequest = new NetworkRequest.Builder()
1736 .addTransportType(TRANSPORT_WIFI)
1738 assertNull(mCm.getBoundNetworkForProcess());
1740 TestNetworkPinner.pin(mServiceContext, wifiRequest);
1741 assertNull(mCm.getBoundNetworkForProcess());
1743 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1744 mCellNetworkAgent.connect(true);
1745 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1746 mWiFiNetworkAgent.connect(false);
1748 // When wi-fi connects, expect to be pinned.
1749 assertTrue(TestNetworkPinner.awaitPin(100));
1750 assertPinnedToWifiWithCellDefault();
1752 // Disconnect and expect the pin to drop.
1753 mWiFiNetworkAgent.disconnect();
1754 assertTrue(TestNetworkPinner.awaitUnpin(100));
1755 assertNotPinnedToWifi();
1757 // Reconnecting does not cause the pin to come back.
1758 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1759 mWiFiNetworkAgent.connect(false);
1760 assertFalse(TestNetworkPinner.awaitPin(100));
1761 assertNotPinnedToWifi();
1763 // Pinning while connected causes the pin to take effect immediately.
1764 TestNetworkPinner.pin(mServiceContext, wifiRequest);
1765 assertTrue(TestNetworkPinner.awaitPin(100));
1766 assertPinnedToWifiWithCellDefault();
1768 // Explicitly unpin and expect to use the default network again.
1769 TestNetworkPinner.unpin();
1770 assertNotPinnedToWifi();
1772 // Disconnect cell and wifi.
1773 ConditionVariable cv = waitForConnectivityBroadcasts(3); // cell down, wifi up, wifi down.
1774 mCellNetworkAgent.disconnect();
1775 mWiFiNetworkAgent.disconnect();
1778 // Pinning takes effect even if the pinned network is the default when the pin is set...
1779 TestNetworkPinner.pin(mServiceContext, wifiRequest);
1780 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1781 mWiFiNetworkAgent.connect(false);
1782 assertTrue(TestNetworkPinner.awaitPin(100));
1783 assertPinnedToWifiWithWifiDefault();
1785 // ... and is maintained even when that network is no longer the default.
1786 cv = waitForConnectivityBroadcasts(1);
1787 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1788 mCellNetworkAgent.connect(true);
1790 assertPinnedToWifiWithCellDefault();
1794 public void testNetworkRequestMaximum() {
1795 final int MAX_REQUESTS = 100;
1796 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
1797 NetworkRequest networkRequest = new NetworkRequest.Builder().build();
1798 ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>();
1800 for (int i = 0; i < MAX_REQUESTS; i++) {
1801 NetworkCallback networkCallback = new NetworkCallback();
1802 mCm.requestNetwork(networkRequest, networkCallback);
1803 networkCallbacks.add(networkCallback);
1805 fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
1806 } catch (IllegalArgumentException expected) {}
1807 for (NetworkCallback networkCallback : networkCallbacks) {
1808 mCm.unregisterNetworkCallback(networkCallback);
1810 networkCallbacks.clear();
1813 for (int i = 0; i < MAX_REQUESTS; i++) {
1814 NetworkCallback networkCallback = new NetworkCallback();
1815 mCm.registerNetworkCallback(networkRequest, networkCallback);
1816 networkCallbacks.add(networkCallback);
1818 fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
1819 } catch (IllegalArgumentException expected) {}
1820 for (NetworkCallback networkCallback : networkCallbacks) {
1821 mCm.unregisterNetworkCallback(networkCallback);
1823 networkCallbacks.clear();
1825 ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
1827 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
1828 PendingIntent pendingIntent =
1829 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
1830 mCm.requestNetwork(networkRequest, pendingIntent);
1831 pendingIntents.add(pendingIntent);
1833 fail("Registering " + MAX_REQUESTS +
1834 " PendingIntent NetworkRequests did not throw exception");
1835 } catch (IllegalArgumentException expected) {}
1836 for (PendingIntent pendingIntent : pendingIntents) {
1837 mCm.unregisterNetworkCallback(pendingIntent);
1839 pendingIntents.clear();
1842 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
1843 PendingIntent pendingIntent =
1844 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
1845 mCm.registerNetworkCallback(networkRequest, pendingIntent);
1846 pendingIntents.add(pendingIntent);
1848 fail("Registering " + MAX_REQUESTS +
1849 " PendingIntent NetworkCallbacks did not throw exception");
1850 } catch (IllegalArgumentException expected) {}
1851 for (PendingIntent pendingIntent : pendingIntents) {
1852 mCm.unregisterNetworkCallback(pendingIntent);
1854 pendingIntents.clear();
1855 mService.waitForIdle(5000);
1857 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed.
1858 for (int i = 0; i < MAX_REQUESTS; i++) {
1859 NetworkCallback networkCallback = new NetworkCallback();
1860 mCm.requestNetwork(networkRequest, networkCallback);
1861 mCm.unregisterNetworkCallback(networkCallback);
1863 mService.waitForIdle();
1864 for (int i = 0; i < MAX_REQUESTS; i++) {
1865 NetworkCallback networkCallback = new NetworkCallback();
1866 mCm.registerNetworkCallback(networkRequest, networkCallback);
1867 mCm.unregisterNetworkCallback(networkCallback);
1869 mService.waitForIdle();
1870 for (int i = 0; i < MAX_REQUESTS; i++) {
1871 PendingIntent pendingIntent =
1872 PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0);
1873 mCm.requestNetwork(networkRequest, pendingIntent);
1874 mCm.unregisterNetworkCallback(pendingIntent);
1876 mService.waitForIdle();
1877 for (int i = 0; i < MAX_REQUESTS; i++) {
1878 PendingIntent pendingIntent =
1879 PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);
1880 mCm.registerNetworkCallback(networkRequest, pendingIntent);
1881 mCm.unregisterNetworkCallback(pendingIntent);