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_ETHERNET;
21 import static android.net.ConnectivityManager.TYPE_MOBILE;
22 import static android.net.ConnectivityManager.TYPE_WIFI;
23 import static android.net.ConnectivityManager.getNetworkTypeName;
24 import static android.net.NetworkCapabilities.*;
26 import static org.mockito.Mockito.anyBoolean;
27 import static org.mockito.Mockito.anyInt;
28 import static org.mockito.Mockito.eq;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.when;
33 import android.app.NotificationManager;
34 import android.app.PendingIntent;
35 import android.content.BroadcastReceiver;
36 import android.content.ContentResolver;
37 import android.content.Context;
38 import android.content.ContextWrapper;
39 import android.content.Intent;
40 import android.content.IntentFilter;
41 import android.content.res.Resources;
42 import android.net.CaptivePortal;
43 import android.net.ConnectivityManager;
44 import android.net.ConnectivityManager.NetworkCallback;
45 import android.net.ConnectivityManager.PacketKeepalive;
46 import android.net.ConnectivityManager.PacketKeepaliveCallback;
47 import android.net.ConnectivityManager.TooManyRequestsException;
48 import android.net.INetworkPolicyManager;
49 import android.net.INetworkStatsService;
50 import android.net.IpPrefix;
51 import android.net.LinkAddress;
52 import android.net.LinkProperties;
53 import android.net.MatchAllNetworkSpecifier;
54 import android.net.Network;
55 import android.net.NetworkAgent;
56 import android.net.NetworkCapabilities;
57 import android.net.NetworkConfig;
58 import android.net.NetworkFactory;
59 import android.net.NetworkInfo;
60 import android.net.NetworkInfo.DetailedState;
61 import android.net.NetworkMisc;
62 import android.net.NetworkRequest;
63 import android.net.NetworkSpecifier;
64 import android.net.RouteInfo;
65 import android.net.StringNetworkSpecifier;
66 import android.net.metrics.IpConnectivityLog;
67 import android.net.util.MultinetworkPolicyTracker;
68 import android.os.ConditionVariable;
69 import android.os.Handler;
70 import android.os.HandlerThread;
71 import android.os.IBinder;
72 import android.os.INetworkManagementService;
73 import android.os.Looper;
74 import android.os.Message;
75 import android.os.MessageQueue;
76 import android.os.Messenger;
77 import android.os.MessageQueue.IdleHandler;
78 import android.os.Parcel;
79 import android.os.Parcelable;
80 import android.os.Process;
81 import android.os.SystemClock;
82 import android.os.UserHandle;
83 import android.provider.Settings;
84 import android.test.AndroidTestCase;
85 import android.test.mock.MockContentResolver;
86 import android.test.suitebuilder.annotation.SmallTest;
87 import android.text.TextUtils;
88 import android.util.Log;
89 import android.util.LogPrinter;
91 import com.android.internal.util.WakeupMessage;
92 import com.android.internal.util.test.BroadcastInterceptingContext;
93 import com.android.internal.util.test.FakeSettingsProvider;
94 import com.android.server.connectivity.MockableSystemProperties;
95 import com.android.server.connectivity.NetworkAgentInfo;
96 import com.android.server.connectivity.NetworkMonitor;
97 import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
98 import com.android.server.net.NetworkPinner;
99 import com.android.server.net.NetworkPolicyManagerInternal;
101 import org.junit.Ignore;
102 import org.mockito.Mock;
103 import org.mockito.MockitoAnnotations;
104 import org.mockito.Spy;
106 import java.net.InetAddress;
107 import java.util.ArrayList;
108 import java.util.Arrays;
109 import java.util.Objects;
110 import java.util.concurrent.CountDownLatch;
111 import java.util.concurrent.LinkedBlockingQueue;
112 import java.util.concurrent.TimeUnit;
113 import java.util.concurrent.atomic.AtomicBoolean;
114 import java.util.function.BooleanSupplier;
117 * Tests for {@link ConnectivityService}.
119 * Build, install and run with:
120 * runtest frameworks-net -c com.android.server.ConnectivityServiceTest
122 public class ConnectivityServiceTest extends AndroidTestCase {
123 private static final String TAG = "ConnectivityServiceTest";
125 private static final int TIMEOUT_MS = 500;
126 private static final int TEST_LINGER_DELAY_MS = 120;
128 private MockContext mServiceContext;
129 private WrappedConnectivityService mService;
130 private WrappedConnectivityManager mCm;
131 private MockNetworkAgent mWiFiNetworkAgent;
132 private MockNetworkAgent mCellNetworkAgent;
133 private MockNetworkAgent mEthernetNetworkAgent;
135 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
136 // do not go through ConnectivityService but talk to netd directly, so they don't automatically
137 // reflect the state of our test ConnectivityService.
138 private class WrappedConnectivityManager extends ConnectivityManager {
139 private Network mFakeBoundNetwork;
141 public synchronized boolean bindProcessToNetwork(Network network) {
142 mFakeBoundNetwork = network;
146 public synchronized Network getBoundNetworkForProcess() {
147 return mFakeBoundNetwork;
150 public WrappedConnectivityManager(Context context, ConnectivityService service) {
151 super(context, service);
155 private class MockContext extends BroadcastInterceptingContext {
156 private final MockContentResolver mContentResolver;
158 @Spy private Resources mResources;
159 private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
161 MockContext(Context base) {
164 mResources = spy(base.getResources());
165 when(mResources.getStringArray(com.android.internal.R.array.networkAttributes)).
166 thenReturn(new String[] {
167 "wifi,1,1,1,-1,true",
168 "mobile,0,0,0,-1,true",
169 "mobile_mms,2,0,2,60000,true",
172 mContentResolver = new MockContentResolver();
173 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
177 public void startActivityAsUser(Intent intent, UserHandle handle) {
178 mStartedActivities.offer(intent);
181 public Intent expectStartActivityIntent(int timeoutMs) {
182 Intent intent = null;
184 intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS);
185 } catch (InterruptedException e) {}
186 assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent);
190 public void expectNoStartActivityIntent(int timeoutMs) {
192 assertNull("Received unexpected Intent to start activity",
193 mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS));
194 } catch (InterruptedException e) {}
198 public Object getSystemService(String name) {
199 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
200 if (Context.NOTIFICATION_SERVICE.equals(name)) return mock(NotificationManager.class);
201 return super.getSystemService(name);
205 public ContentResolver getContentResolver() {
206 return mContentResolver;
210 public Resources getResources() {
216 * Block until the given handler becomes idle, or until timeoutMs has passed.
218 private static void waitForIdleHandler(HandlerThread handlerThread, int timeoutMs) {
219 final ConditionVariable cv = new ConditionVariable();
220 final Handler handler = new Handler(handlerThread.getLooper());
221 handler.post(() -> cv.open());
222 if (!cv.block(timeoutMs)) {
223 fail("HandlerThread " + handlerThread.getName() +
224 " did not become idle after " + timeoutMs + " ms");
228 public void waitForIdle(int timeoutMs) {
229 waitForIdleHandler(mService.mHandlerThread, timeoutMs);
230 waitForIdle(mCellNetworkAgent, timeoutMs);
231 waitForIdle(mWiFiNetworkAgent, timeoutMs);
232 waitForIdle(mEthernetNetworkAgent, timeoutMs);
233 waitForIdleHandler(mService.mHandlerThread, timeoutMs);
236 public void waitForIdle(MockNetworkAgent agent, int timeoutMs) {
240 waitForIdleHandler(agent.mHandlerThread, timeoutMs);
243 private void waitForIdle() {
244 waitForIdle(TIMEOUT_MS);
248 public void testWaitForIdle() {
249 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
251 // Tests that waitForIdle returns immediately if the service is already idle.
252 for (int i = 0; i < attempts; i++) {
256 // Bring up a network that we can use to send messages to ConnectivityService.
257 ConditionVariable cv = waitForConnectivityBroadcasts(1);
258 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
259 mWiFiNetworkAgent.connect(false);
261 Network n = mWiFiNetworkAgent.getNetwork();
264 // Tests that calling waitForIdle waits for messages to be processed.
265 for (int i = 0; i < attempts; i++) {
266 mWiFiNetworkAgent.setSignalStrength(i);
268 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
272 // This test has an inherent race condition in it, and cannot be enabled for continuous testing
273 // or presubmit tests. It is kept for manual runs and documentation purposes.
274 public void verifyThatNotWaitingForIdleCausesRaceConditions() {
275 // Bring up a network that we can use to send messages to ConnectivityService.
276 ConditionVariable cv = waitForConnectivityBroadcasts(1);
277 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
278 mWiFiNetworkAgent.connect(false);
280 Network n = mWiFiNetworkAgent.getNetwork();
283 // Ensure that not calling waitForIdle causes a race condition.
284 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
285 for (int i = 0; i < attempts; i++) {
286 mWiFiNetworkAgent.setSignalStrength(i);
287 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
288 // We hit a race condition, as expected. Pass the test.
293 // No race? There is a bug in this test.
294 fail("expected race condition at least once in " + attempts + " attempts");
297 private class MockNetworkAgent {
298 private final WrappedNetworkMonitor mWrappedNetworkMonitor;
299 private final NetworkInfo mNetworkInfo;
300 private final NetworkCapabilities mNetworkCapabilities;
301 private final HandlerThread mHandlerThread;
302 private final ConditionVariable mDisconnected = new ConditionVariable();
303 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
304 private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
306 private NetworkAgent mNetworkAgent;
307 private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
308 private int mStopKeepaliveError = PacketKeepalive.NO_KEEPALIVE;
309 private Integer mExpectedKeepaliveSlot = null;
310 // Contains the redirectUrl from networkStatus(). Before reading, wait for
311 // mNetworkStatusReceived.
312 private String mRedirectUrl;
314 MockNetworkAgent(int transport) {
315 final int type = transportToLegacyType(transport);
316 final String typeName = ConnectivityManager.getNetworkTypeName(type);
317 mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
318 mNetworkCapabilities = new NetworkCapabilities();
319 mNetworkCapabilities.addTransportType(transport);
321 case TRANSPORT_ETHERNET:
327 case TRANSPORT_CELLULAR:
331 throw new UnsupportedOperationException("unimplemented network type");
333 mHandlerThread = new HandlerThread("Mock-" + typeName);
334 mHandlerThread.start();
335 mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
336 "Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
337 new LinkProperties(), mScore, new NetworkMisc()) {
339 public void unwanted() { mDisconnected.open(); }
342 public void startPacketKeepalive(Message msg) {
344 if (mExpectedKeepaliveSlot != null) {
345 assertEquals((int) mExpectedKeepaliveSlot, slot);
347 onPacketKeepaliveEvent(slot, mStartKeepaliveError);
351 public void stopPacketKeepalive(Message msg) {
352 onPacketKeepaliveEvent(msg.arg1, mStopKeepaliveError);
356 public void networkStatus(int status, String redirectUrl) {
357 mRedirectUrl = redirectUrl;
358 mNetworkStatusReceived.open();
362 protected void preventAutomaticReconnect() {
363 mPreventReconnectReceived.open();
366 // Waits for the NetworkAgent to be registered, which includes the creation of the
369 mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor();
372 public void adjustScore(int change) {
374 mNetworkAgent.sendNetworkScore(mScore);
377 public void explicitlySelected(boolean acceptUnvalidated) {
378 mNetworkAgent.explicitlySelected(acceptUnvalidated);
381 public void addCapability(int capability) {
382 mNetworkCapabilities.addCapability(capability);
383 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
386 public void removeCapability(int capability) {
387 mNetworkCapabilities.removeCapability(capability);
388 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
391 public void setSignalStrength(int signalStrength) {
392 mNetworkCapabilities.setSignalStrength(signalStrength);
393 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
396 public void setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
397 mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
398 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
401 public void connectWithoutInternet() {
402 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
403 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
407 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET.
408 * @param validated Indicate if network should pretend to be validated.
410 public void connect(boolean validated) {
411 assertEquals("MockNetworkAgents can only be connected once",
412 mNetworkInfo.getDetailedState(), DetailedState.IDLE);
413 assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET));
415 NetworkCallback callback = null;
416 final ConditionVariable validatedCv = new ConditionVariable();
418 mWrappedNetworkMonitor.gen204ProbeResult = 204;
419 NetworkRequest request = new NetworkRequest.Builder()
420 .addTransportType(mNetworkCapabilities.getTransportTypes()[0])
422 callback = new NetworkCallback() {
423 public void onCapabilitiesChanged(Network network,
424 NetworkCapabilities networkCapabilities) {
425 if (network.equals(getNetwork()) &&
426 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
431 mCm.registerNetworkCallback(request, callback);
433 addCapability(NET_CAPABILITY_INTERNET);
435 connectWithoutInternet();
438 // Wait for network to validate.
439 waitFor(validatedCv);
440 mWrappedNetworkMonitor.gen204ProbeResult = 500;
443 if (callback != null) mCm.unregisterNetworkCallback(callback);
446 public void connectWithCaptivePortal(String redirectUrl) {
447 mWrappedNetworkMonitor.gen204ProbeResult = 200;
448 mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl;
452 public void suspend() {
453 mNetworkInfo.setDetailedState(DetailedState.SUSPENDED, null, null);
454 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
457 public void disconnect() {
458 mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
459 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
462 public Network getNetwork() {
463 return new Network(mNetworkAgent.netId);
466 public ConditionVariable getPreventReconnectReceived() {
467 return mPreventReconnectReceived;
470 public ConditionVariable getDisconnectedCV() {
471 return mDisconnected;
474 public WrappedNetworkMonitor getWrappedNetworkMonitor() {
475 return mWrappedNetworkMonitor;
478 public void sendLinkProperties(LinkProperties lp) {
479 mNetworkAgent.sendLinkProperties(lp);
482 public void setStartKeepaliveError(int error) {
483 mStartKeepaliveError = error;
486 public void setStopKeepaliveError(int error) {
487 mStopKeepaliveError = error;
490 public void setExpectedKeepaliveSlot(Integer slot) {
491 mExpectedKeepaliveSlot = slot;
494 public String waitForRedirectUrl() {
495 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
501 * A NetworkFactory that allows tests to wait until any in-flight NetworkRequest add or remove
502 * operations have been processed. Before ConnectivityService can add or remove any requests,
503 * the factory must be told to expect those operations by calling expectAddRequests or
504 * expectRemoveRequests.
506 private static class MockNetworkFactory extends NetworkFactory {
507 private final ConditionVariable mNetworkStartedCV = new ConditionVariable();
508 private final ConditionVariable mNetworkStoppedCV = new ConditionVariable();
509 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
511 // Used to expect that requests be removed or added on a separate thread, without sleeping.
512 // Callers can call either expectAddRequests() or expectRemoveRequests() exactly once, then
513 // cause some other thread to add or remove requests, then call waitForRequests(). We can
514 // either expect requests to be added or removed, but not both, because CountDownLatch can
515 // only count in one direction.
516 private CountDownLatch mExpectations;
518 // Whether we are currently expecting requests to be added or removed. Valid only if
519 // mExpectations is non-null.
520 private boolean mExpectingAdditions;
522 public MockNetworkFactory(Looper looper, Context context, String logTag,
523 NetworkCapabilities filter) {
524 super(looper, context, logTag, filter);
527 public int getMyRequestCount() {
528 return getRequestCount();
531 protected void startNetwork() {
532 mNetworkStarted.set(true);
533 mNetworkStartedCV.open();
536 protected void stopNetwork() {
537 mNetworkStarted.set(false);
538 mNetworkStoppedCV.open();
541 public boolean getMyStartRequested() {
542 return mNetworkStarted.get();
545 public ConditionVariable getNetworkStartedCV() {
546 mNetworkStartedCV.close();
547 return mNetworkStartedCV;
550 public ConditionVariable getNetworkStoppedCV() {
551 mNetworkStoppedCV.close();
552 return mNetworkStoppedCV;
556 protected void handleAddRequest(NetworkRequest request, int score) {
557 // If we're expecting anything, we must be expecting additions.
558 if (mExpectations != null && !mExpectingAdditions) {
559 fail("Can't add requests while expecting requests to be removed");
563 super.handleAddRequest(request, score);
565 // Reduce the number of request additions we're waiting for.
566 if (mExpectingAdditions) {
567 assertTrue("Added more requests than expected", mExpectations.getCount() > 0);
568 mExpectations.countDown();
573 protected void handleRemoveRequest(NetworkRequest request) {
574 // If we're expecting anything, we must be expecting removals.
575 if (mExpectations != null && mExpectingAdditions) {
576 fail("Can't remove requests while expecting requests to be added");
579 // Remove the request.
580 super.handleRemoveRequest(request);
582 // Reduce the number of request removals we're waiting for.
583 if (!mExpectingAdditions) {
584 assertTrue("Removed more requests than expected", mExpectations.getCount() > 0);
585 mExpectations.countDown();
589 private void assertNoExpectations() {
590 if (mExpectations != null) {
591 fail("Can't add expectation, " + mExpectations.getCount() + " already pending");
595 // Expects that count requests will be added.
596 public void expectAddRequests(final int count) {
597 assertNoExpectations();
598 mExpectingAdditions = true;
599 mExpectations = new CountDownLatch(count);
602 // Expects that count requests will be removed.
603 public void expectRemoveRequests(final int count) {
604 assertNoExpectations();
605 mExpectingAdditions = false;
606 mExpectations = new CountDownLatch(count);
609 // Waits for the expected request additions or removals to happen within a timeout.
610 public void waitForRequests() throws InterruptedException {
611 assertNotNull("Nothing to wait for", mExpectations);
612 mExpectations.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
613 final long count = mExpectations.getCount();
614 final String msg = count + " requests still not " +
615 (mExpectingAdditions ? "added" : "removed") +
616 " after " + TIMEOUT_MS + " ms";
617 assertEquals(msg, 0, count);
618 mExpectations = null;
621 public void waitForNetworkRequests(final int count) throws InterruptedException {
623 assertEquals(count, getMyRequestCount());
627 private class FakeWakeupMessage extends WakeupMessage {
628 private static final int UNREASONABLY_LONG_WAIT = 1000;
630 public FakeWakeupMessage(Context context, Handler handler, String cmdName, int cmd) {
631 super(context, handler, cmdName, cmd);
634 public FakeWakeupMessage(Context context, Handler handler, String cmdName, int cmd,
635 int arg1, int arg2, Object obj) {
636 super(context, handler, cmdName, cmd, arg1, arg2, obj);
640 public void schedule(long when) {
641 long delayMs = when - SystemClock.elapsedRealtime();
642 if (delayMs < 0) delayMs = 0;
643 if (delayMs > UNREASONABLY_LONG_WAIT) {
644 fail("Attempting to send msg more than " + UNREASONABLY_LONG_WAIT +
645 "ms into the future: " + delayMs);
647 Message msg = mHandler.obtainMessage(mCmd, mArg1, mArg2, mObj);
648 mHandler.sendMessageDelayed(msg, delayMs);
652 public void cancel() {
653 mHandler.removeMessages(mCmd, mObj);
657 public void onAlarm() {
658 throw new AssertionError("Should never happen. Update this fake.");
662 // NetworkMonitor implementation allowing overriding of Internet connectivity probe result.
663 private class WrappedNetworkMonitor extends NetworkMonitor {
664 // HTTP response code fed back to NetworkMonitor for Internet connectivity probe.
665 public int gen204ProbeResult = 500;
666 public String gen204ProbeRedirectUrl = null;
668 public WrappedNetworkMonitor(Context context, Handler handler,
669 NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest,
670 IpConnectivityLog log) {
671 super(context, handler, networkAgentInfo, defaultRequest, log);
675 protected CaptivePortalProbeResult isCaptivePortal() {
676 if (!mIsCaptivePortalCheckEnabled) { return new CaptivePortalProbeResult(204); }
677 return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl, null);
681 private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker {
682 public volatile boolean configRestrictsAvoidBadWifi;
683 public volatile int configMeteredMultipathPreference;
685 public WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
690 public boolean configRestrictsAvoidBadWifi() {
691 return configRestrictsAvoidBadWifi;
695 public int configMeteredMultipathPreference() {
696 return configMeteredMultipathPreference;
700 private class WrappedConnectivityService extends ConnectivityService {
701 public WrappedMultinetworkPolicyTracker wrappedMultinetworkPolicyTracker;
702 private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
703 private MockableSystemProperties mSystemProperties;
705 public WrappedConnectivityService(Context context, INetworkManagementService netManager,
706 INetworkStatsService statsService, INetworkPolicyManager policyManager,
707 IpConnectivityLog log) {
708 super(context, netManager, statsService, policyManager, log);
709 mLingerDelayMs = TEST_LINGER_DELAY_MS;
713 protected MockableSystemProperties getSystemProperties() {
714 // Minimal approach to overriding system properties: let most calls fall through to real
715 // device values, and only override ones values that are important to this test.
716 mSystemProperties = spy(new MockableSystemProperties());
717 when(mSystemProperties.getInt("net.tcp.default_init_rwnd", 0)).thenReturn(0);
718 when(mSystemProperties.getBoolean("ro.radio.noril", false)).thenReturn(false);
719 return mSystemProperties;
723 protected int reserveNetId() {
725 final int netId = super.reserveNetId();
727 // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks
728 // can have odd side-effects, like network validations succeeding.
729 final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks();
730 boolean overlaps = false;
731 for (Network network : networks) {
732 if (netId == network.netId) {
737 if (overlaps) continue;
744 public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
745 NetworkAgentInfo nai, NetworkRequest defaultRequest) {
746 final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(
747 context, handler, nai, defaultRequest, mock(IpConnectivityLog.class));
748 mLastCreatedNetworkMonitor = monitor;
753 public MultinetworkPolicyTracker createMultinetworkPolicyTracker(
754 Context c, Handler h, Runnable r) {
755 final WrappedMultinetworkPolicyTracker tracker = new WrappedMultinetworkPolicyTracker(c, h, r);
759 public WrappedMultinetworkPolicyTracker getMultinetworkPolicyTracker() {
760 return (WrappedMultinetworkPolicyTracker) mMultinetworkPolicyTracker;
764 public WakeupMessage makeWakeupMessage(
765 Context context, Handler handler, String cmdName, int cmd, Object obj) {
766 return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj);
769 public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
770 return mLastCreatedNetworkMonitor;
773 public void waitForIdle(int timeoutMs) {
774 waitForIdleHandler(mHandlerThread, timeoutMs);
777 public void waitForIdle() {
778 waitForIdle(TIMEOUT_MS);
783 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open.
784 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens.
786 static private void waitFor(ConditionVariable conditionVariable) {
787 assertTrue(conditionVariable.block(TIMEOUT_MS));
791 public void setUp() throws Exception {
794 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
795 // http://b/25897652 .
796 if (Looper.myLooper() == null) {
800 mServiceContext = new MockContext(getContext());
801 LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
802 LocalServices.addService(
803 NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
804 mService = new WrappedConnectivityService(mServiceContext,
805 mock(INetworkManagementService.class),
806 mock(INetworkStatsService.class),
807 mock(INetworkPolicyManager.class),
808 mock(IpConnectivityLog.class));
810 mService.systemReady();
811 mCm = new WrappedConnectivityManager(getContext(), mService);
812 mCm.bindProcessToNetwork(null);
814 // Ensure that the default setting for Captive Portals is used for most tests
815 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
816 setMobileDataAlwaysOn(false);
819 public void tearDown() throws Exception {
820 setMobileDataAlwaysOn(false);
821 if (mCellNetworkAgent != null) {
822 mCellNetworkAgent.disconnect();
823 mCellNetworkAgent = null;
825 if (mWiFiNetworkAgent != null) {
826 mWiFiNetworkAgent.disconnect();
827 mWiFiNetworkAgent = null;
829 if (mEthernetNetworkAgent != null) {
830 mEthernetNetworkAgent.disconnect();
831 mEthernetNetworkAgent = null;
836 private static int transportToLegacyType(int transport) {
838 case TRANSPORT_ETHERNET:
839 return TYPE_ETHERNET;
842 case TRANSPORT_CELLULAR:
845 throw new IllegalStateException("Unknown transport " + transport);
849 private void verifyActiveNetwork(int transport) {
850 // Test getActiveNetworkInfo()
851 assertNotNull(mCm.getActiveNetworkInfo());
852 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType());
853 // Test getActiveNetwork()
854 assertNotNull(mCm.getActiveNetwork());
855 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid()));
858 assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
860 case TRANSPORT_CELLULAR:
861 assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork());
864 throw new IllegalStateException("Unknown transport" + transport);
866 // Test getNetworkInfo(Network)
867 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork()));
868 assertEquals(transportToLegacyType(transport),
869 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType());
870 // Test getNetworkCapabilities(Network)
871 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork()));
872 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport));
875 private void verifyNoNetwork() {
876 // Test getActiveNetworkInfo()
877 assertNull(mCm.getActiveNetworkInfo());
878 // Test getActiveNetwork()
879 assertNull(mCm.getActiveNetwork());
880 assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
881 // Test getAllNetworks()
882 assertEquals(0, mCm.getAllNetworks().length);
886 * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION
887 * broadcasts are received.
889 private ConditionVariable waitForConnectivityBroadcasts(final int count) {
890 final ConditionVariable cv = new ConditionVariable();
891 mServiceContext.registerReceiver(new BroadcastReceiver() {
892 private int remaining = count;
893 public void onReceive(Context context, Intent intent) {
894 if (--remaining == 0) {
896 mServiceContext.unregisterReceiver(this);
899 }, new IntentFilter(CONNECTIVITY_ACTION));
903 public void testNetworkTypes() {
904 // Ensure that our mocks for the networkAttributes config variable work as expected. If they
905 // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types
906 // will fail. Failing here is much easier to debug.
907 assertTrue(mCm.isNetworkSupported(TYPE_WIFI));
908 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE));
912 public void testLingering() throws Exception {
914 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
915 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
916 assertNull(mCm.getActiveNetworkInfo());
917 assertNull(mCm.getActiveNetwork());
918 // Test bringing up validated cellular.
919 ConditionVariable cv = waitForConnectivityBroadcasts(1);
920 mCellNetworkAgent.connect(true);
922 verifyActiveNetwork(TRANSPORT_CELLULAR);
923 assertEquals(2, mCm.getAllNetworks().length);
924 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
925 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
926 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) ||
927 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork()));
928 // Test bringing up validated WiFi.
929 cv = waitForConnectivityBroadcasts(2);
930 mWiFiNetworkAgent.connect(true);
932 verifyActiveNetwork(TRANSPORT_WIFI);
933 assertEquals(2, mCm.getAllNetworks().length);
934 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
935 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
936 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) ||
937 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork()));
938 // Test cellular linger timeout.
939 waitFor(mCellNetworkAgent.getDisconnectedCV());
941 assertEquals(1, mCm.getAllNetworks().length);
942 verifyActiveNetwork(TRANSPORT_WIFI);
943 assertEquals(1, mCm.getAllNetworks().length);
944 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork());
945 // Test WiFi disconnect.
946 cv = waitForConnectivityBroadcasts(1);
947 mWiFiNetworkAgent.disconnect();
953 public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
954 // Test bringing up unvalidated WiFi
955 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
956 ConditionVariable cv = waitForConnectivityBroadcasts(1);
957 mWiFiNetworkAgent.connect(false);
959 verifyActiveNetwork(TRANSPORT_WIFI);
960 // Test bringing up unvalidated cellular
961 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
962 mCellNetworkAgent.connect(false);
964 verifyActiveNetwork(TRANSPORT_WIFI);
965 // Test cellular disconnect.
966 mCellNetworkAgent.disconnect();
968 verifyActiveNetwork(TRANSPORT_WIFI);
969 // Test bringing up validated cellular
970 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
971 cv = waitForConnectivityBroadcasts(2);
972 mCellNetworkAgent.connect(true);
974 verifyActiveNetwork(TRANSPORT_CELLULAR);
975 // Test cellular disconnect.
976 cv = waitForConnectivityBroadcasts(2);
977 mCellNetworkAgent.disconnect();
979 verifyActiveNetwork(TRANSPORT_WIFI);
980 // Test WiFi disconnect.
981 cv = waitForConnectivityBroadcasts(1);
982 mWiFiNetworkAgent.disconnect();
988 public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
989 // Test bringing up unvalidated cellular.
990 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
991 ConditionVariable cv = waitForConnectivityBroadcasts(1);
992 mCellNetworkAgent.connect(false);
994 verifyActiveNetwork(TRANSPORT_CELLULAR);
995 // Test bringing up unvalidated WiFi.
996 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
997 cv = waitForConnectivityBroadcasts(2);
998 mWiFiNetworkAgent.connect(false);
1000 verifyActiveNetwork(TRANSPORT_WIFI);
1001 // Test WiFi disconnect.
1002 cv = waitForConnectivityBroadcasts(2);
1003 mWiFiNetworkAgent.disconnect();
1005 verifyActiveNetwork(TRANSPORT_CELLULAR);
1006 // Test cellular disconnect.
1007 cv = waitForConnectivityBroadcasts(1);
1008 mCellNetworkAgent.disconnect();
1014 public void testUnlingeringDoesNotValidate() throws Exception {
1015 // Test bringing up unvalidated WiFi.
1016 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1017 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1018 mWiFiNetworkAgent.connect(false);
1020 verifyActiveNetwork(TRANSPORT_WIFI);
1021 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1022 NET_CAPABILITY_VALIDATED));
1023 // Test bringing up validated cellular.
1024 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1025 cv = waitForConnectivityBroadcasts(2);
1026 mCellNetworkAgent.connect(true);
1028 verifyActiveNetwork(TRANSPORT_CELLULAR);
1029 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1030 NET_CAPABILITY_VALIDATED));
1031 // Test cellular disconnect.
1032 cv = waitForConnectivityBroadcasts(2);
1033 mCellNetworkAgent.disconnect();
1035 verifyActiveNetwork(TRANSPORT_WIFI);
1036 // Unlingering a network should not cause it to be marked as validated.
1037 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1038 NET_CAPABILITY_VALIDATED));
1042 public void testCellularOutscoresWeakWifi() throws Exception {
1043 // Test bringing up validated cellular.
1044 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1045 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1046 mCellNetworkAgent.connect(true);
1048 verifyActiveNetwork(TRANSPORT_CELLULAR);
1049 // Test bringing up validated WiFi.
1050 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1051 cv = waitForConnectivityBroadcasts(2);
1052 mWiFiNetworkAgent.connect(true);
1054 verifyActiveNetwork(TRANSPORT_WIFI);
1055 // Test WiFi getting really weak.
1056 cv = waitForConnectivityBroadcasts(2);
1057 mWiFiNetworkAgent.adjustScore(-11);
1059 verifyActiveNetwork(TRANSPORT_CELLULAR);
1060 // Test WiFi restoring signal strength.
1061 cv = waitForConnectivityBroadcasts(2);
1062 mWiFiNetworkAgent.adjustScore(11);
1064 verifyActiveNetwork(TRANSPORT_WIFI);
1068 public void testReapingNetwork() throws Exception {
1069 // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
1070 // Expect it to be torn down immediately because it satisfies no requests.
1071 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1072 ConditionVariable cv = mWiFiNetworkAgent.getDisconnectedCV();
1073 mWiFiNetworkAgent.connectWithoutInternet();
1075 // Test bringing up cellular without NET_CAPABILITY_INTERNET.
1076 // Expect it to be torn down immediately because it satisfies no requests.
1077 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1078 cv = mCellNetworkAgent.getDisconnectedCV();
1079 mCellNetworkAgent.connectWithoutInternet();
1081 // Test bringing up validated WiFi.
1082 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1083 cv = waitForConnectivityBroadcasts(1);
1084 mWiFiNetworkAgent.connect(true);
1086 verifyActiveNetwork(TRANSPORT_WIFI);
1087 // Test bringing up unvalidated cellular.
1088 // Expect it to be torn down because it could never be the highest scoring network
1089 // satisfying the default request even if it validated.
1090 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1091 cv = mCellNetworkAgent.getDisconnectedCV();
1092 mCellNetworkAgent.connect(false);
1094 verifyActiveNetwork(TRANSPORT_WIFI);
1095 cv = mWiFiNetworkAgent.getDisconnectedCV();
1096 mWiFiNetworkAgent.disconnect();
1101 public void testCellularFallback() throws Exception {
1102 // Test bringing up validated cellular.
1103 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1104 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1105 mCellNetworkAgent.connect(true);
1107 verifyActiveNetwork(TRANSPORT_CELLULAR);
1108 // Test bringing up validated WiFi.
1109 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1110 cv = waitForConnectivityBroadcasts(2);
1111 mWiFiNetworkAgent.connect(true);
1113 verifyActiveNetwork(TRANSPORT_WIFI);
1114 // Reevaluate WiFi (it'll instantly fail DNS).
1115 cv = waitForConnectivityBroadcasts(2);
1116 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1117 NET_CAPABILITY_VALIDATED));
1118 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork());
1119 // Should quickly fall back to Cellular.
1121 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1122 NET_CAPABILITY_VALIDATED));
1123 verifyActiveNetwork(TRANSPORT_CELLULAR);
1124 // Reevaluate cellular (it'll instantly fail DNS).
1125 cv = waitForConnectivityBroadcasts(2);
1126 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1127 NET_CAPABILITY_VALIDATED));
1128 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
1129 // Should quickly fall back to WiFi.
1131 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1132 NET_CAPABILITY_VALIDATED));
1133 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1134 NET_CAPABILITY_VALIDATED));
1135 verifyActiveNetwork(TRANSPORT_WIFI);
1139 public void testWiFiFallback() throws Exception {
1140 // Test bringing up unvalidated WiFi.
1141 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1142 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1143 mWiFiNetworkAgent.connect(false);
1145 verifyActiveNetwork(TRANSPORT_WIFI);
1146 // Test bringing up validated cellular.
1147 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1148 cv = waitForConnectivityBroadcasts(2);
1149 mCellNetworkAgent.connect(true);
1151 verifyActiveNetwork(TRANSPORT_CELLULAR);
1152 // Reevaluate cellular (it'll instantly fail DNS).
1153 cv = waitForConnectivityBroadcasts(2);
1154 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1155 NET_CAPABILITY_VALIDATED));
1156 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
1157 // Should quickly fall back to WiFi.
1159 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1160 NET_CAPABILITY_VALIDATED));
1161 verifyActiveNetwork(TRANSPORT_WIFI);
1164 enum CallbackState {
1167 NETWORK_CAPABILITIES,
1175 private static class CallbackInfo {
1176 public final CallbackState state;
1177 public final Network network;
1178 public final Object arg;
1179 public CallbackInfo(CallbackState s, Network n, Object o) {
1180 state = s; network = n; arg = o;
1182 public String toString() {
1183 return String.format("%s (%s) (%s)", state, network, arg);
1186 public boolean equals(Object o) {
1187 if (!(o instanceof CallbackInfo)) return false;
1188 // Ignore timeMs, since it's unpredictable.
1189 CallbackInfo other = (CallbackInfo) o;
1190 return (state == other.state) && Objects.equals(network, other.network);
1193 public int hashCode() {
1194 return Objects.hash(state, network);
1199 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks
1200 * this class receives, by calling expectCallback() exactly once each time a callback is
1201 * received. assertNoCallback may be called at any time.
1203 private class TestNetworkCallback extends NetworkCallback {
1204 // Chosen to be much less than the linger timeout. This ensures that we can distinguish
1205 // between a LOST callback that arrives immediately and a LOST callback that arrives after
1206 // the linger timeout.
1207 private final static int TIMEOUT_MS = 100;
1209 private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
1211 protected void setLastCallback(CallbackState state, Network network, Object o) {
1212 mCallbacks.offer(new CallbackInfo(state, network, o));
1216 public void onAvailable(Network network) {
1217 setLastCallback(CallbackState.AVAILABLE, network, null);
1221 public void onCapabilitiesChanged(Network network, NetworkCapabilities netCap) {
1222 setLastCallback(CallbackState.NETWORK_CAPABILITIES, network, netCap);
1226 public void onLinkPropertiesChanged(Network network, LinkProperties linkProp) {
1227 setLastCallback(CallbackState.LINK_PROPERTIES, network, linkProp);
1231 public void onUnavailable() {
1232 setLastCallback(CallbackState.UNAVAILABLE, null, null);
1236 public void onNetworkSuspended(Network network) {
1237 setLastCallback(CallbackState.SUSPENDED, network, null);
1241 public void onLosing(Network network, int maxMsToLive) {
1242 setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
1246 public void onLost(Network network) {
1247 setLastCallback(CallbackState.LOST, network, null);
1250 CallbackInfo nextCallback(int timeoutMs) {
1251 CallbackInfo cb = null;
1253 cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS);
1254 } catch (InterruptedException e) {
1257 // LinkedBlockingQueue.poll() returns null if it timeouts.
1258 fail("Did not receive callback after " + timeoutMs + "ms");
1263 CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent, int timeoutMs) {
1264 final Network expectedNetwork = (agent != null) ? agent.getNetwork() : null;
1265 CallbackInfo expected = new CallbackInfo(state, expectedNetwork, 0);
1266 CallbackInfo actual = nextCallback(timeoutMs);
1267 assertEquals("Unexpected callback:", expected, actual);
1269 if (state == CallbackState.LOSING) {
1270 String msg = String.format(
1271 "Invalid linger time value %d, must be between %d and %d",
1272 actual.arg, 0, TEST_LINGER_DELAY_MS);
1273 int maxMsToLive = (Integer) actual.arg;
1274 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= TEST_LINGER_DELAY_MS);
1280 CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent) {
1281 return expectCallback(state, agent, TIMEOUT_MS);
1284 void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended, int timeoutMs) {
1285 expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
1286 if (expectSuspended) {
1287 expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
1289 expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
1290 expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs);
1293 void expectAvailableCallbacks(MockNetworkAgent agent) {
1294 expectAvailableCallbacks(agent, false, TIMEOUT_MS);
1297 void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent) {
1298 expectAvailableCallbacks(agent, true, TIMEOUT_MS);
1301 void expectAvailableAndValidatedCallbacks(MockNetworkAgent agent) {
1302 expectAvailableCallbacks(agent, false, TIMEOUT_MS);
1303 expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
1306 void expectCapabilitiesWith(int capability, MockNetworkAgent agent) {
1307 CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent);
1308 NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
1309 assertTrue(nc.hasCapability(capability));
1312 void expectCapabilitiesWithout(int capability, MockNetworkAgent agent) {
1313 CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent);
1314 NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
1315 assertFalse(nc.hasCapability(capability));
1318 void assertNoCallback() {
1320 CallbackInfo c = mCallbacks.peek();
1321 assertNull("Unexpected callback: " + c, c);
1325 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can
1326 // only be declared in a static or top level type".
1327 static void assertNoCallbacks(TestNetworkCallback ... callbacks) {
1328 for (TestNetworkCallback c : callbacks) {
1329 c.assertNoCallback();
1334 public void testStateChangeNetworkCallbacks() throws Exception {
1335 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
1336 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
1337 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
1338 final NetworkRequest genericRequest = new NetworkRequest.Builder()
1339 .clearCapabilities().build();
1340 final NetworkRequest wifiRequest = new NetworkRequest.Builder()
1341 .addTransportType(TRANSPORT_WIFI).build();
1342 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1343 .addTransportType(TRANSPORT_CELLULAR).build();
1344 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback);
1345 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
1346 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
1348 // Test unvalidated networks
1349 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1350 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1351 mCellNetworkAgent.connect(false);
1352 genericNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent);
1353 cellNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent);
1354 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1356 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1358 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1359 mCellNetworkAgent.adjustScore(-1);
1361 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1362 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1364 cv = waitForConnectivityBroadcasts(2);
1365 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1366 mWiFiNetworkAgent.connect(false);
1367 genericNetworkCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1368 wifiNetworkCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1369 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1371 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1373 cv = waitForConnectivityBroadcasts(2);
1374 mWiFiNetworkAgent.disconnect();
1375 genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1376 wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1377 cellNetworkCallback.assertNoCallback();
1379 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1381 cv = waitForConnectivityBroadcasts(1);
1382 mCellNetworkAgent.disconnect();
1383 genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1384 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1386 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1388 // Test validated networks
1389 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1390 mCellNetworkAgent.connect(true);
1391 genericNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
1392 cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
1393 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1394 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1396 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1397 mCellNetworkAgent.adjustScore(-1);
1399 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1400 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1402 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1403 mWiFiNetworkAgent.connect(true);
1404 genericNetworkCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1405 genericNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1406 genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
1407 wifiNetworkCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
1408 cellNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1409 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1410 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1412 mWiFiNetworkAgent.disconnect();
1413 genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1414 wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1415 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1417 mCellNetworkAgent.disconnect();
1418 genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1419 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1420 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
1424 public void testMultipleLingering() {
1425 NetworkRequest request = new NetworkRequest.Builder()
1426 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED)
1428 TestNetworkCallback callback = new TestNetworkCallback();
1429 mCm.registerNetworkCallback(request, callback);
1431 TestNetworkCallback defaultCallback = new TestNetworkCallback();
1432 mCm.registerDefaultNetworkCallback(defaultCallback);
1434 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1435 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1436 mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
1438 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1439 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1440 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1442 mCellNetworkAgent.connect(true);
1443 callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
1444 defaultCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
1445 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1447 mWiFiNetworkAgent.connect(true);
1448 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request.
1449 // We then get LOSING when wifi validates and cell is outscored.
1450 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1451 // TODO: Investigate sending validated before losing.
1452 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1453 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
1454 defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
1455 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1457 mEthernetNetworkAgent.connect(true);
1458 callback.expectAvailableCallbacks(mEthernetNetworkAgent);
1459 // TODO: Investigate sending validated before losing.
1460 callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
1461 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
1462 defaultCallback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
1463 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1465 mEthernetNetworkAgent.disconnect();
1466 callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1467 defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1468 defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1470 for (int i = 0; i < 4; i++) {
1471 MockNetworkAgent oldNetwork, newNetwork;
1473 mWiFiNetworkAgent.adjustScore(-15);
1474 oldNetwork = mWiFiNetworkAgent;
1475 newNetwork = mCellNetworkAgent;
1477 mWiFiNetworkAgent.adjustScore(15);
1478 oldNetwork = mCellNetworkAgent;
1479 newNetwork = mWiFiNetworkAgent;
1482 callback.expectCallback(CallbackState.LOSING, oldNetwork);
1483 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no
1484 // longer lingering?
1485 defaultCallback.expectAvailableCallbacks(newNetwork);
1486 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork());
1488 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1490 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even
1491 // if the network is still up.
1492 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
1493 // We expect a notification about the capabilities change, and nothing else.
1494 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent);
1495 defaultCallback.assertNoCallback();
1496 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1498 // Wifi no longer satisfies our listen, which is for an unmetered network.
1499 // But because its score is 55, it's still up (and the default network).
1500 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1502 // Disconnect our test networks.
1503 mWiFiNetworkAgent.disconnect();
1504 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1505 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
1506 mCellNetworkAgent.disconnect();
1507 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1509 mCm.unregisterNetworkCallback(callback);
1512 // Check that a network is only lingered or torn down if it would not satisfy a request even
1514 request = new NetworkRequest.Builder().clearCapabilities().build();
1515 callback = new TestNetworkCallback();
1517 mCm.registerNetworkCallback(request, callback);
1519 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1520 mCellNetworkAgent.connect(false); // Score: 10
1521 callback.expectAvailableCallbacks(mCellNetworkAgent);
1522 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
1523 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1525 // Bring up wifi with a score of 20.
1526 // Cell stays up because it would satisfy the default request if it validated.
1527 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1528 mWiFiNetworkAgent.connect(false); // Score: 20
1529 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1530 defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1531 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1533 mWiFiNetworkAgent.disconnect();
1534 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1535 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1536 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
1537 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1539 // Bring up wifi with a score of 70.
1540 // Cell is lingered because it would not satisfy any request, even if it validated.
1541 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1542 mWiFiNetworkAgent.adjustScore(50);
1543 mWiFiNetworkAgent.connect(false); // Score: 70
1544 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1545 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1546 defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1547 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1550 mWiFiNetworkAgent.disconnect();
1551 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1552 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1553 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
1554 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1556 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but
1557 // it's arguably correct to linger it, since it was the default network before it validated.
1558 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1559 mWiFiNetworkAgent.connect(true);
1560 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1561 // TODO: Investigate sending validated before losing.
1562 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1563 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
1564 defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
1565 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1567 mWiFiNetworkAgent.disconnect();
1568 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1569 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1570 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
1571 mCellNetworkAgent.disconnect();
1572 callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1573 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1575 // If a network is lingering, and we add and remove a request from it, resume lingering.
1576 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1577 mCellNetworkAgent.connect(true);
1578 callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
1579 defaultCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
1580 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1581 mWiFiNetworkAgent.connect(true);
1582 defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
1583 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1584 // TODO: Investigate sending validated before losing.
1585 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1586 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
1588 NetworkRequest cellRequest = new NetworkRequest.Builder()
1589 .addTransportType(TRANSPORT_CELLULAR).build();
1590 NetworkCallback noopCallback = new NetworkCallback();
1591 mCm.requestNetwork(cellRequest, noopCallback);
1592 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer
1594 mCm.unregisterNetworkCallback(noopCallback);
1595 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1597 // Similar to the above: lingering can start even after the lingered request is removed.
1598 // Disconnect wifi and switch to cell.
1599 mWiFiNetworkAgent.disconnect();
1600 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1601 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1602 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
1604 // Cell is now the default network. Pin it with a cell-specific request.
1605 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525
1606 mCm.requestNetwork(cellRequest, noopCallback);
1608 // Now connect wifi, and expect it to become the default network.
1609 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1610 mWiFiNetworkAgent.connect(true);
1611 callback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
1612 defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
1613 // The default request is lingering on cell, but nothing happens to cell, and we send no
1614 // callbacks for it, because it's kept up by cellRequest.
1615 callback.assertNoCallback();
1616 // Now unregister cellRequest and expect cell to start lingering.
1617 mCm.unregisterNetworkCallback(noopCallback);
1618 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1620 // Let linger run its course.
1621 callback.assertNoCallback();
1622 final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
1623 callback.expectCallback(CallbackState.LOST, mCellNetworkAgent, lingerTimeoutMs);
1625 // Register a TRACK_DEFAULT request and check that it does not affect lingering.
1626 TestNetworkCallback trackDefaultCallback = new TestNetworkCallback();
1627 mCm.registerDefaultNetworkCallback(trackDefaultCallback);
1628 trackDefaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1629 mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
1630 mEthernetNetworkAgent.connect(true);
1631 callback.expectAvailableCallbacks(mEthernetNetworkAgent);
1632 callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
1633 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
1634 trackDefaultCallback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
1635 defaultCallback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
1637 // Let linger run its course.
1638 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
1641 mEthernetNetworkAgent.disconnect();
1642 callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1643 defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1644 trackDefaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1646 mCm.unregisterNetworkCallback(callback);
1647 mCm.unregisterNetworkCallback(defaultCallback);
1648 mCm.unregisterNetworkCallback(trackDefaultCallback);
1652 public void testExplicitlySelected() {
1653 NetworkRequest request = new NetworkRequest.Builder()
1654 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
1656 TestNetworkCallback callback = new TestNetworkCallback();
1657 mCm.registerNetworkCallback(request, callback);
1659 // Bring up validated cell.
1660 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1661 mCellNetworkAgent.connect(true);
1662 callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
1664 // Bring up unvalidated wifi with explicitlySelected=true.
1665 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1666 mWiFiNetworkAgent.explicitlySelected(false);
1667 mWiFiNetworkAgent.connect(false);
1668 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1670 // Cell Remains the default.
1671 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1673 // Lower wifi's score to below than cell, and check that it doesn't disconnect because
1674 // it's explicitly selected.
1675 mWiFiNetworkAgent.adjustScore(-40);
1676 mWiFiNetworkAgent.adjustScore(40);
1677 callback.assertNoCallback();
1679 // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to
1680 // wifi even though it's unvalidated.
1681 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false);
1682 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1683 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1685 // Disconnect wifi, and then reconnect, again with explicitlySelected=true.
1686 mWiFiNetworkAgent.disconnect();
1687 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1688 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1689 mWiFiNetworkAgent.explicitlySelected(false);
1690 mWiFiNetworkAgent.connect(false);
1691 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1693 // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the
1694 // network to disconnect.
1695 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false);
1696 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1698 // Reconnect, again with explicitlySelected=true, but this time validate.
1699 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1700 mWiFiNetworkAgent.explicitlySelected(false);
1701 mWiFiNetworkAgent.connect(true);
1702 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
1703 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1704 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
1705 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1707 // BUG: the network will no longer linger, even though it's validated and outscored.
1709 mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
1710 mEthernetNetworkAgent.connect(true);
1711 callback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
1712 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1713 callback.assertNoCallback();
1716 mWiFiNetworkAgent.disconnect();
1717 mCellNetworkAgent.disconnect();
1718 mEthernetNetworkAgent.disconnect();
1720 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1721 callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1722 callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1725 private void tryNetworkFactoryRequests(int capability) throws Exception {
1726 // Verify NOT_RESTRICTED is set appropriately
1727 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
1728 .build().networkCapabilities;
1729 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
1730 capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
1731 capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
1732 capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
1733 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1735 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1738 NetworkCapabilities filter = new NetworkCapabilities();
1739 filter.addCapability(capability);
1740 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
1741 handlerThread.start();
1742 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
1743 mServiceContext, "testFactory", filter);
1744 testFactory.setScoreFilter(40);
1745 ConditionVariable cv = testFactory.getNetworkStartedCV();
1746 testFactory.expectAddRequests(1);
1747 testFactory.register();
1748 testFactory.waitForNetworkRequests(1);
1749 int expectedRequestCount = 1;
1750 NetworkCallback networkCallback = null;
1751 // For non-INTERNET capabilities we cannot rely on the default request being present, so
1753 if (capability != NET_CAPABILITY_INTERNET) {
1754 assertFalse(testFactory.getMyStartRequested());
1755 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
1756 networkCallback = new NetworkCallback();
1757 testFactory.expectAddRequests(1);
1758 mCm.requestNetwork(request, networkCallback);
1759 expectedRequestCount++;
1760 testFactory.waitForNetworkRequests(expectedRequestCount);
1763 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1764 assertTrue(testFactory.getMyStartRequested());
1766 // Now bring in a higher scored network.
1767 MockNetworkAgent testAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1768 // Rather than create a validated network which complicates things by registering it's
1769 // own NetworkRequest during startup, just bump up the score to cancel out the
1770 // unvalidated penalty.
1771 testAgent.adjustScore(40);
1772 cv = testFactory.getNetworkStoppedCV();
1774 // When testAgent connects, ConnectivityService will re-send us all current requests with
1775 // the new score. There are expectedRequestCount such requests, and we must wait for all of
1777 testFactory.expectAddRequests(expectedRequestCount);
1778 testAgent.connect(false);
1779 testAgent.addCapability(capability);
1781 testFactory.waitForNetworkRequests(expectedRequestCount);
1782 assertFalse(testFactory.getMyStartRequested());
1784 // Bring in a bunch of requests.
1785 testFactory.expectAddRequests(10);
1786 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1787 ConnectivityManager.NetworkCallback[] networkCallbacks =
1788 new ConnectivityManager.NetworkCallback[10];
1789 for (int i = 0; i< networkCallbacks.length; i++) {
1790 networkCallbacks[i] = new ConnectivityManager.NetworkCallback();
1791 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1792 builder.addCapability(capability);
1793 mCm.requestNetwork(builder.build(), networkCallbacks[i]);
1795 testFactory.waitForNetworkRequests(10 + expectedRequestCount);
1796 assertFalse(testFactory.getMyStartRequested());
1798 // Remove the requests.
1799 testFactory.expectRemoveRequests(10);
1800 for (int i = 0; i < networkCallbacks.length; i++) {
1801 mCm.unregisterNetworkCallback(networkCallbacks[i]);
1803 testFactory.waitForNetworkRequests(expectedRequestCount);
1804 assertFalse(testFactory.getMyStartRequested());
1806 // Drop the higher scored network.
1807 cv = testFactory.getNetworkStartedCV();
1808 testAgent.disconnect();
1810 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1811 assertTrue(testFactory.getMyStartRequested());
1813 testFactory.unregister();
1814 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback);
1815 handlerThread.quit();
1819 public void testNetworkFactoryRequests() throws Exception {
1820 tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
1821 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
1822 tryNetworkFactoryRequests(NET_CAPABILITY_DUN);
1823 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA);
1824 tryNetworkFactoryRequests(NET_CAPABILITY_IMS);
1825 tryNetworkFactoryRequests(NET_CAPABILITY_CBS);
1826 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P);
1827 tryNetworkFactoryRequests(NET_CAPABILITY_IA);
1828 tryNetworkFactoryRequests(NET_CAPABILITY_RCS);
1829 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP);
1830 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS);
1831 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED);
1832 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET);
1833 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED);
1834 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN);
1835 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
1839 public void testNoMutableNetworkRequests() throws Exception {
1840 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
1841 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1842 builder.addCapability(NET_CAPABILITY_VALIDATED);
1844 mCm.requestNetwork(builder.build(), new NetworkCallback());
1846 } catch (IllegalArgumentException expected) {}
1848 mCm.requestNetwork(builder.build(), pendingIntent);
1850 } catch (IllegalArgumentException expected) {}
1851 builder = new NetworkRequest.Builder();
1852 builder.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
1854 mCm.requestNetwork(builder.build(), new NetworkCallback());
1856 } catch (IllegalArgumentException expected) {}
1858 mCm.requestNetwork(builder.build(), pendingIntent);
1860 } catch (IllegalArgumentException expected) {}
1864 public void testMMSonWiFi() throws Exception {
1865 // Test bringing up cellular without MMS NetworkRequest gets reaped
1866 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1867 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1868 ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV();
1869 mCellNetworkAgent.connectWithoutInternet();
1872 assertEquals(0, mCm.getAllNetworks().length);
1875 // Test bringing up validated WiFi.
1876 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1877 cv = waitForConnectivityBroadcasts(1);
1878 mWiFiNetworkAgent.connect(true);
1880 verifyActiveNetwork(TRANSPORT_WIFI);
1882 // Register MMS NetworkRequest
1883 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1884 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1885 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1886 mCm.requestNetwork(builder.build(), networkCallback);
1888 // Test bringing up unvalidated cellular with MMS
1889 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1890 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1891 mCellNetworkAgent.connectWithoutInternet();
1892 networkCallback.expectAvailableCallbacks(mCellNetworkAgent);
1893 verifyActiveNetwork(TRANSPORT_WIFI);
1895 // Test releasing NetworkRequest disconnects cellular with MMS
1896 cv = mCellNetworkAgent.getDisconnectedCV();
1897 mCm.unregisterNetworkCallback(networkCallback);
1899 verifyActiveNetwork(TRANSPORT_WIFI);
1903 public void testMMSonCell() throws Exception {
1904 // Test bringing up cellular without MMS
1905 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1906 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1907 mCellNetworkAgent.connect(false);
1909 verifyActiveNetwork(TRANSPORT_CELLULAR);
1911 // Register MMS NetworkRequest
1912 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1913 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1914 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1915 mCm.requestNetwork(builder.build(), networkCallback);
1917 // Test bringing up MMS cellular network
1918 MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1919 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1920 mmsNetworkAgent.connectWithoutInternet();
1921 networkCallback.expectAvailableCallbacks(mmsNetworkAgent);
1922 verifyActiveNetwork(TRANSPORT_CELLULAR);
1924 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
1925 cv = mmsNetworkAgent.getDisconnectedCV();
1926 mCm.unregisterNetworkCallback(networkCallback);
1928 verifyActiveNetwork(TRANSPORT_CELLULAR);
1932 public void testCaptivePortal() {
1933 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1934 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1935 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1936 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1938 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1939 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1940 .addCapability(NET_CAPABILITY_VALIDATED).build();
1941 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
1943 // Bring up a network with a captive portal.
1944 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
1945 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1946 String firstRedirectUrl = "http://example.com/firstPath";
1947 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
1948 captivePortalCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1949 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
1951 // Take down network.
1952 // Expect onLost callback.
1953 mWiFiNetworkAgent.disconnect();
1954 captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1956 // Bring up a network with a captive portal.
1957 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
1958 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1959 String secondRedirectUrl = "http://example.com/secondPath";
1960 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
1961 captivePortalCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1962 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl);
1964 // Make captive portal disappear then revalidate.
1965 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
1966 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
1967 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
1968 captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1970 // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
1971 validatedCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
1972 // TODO: Investigate only sending available callbacks.
1973 validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
1975 // Break network connectivity.
1976 // Expect NET_CAPABILITY_VALIDATED onLost callback.
1977 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
1978 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
1979 validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1983 public void testCaptivePortalApp() {
1984 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1985 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1986 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1987 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1989 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1990 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1991 .addCapability(NET_CAPABILITY_VALIDATED).build();
1992 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
1995 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1996 mWiFiNetworkAgent.connect(true);
1997 validatedCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
1998 Network wifiNetwork = mWiFiNetworkAgent.getNetwork();
2000 // Check that calling startCaptivePortalApp does nothing.
2001 final int fastTimeoutMs = 100;
2002 mCm.startCaptivePortalApp(wifiNetwork);
2003 mServiceContext.expectNoStartActivityIntent(fastTimeoutMs);
2005 // Turn into a captive portal.
2006 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 302;
2007 mCm.reportNetworkConnectivity(wifiNetwork, false);
2008 captivePortalCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2009 validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2011 // Check that startCaptivePortalApp sends the expected intent.
2012 mCm.startCaptivePortalApp(wifiNetwork);
2013 Intent intent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS);
2014 assertEquals(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN, intent.getAction());
2015 assertEquals(wifiNetwork, intent.getExtra(ConnectivityManager.EXTRA_NETWORK));
2017 // Have the app report that the captive portal is dismissed, and check that we revalidate.
2018 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
2019 CaptivePortal c = (CaptivePortal) intent.getExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
2020 c.reportCaptivePortalDismissed();
2021 validatedCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2022 captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2024 mCm.unregisterNetworkCallback(validatedCallback);
2025 mCm.unregisterNetworkCallback(captivePortalCallback);
2029 public void testAvoidOrIgnoreCaptivePortals() {
2030 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
2031 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
2032 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
2033 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
2035 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
2036 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
2037 .addCapability(NET_CAPABILITY_VALIDATED).build();
2038 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
2040 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_AVOID);
2041 // Bring up a network with a captive portal.
2042 // Expect it to fail to connect and not result in any callbacks.
2043 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2044 String firstRedirectUrl = "http://example.com/firstPath";
2046 ConditionVariable disconnectCv = mWiFiNetworkAgent.getDisconnectedCV();
2047 ConditionVariable avoidCv = mWiFiNetworkAgent.getPreventReconnectReceived();
2048 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
2049 waitFor(disconnectCv);
2052 assertNoCallbacks(captivePortalCallback, validatedCallback);
2054 // Now test ignore mode.
2055 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
2057 // Bring up a network with a captive portal.
2058 // Since we're ignoring captive portals, the network will validate.
2059 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2060 String secondRedirectUrl = "http://example.com/secondPath";
2061 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
2063 // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
2064 validatedCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2065 // But there should be no CaptivePortal callback.
2066 captivePortalCallback.assertNoCallback();
2069 private NetworkRequest.Builder newWifiRequestBuilder() {
2070 return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
2074 public void testNetworkSpecifier() {
2075 NetworkRequest rEmpty1 = newWifiRequestBuilder().build();
2076 NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build();
2077 NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build();
2078 NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier(
2079 (NetworkSpecifier) null).build();
2080 NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier("foo").build();
2081 NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier(
2082 new StringNetworkSpecifier("bar")).build();
2084 TestNetworkCallback cEmpty1 = new TestNetworkCallback();
2085 TestNetworkCallback cEmpty2 = new TestNetworkCallback();
2086 TestNetworkCallback cEmpty3 = new TestNetworkCallback();
2087 TestNetworkCallback cEmpty4 = new TestNetworkCallback();
2088 TestNetworkCallback cFoo = new TestNetworkCallback();
2089 TestNetworkCallback cBar = new TestNetworkCallback();
2090 TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] {
2091 cEmpty1, cEmpty2, cEmpty3 };
2093 mCm.registerNetworkCallback(rEmpty1, cEmpty1);
2094 mCm.registerNetworkCallback(rEmpty2, cEmpty2);
2095 mCm.registerNetworkCallback(rEmpty3, cEmpty3);
2096 mCm.registerNetworkCallback(rEmpty4, cEmpty4);
2097 mCm.registerNetworkCallback(rFoo, cFoo);
2098 mCm.registerNetworkCallback(rBar, cBar);
2100 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2101 mWiFiNetworkAgent.connect(false);
2102 cEmpty1.expectAvailableCallbacks(mWiFiNetworkAgent);
2103 cEmpty2.expectAvailableCallbacks(mWiFiNetworkAgent);
2104 cEmpty3.expectAvailableCallbacks(mWiFiNetworkAgent);
2105 cEmpty4.expectAvailableCallbacks(mWiFiNetworkAgent);
2106 assertNoCallbacks(cFoo, cBar);
2108 mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("foo"));
2109 cFoo.expectAvailableCallbacks(mWiFiNetworkAgent);
2110 for (TestNetworkCallback c: emptyCallbacks) {
2111 c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
2113 cFoo.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
2114 cFoo.assertNoCallback();
2116 mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("bar"));
2117 cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2118 cBar.expectAvailableCallbacks(mWiFiNetworkAgent);
2119 for (TestNetworkCallback c: emptyCallbacks) {
2120 c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
2122 cBar.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
2123 cBar.assertNoCallback();
2125 mWiFiNetworkAgent.setNetworkSpecifier(null);
2126 cBar.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2127 for (TestNetworkCallback c: emptyCallbacks) {
2128 c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
2131 assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cFoo, cBar);
2135 public void testInvalidNetworkSpecifier() {
2137 NetworkRequest.Builder builder = new NetworkRequest.Builder();
2138 builder.setNetworkSpecifier(new MatchAllNetworkSpecifier());
2139 fail("NetworkRequest builder with MatchAllNetworkSpecifier");
2140 } catch (IllegalArgumentException expected) {
2145 NetworkCapabilities networkCapabilities = new NetworkCapabilities();
2146 networkCapabilities.addTransportType(TRANSPORT_WIFI)
2147 .setNetworkSpecifier(new MatchAllNetworkSpecifier());
2148 mService.requestNetwork(networkCapabilities, null, 0, null,
2149 ConnectivityManager.TYPE_WIFI);
2150 fail("ConnectivityService requestNetwork with MatchAllNetworkSpecifier");
2151 } catch (IllegalArgumentException expected) {
2155 class NonParcelableSpecifier extends NetworkSpecifier {
2156 public boolean satisfiedBy(NetworkSpecifier other) { return false; }
2158 class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable {
2159 @Override public int describeContents() { return 0; }
2160 @Override public void writeToParcel(Parcel p, int flags) {}
2162 NetworkRequest.Builder builder;
2164 builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
2166 builder.setNetworkSpecifier(new NonParcelableSpecifier());
2167 Parcel parcelW = Parcel.obtain();
2168 builder.build().writeToParcel(parcelW, 0);
2169 fail("Parceling a non-parcelable specifier did not throw an exception");
2170 } catch (Exception e) {
2174 builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
2175 builder.setNetworkSpecifier(new ParcelableSpecifier());
2176 NetworkRequest nr = builder.build();
2180 Parcel parcelW = Parcel.obtain();
2181 nr.writeToParcel(parcelW, 0);
2182 byte[] bytes = parcelW.marshall();
2185 Parcel parcelR = Parcel.obtain();
2186 parcelR.unmarshall(bytes, 0, bytes.length);
2187 parcelR.setDataPosition(0);
2188 NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR);
2189 fail("Unparceling a non-framework NetworkSpecifier did not throw an exception");
2190 } catch (Exception e) {
2196 public void testNetworkSpecifierUidSpoofSecurityException() {
2197 class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
2199 public boolean satisfiedBy(NetworkSpecifier other) {
2204 public void assertValidFromUid(int requestorUid) {
2205 throw new SecurityException("failure");
2209 public int describeContents() { return 0; }
2211 public void writeToParcel(Parcel dest, int flags) {}
2214 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2215 mWiFiNetworkAgent.connect(false);
2217 UidAwareNetworkSpecifier networkSpecifier = new UidAwareNetworkSpecifier();
2218 NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier(
2219 networkSpecifier).build();
2220 TestNetworkCallback networkCallback = new TestNetworkCallback();
2222 mCm.requestNetwork(networkRequest, networkCallback);
2223 fail("Network request with spoofed UID did not throw a SecurityException");
2224 } catch (SecurityException e) {
2230 public void testRegisterDefaultNetworkCallback() throws Exception {
2231 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
2232 mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
2233 defaultNetworkCallback.assertNoCallback();
2235 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up
2236 // whenever Wi-Fi is up. Without this, the mobile network agent is
2237 // reaped before any other activity can take place.
2238 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2239 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2240 .addTransportType(TRANSPORT_CELLULAR).build();
2241 mCm.requestNetwork(cellRequest, cellNetworkCallback);
2242 cellNetworkCallback.assertNoCallback();
2244 // Bring up cell and expect CALLBACK_AVAILABLE.
2245 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2246 mCellNetworkAgent.connect(true);
2247 cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2248 defaultNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2250 // Bring up wifi and expect CALLBACK_AVAILABLE.
2251 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2252 mWiFiNetworkAgent.connect(true);
2253 cellNetworkCallback.assertNoCallback();
2254 defaultNetworkCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
2256 // Bring down cell. Expect no default network callback, since it wasn't the default.
2257 mCellNetworkAgent.disconnect();
2258 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2259 defaultNetworkCallback.assertNoCallback();
2261 // Bring up cell. Expect no default network callback, since it won't be the default.
2262 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2263 mCellNetworkAgent.connect(true);
2264 cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2265 defaultNetworkCallback.assertNoCallback();
2267 // Bring down wifi. Expect the default network callback to notified of LOST wifi
2268 // followed by AVAILABLE cell.
2269 mWiFiNetworkAgent.disconnect();
2270 cellNetworkCallback.assertNoCallback();
2271 defaultNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2272 defaultNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent);
2273 mCellNetworkAgent.disconnect();
2274 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2275 defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2279 public void testAdditionalStateCallbacks() throws Exception {
2280 // File a network request for mobile.
2281 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2282 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2283 .addTransportType(TRANSPORT_CELLULAR).build();
2284 mCm.requestNetwork(cellRequest, cellNetworkCallback);
2286 // Bring up the mobile network.
2287 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2288 mCellNetworkAgent.connect(true);
2290 // We should get onAvailable(), onCapabilitiesChanged(), and
2291 // onLinkPropertiesChanged() in rapid succession. Additionally, we
2292 // should get onCapabilitiesChanged() when the mobile network validates.
2293 cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2294 cellNetworkCallback.assertNoCallback();
2296 // Update LinkProperties.
2297 final LinkProperties lp = new LinkProperties();
2298 lp.setInterfaceName("foonet_data0");
2299 mCellNetworkAgent.sendLinkProperties(lp);
2300 // We should get onLinkPropertiesChanged().
2301 cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
2302 cellNetworkCallback.assertNoCallback();
2304 // Suspend the network.
2305 mCellNetworkAgent.suspend();
2306 cellNetworkCallback.expectCallback(CallbackState.SUSPENDED, mCellNetworkAgent);
2307 cellNetworkCallback.assertNoCallback();
2309 // Register a garden variety default network request.
2310 final TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();
2311 mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
2312 // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(),
2313 // as well as onNetworkSuspended() in rapid succession.
2314 dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent);
2315 dfltNetworkCallback.assertNoCallback();
2317 mCm.unregisterNetworkCallback(dfltNetworkCallback);
2318 mCm.unregisterNetworkCallback(cellNetworkCallback);
2321 private void setCaptivePortalMode(int mode) {
2322 ContentResolver cr = mServiceContext.getContentResolver();
2323 Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
2326 private void setMobileDataAlwaysOn(boolean enable) {
2327 ContentResolver cr = mServiceContext.getContentResolver();
2328 Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0);
2329 mService.updateMobileDataAlwaysOn();
2333 private boolean isForegroundNetwork(MockNetworkAgent network) {
2334 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork());
2336 return nc.hasCapability(NET_CAPABILITY_FOREGROUND);
2340 public void testBackgroundNetworks() throws Exception {
2341 // Create a background request. We can't do this ourselves because ConnectivityService
2342 // doesn't have an API for it. So just turn on mobile data always on.
2343 setMobileDataAlwaysOn(true);
2344 final NetworkRequest request = new NetworkRequest.Builder().build();
2345 final NetworkRequest fgRequest = new NetworkRequest.Builder()
2346 .addCapability(NET_CAPABILITY_FOREGROUND).build();
2347 final TestNetworkCallback callback = new TestNetworkCallback();
2348 final TestNetworkCallback fgCallback = new TestNetworkCallback();
2349 mCm.registerNetworkCallback(request, callback);
2350 mCm.registerNetworkCallback(fgRequest, fgCallback);
2352 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2353 mCellNetworkAgent.connect(true);
2354 callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2355 fgCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2356 assertTrue(isForegroundNetwork(mCellNetworkAgent));
2358 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2359 mWiFiNetworkAgent.connect(true);
2361 // When wifi connects, cell lingers.
2362 callback.expectAvailableCallbacks(mWiFiNetworkAgent);
2363 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
2364 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
2365 fgCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2366 fgCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
2367 fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
2368 assertTrue(isForegroundNetwork(mCellNetworkAgent));
2369 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
2371 // When lingering is complete, cell is still there but is now in the background.
2373 int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
2374 fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent, timeoutMs);
2375 // Expect a network capabilities update sans FOREGROUND.
2376 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
2377 assertFalse(isForegroundNetwork(mCellNetworkAgent));
2378 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
2380 // File a cell request and check that cell comes into the foreground.
2381 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2382 .addTransportType(TRANSPORT_CELLULAR).build();
2383 final TestNetworkCallback cellCallback = new TestNetworkCallback();
2384 mCm.requestNetwork(cellRequest, cellCallback);
2385 // NOTE: This request causes the network's capabilities to change. This
2386 // is currently delivered before the onAvailable() callbacks.
2388 cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
2389 cellCallback.expectAvailableCallbacks(mCellNetworkAgent);
2390 fgCallback.expectAvailableCallbacks(mCellNetworkAgent);
2391 // Expect a network capabilities update with FOREGROUND, because the most recent
2392 // request causes its state to change.
2393 callback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
2394 assertTrue(isForegroundNetwork(mCellNetworkAgent));
2395 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
2397 // Release the request. The network immediately goes into the background, since it was not
2399 mCm.unregisterNetworkCallback(cellCallback);
2400 fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2401 // Expect a network capabilities update sans FOREGROUND.
2402 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
2403 assertFalse(isForegroundNetwork(mCellNetworkAgent));
2404 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
2406 // Disconnect wifi and check that cell is foreground again.
2407 mWiFiNetworkAgent.disconnect();
2408 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2409 fgCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2410 fgCallback.expectAvailableCallbacks(mCellNetworkAgent);
2411 assertTrue(isForegroundNetwork(mCellNetworkAgent));
2413 mCm.unregisterNetworkCallback(callback);
2414 mCm.unregisterNetworkCallback(fgCallback);
2417 @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing.
2418 public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception {
2419 // TODO: turn this unit test into a real benchmarking test.
2420 // Benchmarks connecting and switching performance in the presence of a large number of
2422 // 1. File NUM_REQUESTS requests.
2423 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire.
2424 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing
2425 // and NUM_REQUESTS onAvailable callbacks to fire.
2426 // See how long it took.
2427 final int NUM_REQUESTS = 90;
2428 final int REGISTER_TIME_LIMIT_MS = 200;
2429 final int CONNECT_TIME_LIMIT_MS = 60;
2430 final int SWITCH_TIME_LIMIT_MS = 60;
2431 final int UNREGISTER_TIME_LIMIT_MS = 20;
2433 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
2434 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS];
2435 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS);
2436 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS);
2438 for (int i = 0; i < NUM_REQUESTS; i++) {
2439 callbacks[i] = new NetworkCallback() {
2440 @Override public void onAvailable(Network n) { availableLatch.countDown(); }
2441 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); }
2445 assertTimeLimit("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> {
2446 for (NetworkCallback cb : callbacks) {
2447 mCm.registerNetworkCallback(request, cb);
2451 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2452 // Don't request that the network validate, because otherwise connect() will block until
2453 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired,
2454 // and we won't actually measure anything.
2455 mCellNetworkAgent.connect(false);
2457 long onAvailableDispatchingDuration = durationOf(() -> {
2458 awaitLatch(availableLatch, 10 * CONNECT_TIME_LIMIT_MS);
2460 Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms",
2461 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
2462 onAvailableDispatchingDuration));
2463 assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms",
2464 NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS),
2465 onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS);
2467 // Give wifi a high enough score that we'll linger cell when wifi comes up.
2468 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2469 mWiFiNetworkAgent.adjustScore(40);
2470 mWiFiNetworkAgent.connect(false);
2472 long onLostDispatchingDuration = durationOf(() -> {
2473 awaitLatch(losingLatch, 10 * SWITCH_TIME_LIMIT_MS);
2475 Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms",
2476 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration));
2477 assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms",
2478 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS),
2479 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS);
2481 assertTimeLimit("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> {
2482 for (NetworkCallback cb : callbacks) {
2483 mCm.unregisterNetworkCallback(cb);
2488 private long durationOf(Runnable fn) {
2489 long startTime = SystemClock.elapsedRealtime();
2491 return SystemClock.elapsedRealtime() - startTime;
2494 private void assertTimeLimit(String descr, long timeLimit, Runnable fn) {
2495 long timeTaken = durationOf(fn);
2496 String msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit);
2498 assertTrue(msg, timeTaken <= timeLimit);
2501 private boolean awaitLatch(CountDownLatch l, long timeoutMs) {
2503 return l.await(timeoutMs, TimeUnit.MILLISECONDS);
2504 } catch (InterruptedException e) {}
2509 public void testMobileDataAlwaysOn() throws Exception {
2510 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2511 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2512 .addTransportType(TRANSPORT_CELLULAR).build();
2513 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
2515 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory");
2516 handlerThread.start();
2517 NetworkCapabilities filter = new NetworkCapabilities()
2518 .addTransportType(TRANSPORT_CELLULAR)
2519 .addCapability(NET_CAPABILITY_INTERNET);
2520 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
2521 mServiceContext, "testFactory", filter);
2522 testFactory.setScoreFilter(40);
2524 // Register the factory and expect it to start looking for a network.
2525 testFactory.expectAddRequests(1);
2526 testFactory.register();
2527 testFactory.waitForNetworkRequests(1);
2528 assertTrue(testFactory.getMyStartRequested());
2530 // Bring up wifi. The factory stops looking for a network.
2531 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2532 testFactory.expectAddRequests(2); // Because the default request changes score twice.
2533 mWiFiNetworkAgent.connect(true);
2534 testFactory.waitForNetworkRequests(1);
2535 assertFalse(testFactory.getMyStartRequested());
2537 ContentResolver cr = mServiceContext.getContentResolver();
2539 // Turn on mobile data always on. The factory starts looking again.
2540 testFactory.expectAddRequests(1);
2541 setMobileDataAlwaysOn(true);
2542 testFactory.waitForNetworkRequests(2);
2543 assertTrue(testFactory.getMyStartRequested());
2545 // Bring up cell data and check that the factory stops looking.
2546 assertEquals(1, mCm.getAllNetworks().length);
2547 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2548 testFactory.expectAddRequests(2); // Because the cell request changes score twice.
2549 mCellNetworkAgent.connect(true);
2550 cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2551 testFactory.waitForNetworkRequests(2);
2552 assertFalse(testFactory.getMyStartRequested()); // Because the cell network outscores us.
2554 // Check that cell data stays up.
2556 verifyActiveNetwork(TRANSPORT_WIFI);
2557 assertEquals(2, mCm.getAllNetworks().length);
2559 // Turn off mobile data always on and expect the request to disappear...
2560 testFactory.expectRemoveRequests(1);
2561 setMobileDataAlwaysOn(false);
2562 testFactory.waitForNetworkRequests(1);
2564 // ... and cell data to be torn down.
2565 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2566 assertEquals(1, mCm.getAllNetworks().length);
2568 testFactory.unregister();
2569 mCm.unregisterNetworkCallback(cellNetworkCallback);
2570 handlerThread.quit();
2574 public void testAvoidBadWifiSetting() throws Exception {
2575 final ContentResolver cr = mServiceContext.getContentResolver();
2576 final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
2577 final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
2579 tracker.configRestrictsAvoidBadWifi = false;
2580 String[] values = new String[] {null, "0", "1"};
2581 for (int i = 0; i < values.length; i++) {
2582 Settings.Global.putInt(cr, settingName, 1);
2583 tracker.reevaluate();
2585 String msg = String.format("config=false, setting=%s", values[i]);
2586 assertTrue(mService.avoidBadWifi());
2587 assertFalse(msg, tracker.shouldNotifyWifiUnvalidated());
2590 tracker.configRestrictsAvoidBadWifi = true;
2592 Settings.Global.putInt(cr, settingName, 0);
2593 tracker.reevaluate();
2595 assertFalse(mService.avoidBadWifi());
2596 assertFalse(tracker.shouldNotifyWifiUnvalidated());
2598 Settings.Global.putInt(cr, settingName, 1);
2599 tracker.reevaluate();
2601 assertTrue(mService.avoidBadWifi());
2602 assertFalse(tracker.shouldNotifyWifiUnvalidated());
2604 Settings.Global.putString(cr, settingName, null);
2605 tracker.reevaluate();
2607 assertFalse(mService.avoidBadWifi());
2608 assertTrue(tracker.shouldNotifyWifiUnvalidated());
2612 public void testAvoidBadWifi() throws Exception {
2613 final ContentResolver cr = mServiceContext.getContentResolver();
2614 final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
2616 // Pretend we're on a carrier that restricts switching away from bad wifi.
2617 tracker.configRestrictsAvoidBadWifi = true;
2619 // File a request for cell to ensure it doesn't go down.
2620 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2621 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2622 .addTransportType(TRANSPORT_CELLULAR).build();
2623 mCm.requestNetwork(cellRequest, cellNetworkCallback);
2625 TestNetworkCallback defaultCallback = new TestNetworkCallback();
2626 mCm.registerDefaultNetworkCallback(defaultCallback);
2628 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder()
2629 .addTransportType(TRANSPORT_WIFI)
2630 .addCapability(NET_CAPABILITY_VALIDATED)
2632 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback();
2633 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback);
2635 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 0);
2636 tracker.reevaluate();
2638 // Bring up validated cell.
2639 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2640 mCellNetworkAgent.connect(true);
2641 cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2642 defaultCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
2643 Network cellNetwork = mCellNetworkAgent.getNetwork();
2645 // Bring up validated wifi.
2646 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2647 mWiFiNetworkAgent.connect(true);
2648 defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
2649 validatedWifiCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2650 validatedWifiCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
2651 Network wifiNetwork = mWiFiNetworkAgent.getNetwork();
2653 // Fail validation on wifi.
2654 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
2655 mCm.reportNetworkConnectivity(wifiNetwork, false);
2656 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
2657 validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2659 // Because avoid bad wifi is off, we don't switch to cellular.
2660 defaultCallback.assertNoCallback();
2661 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2662 NET_CAPABILITY_VALIDATED));
2663 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2664 NET_CAPABILITY_VALIDATED));
2665 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2667 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect
2668 // that we switch back to cell.
2669 tracker.configRestrictsAvoidBadWifi = false;
2670 tracker.reevaluate();
2671 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
2672 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2674 // Switch back to a restrictive carrier.
2675 tracker.configRestrictsAvoidBadWifi = true;
2676 tracker.reevaluate();
2677 defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2678 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2680 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell.
2681 mCm.setAvoidUnvalidated(wifiNetwork);
2682 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
2683 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2684 NET_CAPABILITY_VALIDATED));
2685 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2686 NET_CAPABILITY_VALIDATED));
2687 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2689 // Disconnect and reconnect wifi to clear the one-time switch above.
2690 mWiFiNetworkAgent.disconnect();
2691 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2692 mWiFiNetworkAgent.connect(true);
2693 defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
2694 validatedWifiCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2695 validatedWifiCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
2696 wifiNetwork = mWiFiNetworkAgent.getNetwork();
2698 // Fail validation on wifi and expect the dialog to appear.
2699 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
2700 mCm.reportNetworkConnectivity(wifiNetwork, false);
2701 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
2702 validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2704 // Simulate the user selecting "switch" and checking the don't ask again checkbox.
2705 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
2706 tracker.reevaluate();
2708 // We now switch to cell.
2709 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
2710 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2711 NET_CAPABILITY_VALIDATED));
2712 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2713 NET_CAPABILITY_VALIDATED));
2714 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2716 // Simulate the user turning the cellular fallback setting off and then on.
2717 // We switch to wifi and then to cell.
2718 Settings.Global.putString(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
2719 tracker.reevaluate();
2720 defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2721 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2722 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
2723 tracker.reevaluate();
2724 defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
2725 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2727 // If cell goes down, we switch to wifi.
2728 mCellNetworkAgent.disconnect();
2729 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2730 defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
2731 validatedWifiCallback.assertNoCallback();
2733 mCm.unregisterNetworkCallback(cellNetworkCallback);
2734 mCm.unregisterNetworkCallback(validatedWifiCallback);
2735 mCm.unregisterNetworkCallback(defaultCallback);
2739 public void testMeteredMultipathPreferenceSetting() throws Exception {
2740 final ContentResolver cr = mServiceContext.getContentResolver();
2741 final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
2742 final String settingName = Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
2744 for (int config : Arrays.asList(0, 3, 2)) {
2745 for (String setting: Arrays.asList(null, "0", "2", "1")) {
2746 tracker.configMeteredMultipathPreference = config;
2747 Settings.Global.putString(cr, settingName, setting);
2748 tracker.reevaluate();
2751 final int expected = (setting != null) ? Integer.parseInt(setting) : config;
2752 String msg = String.format("config=%d, setting=%s", config, setting);
2753 assertEquals(msg, expected, mCm.getMultipathPreference(null));
2759 * Validate that a satisfied network request does not trigger onUnavailable() once the
2760 * time-out period expires.
2763 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
2764 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2765 NetworkCapabilities.TRANSPORT_WIFI).build();
2766 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2767 final int timeoutMs = 150;
2768 mCm.requestNetwork(nr, networkCallback, timeoutMs);
2770 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2771 mWiFiNetworkAgent.connect(false);
2772 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, timeoutMs);
2774 // pass timeout and validate that UNAVAILABLE is not called
2775 networkCallback.assertNoCallback();
2779 * Validate that a satisfied network request followed by a disconnected (lost) network does
2780 * not trigger onUnavailable() once the time-out period expires.
2783 public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() {
2784 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2785 NetworkCapabilities.TRANSPORT_WIFI).build();
2786 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2787 final int requestTimeoutMs = 100;
2788 mCm.requestNetwork(nr, networkCallback, requestTimeoutMs);
2790 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2791 mWiFiNetworkAgent.connect(false);
2792 final int assertTimeoutMs = 150;
2793 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, assertTimeoutMs);
2795 mWiFiNetworkAgent.disconnect();
2796 networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2798 // pass timeout and validate that UNAVAILABLE is not called
2800 networkCallback.assertNoCallback();
2804 * Validate that when a time-out is specified for a network request the onUnavailable()
2805 * callback is called when time-out expires. Then validate that if network request is
2806 * (somehow) satisfied - the callback isn't called later.
2809 public void testTimedoutNetworkRequest() {
2810 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2811 NetworkCapabilities.TRANSPORT_WIFI).build();
2812 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2813 final int timeoutMs = 10;
2814 mCm.requestNetwork(nr, networkCallback, timeoutMs);
2816 // pass timeout and validate that UNAVAILABLE is called
2817 networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
2819 // create a network satisfying request - validate that request not triggered
2820 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2821 mWiFiNetworkAgent.connect(false);
2822 networkCallback.assertNoCallback();
2826 * Validate that when a network request is unregistered (cancelled) the time-out for that
2827 * request doesn't trigger the onUnavailable() callback.
2830 public void testTimedoutAfterUnregisteredNetworkRequest() {
2831 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2832 NetworkCapabilities.TRANSPORT_WIFI).build();
2833 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2834 final int timeoutMs = 10;
2835 mCm.requestNetwork(nr, networkCallback, timeoutMs);
2838 mCm.unregisterNetworkCallback(networkCallback);
2840 // pass timeout and validate that no callbacks
2841 // Note: doesn't validate that nothing called from CS since even if called the CM already
2842 // unregisters the callback and won't pass it through!
2844 networkCallback.assertNoCallback();
2846 // create a network satisfying request - validate that request not triggered
2847 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2848 mWiFiNetworkAgent.connect(false);
2849 networkCallback.assertNoCallback();
2852 private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
2854 public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
2856 private class CallbackValue {
2857 public CallbackType callbackType;
2860 public CallbackValue(CallbackType type) {
2861 this.callbackType = type;
2862 this.error = PacketKeepalive.SUCCESS;
2863 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR);
2866 public CallbackValue(CallbackType type, int error) {
2867 this.callbackType = type;
2869 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR);
2873 public boolean equals(Object o) {
2874 return o instanceof CallbackValue &&
2875 this.callbackType == ((CallbackValue) o).callbackType &&
2876 this.error == ((CallbackValue) o).error;
2880 public String toString() {
2881 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error);
2885 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>();
2888 public void onStarted() {
2889 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED));
2893 public void onStopped() {
2894 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED));
2898 public void onError(int error) {
2899 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
2902 private void expectCallback(CallbackValue callbackValue) {
2906 mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
2907 } catch (InterruptedException e) {
2908 fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
2912 public void expectStarted() {
2913 expectCallback(new CallbackValue(CallbackType.ON_STARTED));
2916 public void expectStopped() {
2917 expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
2920 public void expectError(int error) {
2921 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
2925 private Network connectKeepaliveNetwork(LinkProperties lp) {
2926 // Ensure the network is disconnected before we do anything.
2927 if (mWiFiNetworkAgent != null) {
2928 assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
2931 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2932 ConditionVariable cv = waitForConnectivityBroadcasts(1);
2933 mWiFiNetworkAgent.connect(true);
2935 verifyActiveNetwork(TRANSPORT_WIFI);
2936 mWiFiNetworkAgent.sendLinkProperties(lp);
2938 return mWiFiNetworkAgent.getNetwork();
2942 public void testPacketKeepalives() throws Exception {
2943 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
2944 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
2945 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
2946 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
2947 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888");
2949 LinkProperties lp = new LinkProperties();
2950 lp.setInterfaceName("wlan12");
2951 lp.addLinkAddress(new LinkAddress(myIPv6, 64));
2952 lp.addLinkAddress(new LinkAddress(myIPv4, 25));
2953 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234")));
2954 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
2956 Network notMyNet = new Network(61234);
2957 Network myNet = connectKeepaliveNetwork(lp);
2959 TestKeepaliveCallback callback = new TestKeepaliveCallback();
2962 // Attempt to start keepalives with invalid parameters and check for errors.
2963 ka = mCm.startNattKeepalive(notMyNet, 25, callback, myIPv4, 1234, dstIPv4);
2964 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
2966 ka = mCm.startNattKeepalive(myNet, 19, callback, notMyIPv4, 1234, dstIPv4);
2967 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL);
2969 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 1234, dstIPv6);
2970 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2972 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv4);
2973 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2975 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv6);
2976 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); // NAT-T is IPv4-only.
2978 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
2979 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
2981 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
2982 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
2984 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2985 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
2987 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2988 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
2990 // Check that a started keepalive can be stopped.
2991 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
2992 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2993 callback.expectStarted();
2994 mWiFiNetworkAgent.setStopKeepaliveError(PacketKeepalive.SUCCESS);
2996 callback.expectStopped();
2998 // Check that deleting the IP address stops the keepalive.
2999 LinkProperties bogusLp = new LinkProperties(lp);
3000 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
3001 callback.expectStarted();
3002 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25));
3003 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25));
3004 mWiFiNetworkAgent.sendLinkProperties(bogusLp);
3005 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
3006 mWiFiNetworkAgent.sendLinkProperties(lp);
3008 // Check that a started keepalive is stopped correctly when the network disconnects.
3009 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
3010 callback.expectStarted();
3011 mWiFiNetworkAgent.disconnect();
3012 waitFor(mWiFiNetworkAgent.getDisconnectedCV());
3013 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
3015 // ... and that stopping it after that has no adverse effects.
3017 final Network myNetAlias = myNet;
3018 assertNull(mCm.getNetworkCapabilities(myNetAlias));
3022 myNet = connectKeepaliveNetwork(lp);
3023 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
3025 // Check things work as expected when the keepalive is stopped and the network disconnects.
3026 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
3027 callback.expectStarted();
3029 mWiFiNetworkAgent.disconnect();
3030 waitFor(mWiFiNetworkAgent.getDisconnectedCV());
3032 callback.expectStopped();
3035 myNet = connectKeepaliveNetwork(lp);
3036 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
3038 // Check that keepalive slots start from 1 and increment. The first one gets slot 1.
3039 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
3040 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
3041 callback.expectStarted();
3043 // The second one gets slot 2.
3044 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
3045 TestKeepaliveCallback callback2 = new TestKeepaliveCallback();
3046 PacketKeepalive ka2 = mCm.startNattKeepalive(myNet, 25, callback2, myIPv4, 6789, dstIPv4);
3047 callback2.expectStarted();
3049 // Now stop the first one and create a third. This also gets slot 1.
3051 callback.expectStopped();
3053 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
3054 TestKeepaliveCallback callback3 = new TestKeepaliveCallback();
3055 PacketKeepalive ka3 = mCm.startNattKeepalive(myNet, 25, callback3, myIPv4, 9876, dstIPv4);
3056 callback3.expectStarted();
3059 callback2.expectStopped();
3062 callback3.expectStopped();
3066 public void testGetCaptivePortalServerUrl() throws Exception {
3067 String url = mCm.getCaptivePortalServerUrl();
3068 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url);
3071 private static class TestNetworkPinner extends NetworkPinner {
3072 public static boolean awaitPin(int timeoutMs) {
3073 synchronized(sLock) {
3074 if (sNetwork == null) {
3076 sLock.wait(timeoutMs);
3077 } catch (InterruptedException e) {}
3079 return sNetwork != null;
3083 public static boolean awaitUnpin(int timeoutMs) {
3084 synchronized(sLock) {
3085 if (sNetwork != null) {
3087 sLock.wait(timeoutMs);
3088 } catch (InterruptedException e) {}
3090 return sNetwork == null;
3095 private void assertPinnedToWifiWithCellDefault() {
3096 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
3097 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
3100 private void assertPinnedToWifiWithWifiDefault() {
3101 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
3102 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
3105 private void assertNotPinnedToWifi() {
3106 assertNull(mCm.getBoundNetworkForProcess());
3107 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
3111 public void testNetworkPinner() {
3112 NetworkRequest wifiRequest = new NetworkRequest.Builder()
3113 .addTransportType(TRANSPORT_WIFI)
3115 assertNull(mCm.getBoundNetworkForProcess());
3117 TestNetworkPinner.pin(mServiceContext, wifiRequest);
3118 assertNull(mCm.getBoundNetworkForProcess());
3120 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
3121 mCellNetworkAgent.connect(true);
3122 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
3123 mWiFiNetworkAgent.connect(false);
3125 // When wi-fi connects, expect to be pinned.
3126 assertTrue(TestNetworkPinner.awaitPin(100));
3127 assertPinnedToWifiWithCellDefault();
3129 // Disconnect and expect the pin to drop.
3130 mWiFiNetworkAgent.disconnect();
3131 assertTrue(TestNetworkPinner.awaitUnpin(100));
3132 assertNotPinnedToWifi();
3134 // Reconnecting does not cause the pin to come back.
3135 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
3136 mWiFiNetworkAgent.connect(false);
3137 assertFalse(TestNetworkPinner.awaitPin(100));
3138 assertNotPinnedToWifi();
3140 // Pinning while connected causes the pin to take effect immediately.
3141 TestNetworkPinner.pin(mServiceContext, wifiRequest);
3142 assertTrue(TestNetworkPinner.awaitPin(100));
3143 assertPinnedToWifiWithCellDefault();
3145 // Explicitly unpin and expect to use the default network again.
3146 TestNetworkPinner.unpin();
3147 assertNotPinnedToWifi();
3149 // Disconnect cell and wifi.
3150 ConditionVariable cv = waitForConnectivityBroadcasts(3); // cell down, wifi up, wifi down.
3151 mCellNetworkAgent.disconnect();
3152 mWiFiNetworkAgent.disconnect();
3155 // Pinning takes effect even if the pinned network is the default when the pin is set...
3156 TestNetworkPinner.pin(mServiceContext, wifiRequest);
3157 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
3158 mWiFiNetworkAgent.connect(false);
3159 assertTrue(TestNetworkPinner.awaitPin(100));
3160 assertPinnedToWifiWithWifiDefault();
3162 // ... and is maintained even when that network is no longer the default.
3163 cv = waitForConnectivityBroadcasts(1);
3164 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
3165 mCellNetworkAgent.connect(true);
3167 assertPinnedToWifiWithCellDefault();
3171 public void testNetworkRequestMaximum() {
3172 final int MAX_REQUESTS = 100;
3173 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
3174 NetworkRequest networkRequest = new NetworkRequest.Builder().build();
3175 ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>();
3177 for (int i = 0; i < MAX_REQUESTS; i++) {
3178 NetworkCallback networkCallback = new NetworkCallback();
3179 mCm.requestNetwork(networkRequest, networkCallback);
3180 networkCallbacks.add(networkCallback);
3182 fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
3183 } catch (TooManyRequestsException expected) {}
3184 for (NetworkCallback networkCallback : networkCallbacks) {
3185 mCm.unregisterNetworkCallback(networkCallback);
3187 networkCallbacks.clear();
3190 for (int i = 0; i < MAX_REQUESTS; i++) {
3191 NetworkCallback networkCallback = new NetworkCallback();
3192 mCm.registerNetworkCallback(networkRequest, networkCallback);
3193 networkCallbacks.add(networkCallback);
3195 fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
3196 } catch (TooManyRequestsException expected) {}
3197 for (NetworkCallback networkCallback : networkCallbacks) {
3198 mCm.unregisterNetworkCallback(networkCallback);
3200 networkCallbacks.clear();
3202 ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
3204 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
3205 PendingIntent pendingIntent =
3206 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
3207 mCm.requestNetwork(networkRequest, pendingIntent);
3208 pendingIntents.add(pendingIntent);
3210 fail("Registering " + MAX_REQUESTS +
3211 " PendingIntent NetworkRequests did not throw exception");
3212 } catch (TooManyRequestsException expected) {}
3213 for (PendingIntent pendingIntent : pendingIntents) {
3214 mCm.unregisterNetworkCallback(pendingIntent);
3216 pendingIntents.clear();
3219 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
3220 PendingIntent pendingIntent =
3221 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
3222 mCm.registerNetworkCallback(networkRequest, pendingIntent);
3223 pendingIntents.add(pendingIntent);
3225 fail("Registering " + MAX_REQUESTS +
3226 " PendingIntent NetworkCallbacks did not throw exception");
3227 } catch (TooManyRequestsException expected) {}
3228 for (PendingIntent pendingIntent : pendingIntents) {
3229 mCm.unregisterNetworkCallback(pendingIntent);
3231 pendingIntents.clear();
3234 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed.
3235 for (int i = 0; i < MAX_REQUESTS; i++) {
3236 NetworkCallback networkCallback = new NetworkCallback();
3237 mCm.requestNetwork(networkRequest, networkCallback);
3238 mCm.unregisterNetworkCallback(networkCallback);
3241 for (int i = 0; i < MAX_REQUESTS; i++) {
3242 NetworkCallback networkCallback = new NetworkCallback();
3243 mCm.registerNetworkCallback(networkRequest, networkCallback);
3244 mCm.unregisterNetworkCallback(networkCallback);
3247 for (int i = 0; i < MAX_REQUESTS; i++) {
3248 PendingIntent pendingIntent =
3249 PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0);
3250 mCm.requestNetwork(networkRequest, pendingIntent);
3251 mCm.unregisterNetworkCallback(pendingIntent);
3254 for (int i = 0; i < MAX_REQUESTS; i++) {
3255 PendingIntent pendingIntent =
3256 PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);
3257 mCm.registerNetworkCallback(networkRequest, pendingIntent);
3258 mCm.unregisterNetworkCallback(pendingIntent);
3262 /* test utilities */
3263 // TODO: eliminate all usages of sleepFor and replace by proper timeouts/waitForIdle.
3264 static private void sleepFor(int ms) {
3267 } catch (InterruptedException e) {