blob: 9bf3c2cf5efd41cd637bd654a8eaf68f94a7cc59 [file] [log] [blame]
Jeff Sharkeyfb878b62012-07-26 18:32:30 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
Erik Klinef851d6d2015-04-20 16:03:48 +090019import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +090020import static android.net.ConnectivityManager.TYPE_ETHERNET;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070021import static android.net.ConnectivityManager.TYPE_MOBILE;
22import static android.net.ConnectivityManager.TYPE_WIFI;
23import static android.net.ConnectivityManager.getNetworkTypeName;
Lorenzo Colitti83fa2582015-08-07 12:49:01 +090024import static android.net.NetworkCapabilities.*;
25
Jeff Sharkey3671b1e2013-01-31 17:22:26 -080026import static org.mockito.Mockito.mock;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070027
Lorenzo Colitti73b209382016-09-15 22:18:09 +090028import android.app.NotificationManager;
Paul Jensenbb2e0e92015-06-16 15:11:58 -040029import android.app.PendingIntent;
Paul Jensend7b6ca92015-05-13 14:05:12 -040030import android.content.BroadcastReceiver;
Lorenzo Colitti6d553f62016-06-05 02:20:29 +090031import android.content.ContentResolver;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070032import android.content.Context;
Paul Jensend7b6ca92015-05-13 14:05:12 -040033import android.content.ContextWrapper;
34import android.content.Intent;
35import android.content.IntentFilter;
36import android.net.ConnectivityManager;
37import android.net.ConnectivityManager.NetworkCallback;
Lorenzo Colitti7914ce52015-09-08 13:21:48 +090038import android.net.ConnectivityManager.PacketKeepalive;
39import android.net.ConnectivityManager.PacketKeepaliveCallback;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070040import android.net.INetworkPolicyManager;
41import android.net.INetworkStatsService;
Lorenzo Colitti7914ce52015-09-08 13:21:48 +090042import android.net.IpPrefix;
43import android.net.LinkAddress;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070044import android.net.LinkProperties;
Paul Jensend7b6ca92015-05-13 14:05:12 -040045import android.net.Network;
46import android.net.NetworkAgent;
47import android.net.NetworkCapabilities;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070048import android.net.NetworkConfig;
Robert Greenwalt348e98d2015-06-05 17:55:36 -070049import android.net.NetworkFactory;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070050import android.net.NetworkInfo;
51import android.net.NetworkInfo.DetailedState;
Paul Jensend7b6ca92015-05-13 14:05:12 -040052import android.net.NetworkMisc;
53import android.net.NetworkRequest;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070054import android.net.RouteInfo;
Hugo Benichif9fdf872016-07-28 17:53:06 +090055import android.net.metrics.IpConnectivityLog;
Erik Kline065ab6e2016-10-02 18:02:14 +090056import android.net.util.AvoidBadWifiTracker;
Paul Jensend7b6ca92015-05-13 14:05:12 -040057import android.os.ConditionVariable;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070058import android.os.Handler;
Robert Greenwalt348e98d2015-06-05 17:55:36 -070059import android.os.HandlerThread;
Etan Cohenddb9ef02015-11-18 10:56:15 -080060import android.os.IBinder;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070061import android.os.INetworkManagementService;
Lorenzo Colittie58961a2015-08-07 20:17:27 +090062import android.os.Looper;
Lorenzo Colitti7914ce52015-09-08 13:21:48 +090063import android.os.Message;
Lorenzo Colittie58961a2015-08-07 20:17:27 +090064import android.os.MessageQueue;
Etan Cohenddb9ef02015-11-18 10:56:15 -080065import android.os.Messenger;
Lorenzo Colittie58961a2015-08-07 20:17:27 +090066import android.os.MessageQueue.IdleHandler;
Robin Leed2baf792016-03-24 12:07:00 +000067import android.os.Process;
Lorenzo Colittibfecba22016-02-21 01:09:26 +090068import android.os.SystemClock;
Lorenzo Colitti6d553f62016-06-05 02:20:29 +090069import android.provider.Settings;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070070import android.test.AndroidTestCase;
Hugo Benichia5605c32016-10-17 15:54:51 +090071import android.test.FlakyTest;
Lorenzo Colitti6d553f62016-06-05 02:20:29 +090072import android.test.mock.MockContentResolver;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070073import android.test.suitebuilder.annotation.LargeTest;
Udam Sainib7c24872016-01-04 12:16:14 -080074import android.test.suitebuilder.annotation.SmallTest;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070075import android.util.Log;
76import android.util.LogPrinter;
77
Lorenzo Colittibfecba22016-02-21 01:09:26 +090078import com.android.internal.util.WakeupMessage;
Lorenzo Colittic8690892016-10-28 12:37:38 +090079import com.android.internal.util.test.FakeSettingsProvider;
Paul Jensencf4c2c62015-07-01 14:16:32 -040080import com.android.server.connectivity.NetworkAgentInfo;
Paul Jensend7b6ca92015-05-13 14:05:12 -040081import com.android.server.connectivity.NetworkMonitor;
Paul Jensen232437312016-04-06 09:51:26 -040082import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
Lorenzo Colitti531a3442016-03-01 12:55:58 +090083import com.android.server.net.NetworkPinner;
Paul Jensend7b6ca92015-05-13 14:05:12 -040084
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070085import java.net.InetAddress;
Paul Jensen4e1d3fd2016-04-08 13:56:52 -040086import java.util.ArrayList;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +090087import java.util.Arrays;
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +090088import java.util.Objects;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +090089import java.util.concurrent.CountDownLatch;
Lorenzo Colitti7914ce52015-09-08 13:21:48 +090090import java.util.concurrent.LinkedBlockingQueue;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +090091import java.util.concurrent.TimeUnit;
Robert Greenwalt348e98d2015-06-05 17:55:36 -070092import java.util.concurrent.atomic.AtomicBoolean;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070093
94/**
95 * Tests for {@link ConnectivityService}.
Paul Jensend7b6ca92015-05-13 14:05:12 -040096 *
97 * Build, install and run with:
98 * runtest frameworks-services -c com.android.server.ConnectivityServiceTest
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070099 */
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700100public class ConnectivityServiceTest extends AndroidTestCase {
101 private static final String TAG = "ConnectivityServiceTest";
102
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900103 private static final int TIMEOUT_MS = 500;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900104 private static final int TEST_LINGER_DELAY_MS = 120;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900105
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700106 private BroadcastInterceptingContext mServiceContext;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400107 private WrappedConnectivityService mService;
Lorenzo Colitti531a3442016-03-01 12:55:58 +0900108 private WrappedConnectivityManager mCm;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400109 private MockNetworkAgent mWiFiNetworkAgent;
110 private MockNetworkAgent mCellNetworkAgent;
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900111 private MockNetworkAgent mEthernetNetworkAgent;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700112
Lorenzo Colitti531a3442016-03-01 12:55:58 +0900113 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
114 // do not go through ConnectivityService but talk to netd directly, so they don't automatically
115 // reflect the state of our test ConnectivityService.
116 private class WrappedConnectivityManager extends ConnectivityManager {
117 private Network mFakeBoundNetwork;
118
119 public synchronized boolean bindProcessToNetwork(Network network) {
120 mFakeBoundNetwork = network;
121 return true;
122 }
123
124 public synchronized Network getBoundNetworkForProcess() {
125 return mFakeBoundNetwork;
126 }
127
128 public WrappedConnectivityManager(Context context, ConnectivityService service) {
129 super(context, service);
130 }
131 }
132
Paul Jensend7b6ca92015-05-13 14:05:12 -0400133 private class MockContext extends BroadcastInterceptingContext {
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900134 private final MockContentResolver mContentResolver;
135
Paul Jensend7b6ca92015-05-13 14:05:12 -0400136 MockContext(Context base) {
137 super(base);
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900138 mContentResolver = new MockContentResolver();
139 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Paul Jensend7b6ca92015-05-13 14:05:12 -0400140 }
141
142 @Override
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900143 public Object getSystemService(String name) {
Lorenzo Colitti73b209382016-09-15 22:18:09 +0900144 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
145 if (Context.NOTIFICATION_SERVICE.equals(name)) return mock(NotificationManager.class);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400146 return super.getSystemService(name);
147 }
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900148
149 @Override
150 public ContentResolver getContentResolver() {
151 return mContentResolver;
152 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400153 }
154
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900155 /**
156 * A subclass of HandlerThread that allows callers to wait for it to become idle. waitForIdle
157 * will return immediately if the handler is already idle.
158 */
159 private class IdleableHandlerThread extends HandlerThread {
160 private IdleHandler mIdleHandler;
161
162 public IdleableHandlerThread(String name) {
163 super(name);
164 }
165
166 public void waitForIdle(int timeoutMs) {
167 final ConditionVariable cv = new ConditionVariable();
168 final MessageQueue queue = getLooper().getQueue();
169
170 synchronized (queue) {
171 if (queue.isIdle()) {
172 return;
173 }
174
175 assertNull("BUG: only one idle handler allowed", mIdleHandler);
176 mIdleHandler = new IdleHandler() {
177 public boolean queueIdle() {
Lorenzo Colitti5eaaf742016-03-02 21:47:42 +0900178 synchronized (queue) {
179 cv.open();
180 mIdleHandler = null;
181 return false; // Remove the handler.
182 }
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900183 }
184 };
185 queue.addIdleHandler(mIdleHandler);
186 }
187
188 if (!cv.block(timeoutMs)) {
189 fail("HandlerThread " + getName() +
190 " did not become idle after " + timeoutMs + " ms");
191 queue.removeIdleHandler(mIdleHandler);
192 }
193 }
194 }
195
196 // Tests that IdleableHandlerThread works as expected.
197 public void testIdleableHandlerThread() {
198 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
199
200 // Tests that waitForIdle returns immediately if the service is already idle.
201 for (int i = 0; i < attempts; i++) {
202 mService.waitForIdle();
203 }
204
205 // Bring up a network that we can use to send messages to ConnectivityService.
206 ConditionVariable cv = waitForConnectivityBroadcasts(1);
207 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
208 mWiFiNetworkAgent.connect(false);
209 waitFor(cv);
210 Network n = mWiFiNetworkAgent.getNetwork();
211 assertNotNull(n);
212
213 // Tests that calling waitForIdle waits for messages to be processed.
214 for (int i = 0; i < attempts; i++) {
215 mWiFiNetworkAgent.setSignalStrength(i);
216 mService.waitForIdle();
217 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
218 }
Hugo Benichia5605c32016-10-17 15:54:51 +0900219 }
220
221 @FlakyTest(tolerance = 3)
222 public void testNotWaitingForIdleCausesRaceConditions() {
223 // Bring up a network that we can use to send messages to ConnectivityService.
224 ConditionVariable cv = waitForConnectivityBroadcasts(1);
225 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
226 mWiFiNetworkAgent.connect(false);
227 waitFor(cv);
228 Network n = mWiFiNetworkAgent.getNetwork();
229 assertNotNull(n);
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900230
231 // Ensure that not calling waitForIdle causes a race condition.
Hugo Benichia5605c32016-10-17 15:54:51 +0900232 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900233 for (int i = 0; i < attempts; i++) {
234 mWiFiNetworkAgent.setSignalStrength(i);
235 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
236 // We hit a race condition, as expected. Pass the test.
237 return;
238 }
239 }
240
241 // No race? There is a bug in this test.
242 fail("expected race condition at least once in " + attempts + " attempts");
243 }
244
Paul Jensend7b6ca92015-05-13 14:05:12 -0400245 private class MockNetworkAgent {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400246 private final WrappedNetworkMonitor mWrappedNetworkMonitor;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400247 private final NetworkInfo mNetworkInfo;
248 private final NetworkCapabilities mNetworkCapabilities;
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900249 private final IdleableHandlerThread mHandlerThread;
Paul Jensene0988542015-06-25 15:30:08 -0400250 private final ConditionVariable mDisconnected = new ConditionVariable();
Paul Jensen232437312016-04-06 09:51:26 -0400251 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
Calvin Ond2bd69a2016-10-11 15:10:46 -0700252 private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
Paul Jensen3d911462015-06-12 06:40:24 -0400253 private int mScore;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400254 private NetworkAgent mNetworkAgent;
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900255 private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
256 private int mStopKeepaliveError = PacketKeepalive.NO_KEEPALIVE;
257 private Integer mExpectedKeepaliveSlot = null;
Paul Jensen232437312016-04-06 09:51:26 -0400258 // Contains the redirectUrl from networkStatus(). Before reading, wait for
259 // mNetworkStatusReceived.
260 private String mRedirectUrl;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400261
262 MockNetworkAgent(int transport) {
263 final int type = transportToLegacyType(transport);
264 final String typeName = ConnectivityManager.getNetworkTypeName(type);
265 mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
266 mNetworkCapabilities = new NetworkCapabilities();
267 mNetworkCapabilities.addTransportType(transport);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400268 switch (transport) {
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900269 case TRANSPORT_ETHERNET:
270 mScore = 70;
271 break;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400272 case TRANSPORT_WIFI:
Paul Jensen3d911462015-06-12 06:40:24 -0400273 mScore = 60;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400274 break;
275 case TRANSPORT_CELLULAR:
Paul Jensen3d911462015-06-12 06:40:24 -0400276 mScore = 50;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400277 break;
278 default:
279 throw new UnsupportedOperationException("unimplemented network type");
280 }
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900281 mHandlerThread = new IdleableHandlerThread("Mock-" + typeName);
282 mHandlerThread.start();
283 mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
284 "Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
285 new LinkProperties(), mScore, new NetworkMisc()) {
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900286 @Override
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900287 public void unwanted() { mDisconnected.open(); }
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900288
289 @Override
290 public void startPacketKeepalive(Message msg) {
291 int slot = msg.arg1;
292 if (mExpectedKeepaliveSlot != null) {
293 assertEquals((int) mExpectedKeepaliveSlot, slot);
294 }
295 onPacketKeepaliveEvent(slot, mStartKeepaliveError);
296 }
297
298 @Override
299 public void stopPacketKeepalive(Message msg) {
300 onPacketKeepaliveEvent(msg.arg1, mStopKeepaliveError);
301 }
Paul Jensen232437312016-04-06 09:51:26 -0400302
303 @Override
304 public void networkStatus(int status, String redirectUrl) {
305 mRedirectUrl = redirectUrl;
306 mNetworkStatusReceived.open();
307 }
Calvin Ond2bd69a2016-10-11 15:10:46 -0700308
309 @Override
310 protected void preventAutomaticReconnect() {
311 mPreventReconnectReceived.open();
312 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400313 };
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900314 // Waits for the NetworkAgent to be registered, which includes the creation of the
315 // NetworkMonitor.
316 mService.waitForIdle();
Paul Jensencf4c2c62015-07-01 14:16:32 -0400317 mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor();
Paul Jensen3d911462015-06-12 06:40:24 -0400318 }
319
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900320 public void waitForIdle(int timeoutMs) {
321 mHandlerThread.waitForIdle(timeoutMs);
322 }
323
324 public void waitForIdle() {
325 waitForIdle(TIMEOUT_MS);
326 }
327
Paul Jensen3d911462015-06-12 06:40:24 -0400328 public void adjustScore(int change) {
329 mScore += change;
330 mNetworkAgent.sendNetworkScore(mScore);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400331 }
332
Paul Jensen85cf78e2015-06-25 13:25:07 -0400333 public void addCapability(int capability) {
334 mNetworkCapabilities.addCapability(capability);
335 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
336 }
337
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900338 public void removeCapability(int capability) {
339 mNetworkCapabilities.removeCapability(capability);
340 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
341 }
342
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900343 public void setSignalStrength(int signalStrength) {
344 mNetworkCapabilities.setSignalStrength(signalStrength);
345 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
346 }
347
Paul Jensene0988542015-06-25 15:30:08 -0400348 public void connectWithoutInternet() {
349 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
350 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
351 }
352
Paul Jensend7b6ca92015-05-13 14:05:12 -0400353 /**
Paul Jensene0988542015-06-25 15:30:08 -0400354 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET.
Paul Jensend7b6ca92015-05-13 14:05:12 -0400355 * @param validated Indicate if network should pretend to be validated.
356 */
357 public void connect(boolean validated) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900358 assertEquals("MockNetworkAgents can only be connected once",
359 mNetworkInfo.getDetailedState(), DetailedState.IDLE);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400360 assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET));
361
Paul Jensend7b6ca92015-05-13 14:05:12 -0400362 NetworkCallback callback = null;
363 final ConditionVariable validatedCv = new ConditionVariable();
364 if (validated) {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400365 mWrappedNetworkMonitor.gen204ProbeResult = 204;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400366 NetworkRequest request = new NetworkRequest.Builder()
367 .addTransportType(mNetworkCapabilities.getTransportTypes()[0])
368 .build();
369 callback = new NetworkCallback() {
370 public void onCapabilitiesChanged(Network network,
371 NetworkCapabilities networkCapabilities) {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400372 if (network.equals(getNetwork()) &&
373 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
Paul Jensend7b6ca92015-05-13 14:05:12 -0400374 validatedCv.open();
375 }
376 }
377 };
Paul Jensencf4c2c62015-07-01 14:16:32 -0400378 mCm.registerNetworkCallback(request, callback);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400379 }
Paul Jensencf4c2c62015-07-01 14:16:32 -0400380 addCapability(NET_CAPABILITY_INTERNET);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400381
Paul Jensene0988542015-06-25 15:30:08 -0400382 connectWithoutInternet();
Paul Jensend7b6ca92015-05-13 14:05:12 -0400383
384 if (validated) {
385 // Wait for network to validate.
Paul Jensen3d911462015-06-12 06:40:24 -0400386 waitFor(validatedCv);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400387 mWrappedNetworkMonitor.gen204ProbeResult = 500;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400388 }
389
390 if (callback != null) mCm.unregisterNetworkCallback(callback);
391 }
392
Paul Jensen232437312016-04-06 09:51:26 -0400393 public void connectWithCaptivePortal(String redirectUrl) {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400394 mWrappedNetworkMonitor.gen204ProbeResult = 200;
Paul Jensen232437312016-04-06 09:51:26 -0400395 mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400396 connect(false);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400397 }
398
Paul Jensend7b6ca92015-05-13 14:05:12 -0400399 public void disconnect() {
400 mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
401 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
402 }
403
404 public Network getNetwork() {
405 return new Network(mNetworkAgent.netId);
406 }
Paul Jensene0988542015-06-25 15:30:08 -0400407
Calvin Ond2bd69a2016-10-11 15:10:46 -0700408 public ConditionVariable getPreventReconnectReceived() {
409 return mPreventReconnectReceived;
410 }
411
Paul Jensene0988542015-06-25 15:30:08 -0400412 public ConditionVariable getDisconnectedCV() {
413 return mDisconnected;
414 }
Paul Jensencf4c2c62015-07-01 14:16:32 -0400415
416 public WrappedNetworkMonitor getWrappedNetworkMonitor() {
417 return mWrappedNetworkMonitor;
418 }
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900419
420 public void sendLinkProperties(LinkProperties lp) {
421 mNetworkAgent.sendLinkProperties(lp);
422 }
423
424 public void setStartKeepaliveError(int error) {
425 mStartKeepaliveError = error;
426 }
427
428 public void setStopKeepaliveError(int error) {
429 mStopKeepaliveError = error;
430 }
431
432 public void setExpectedKeepaliveSlot(Integer slot) {
433 mExpectedKeepaliveSlot = slot;
434 }
Paul Jensen232437312016-04-06 09:51:26 -0400435
436 public String waitForRedirectUrl() {
437 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
438 return mRedirectUrl;
439 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400440 }
441
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900442 /**
443 * A NetworkFactory that allows tests to wait until any in-flight NetworkRequest add or remove
444 * operations have been processed. Before ConnectivityService can add or remove any requests,
445 * the factory must be told to expect those operations by calling expectAddRequests or
446 * expectRemoveRequests.
447 */
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700448 private static class MockNetworkFactory extends NetworkFactory {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400449 private final ConditionVariable mNetworkStartedCV = new ConditionVariable();
450 private final ConditionVariable mNetworkStoppedCV = new ConditionVariable();
Paul Jensencf4c2c62015-07-01 14:16:32 -0400451 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700452
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900453 // Used to expect that requests be removed or added on a separate thread, without sleeping.
454 // Callers can call either expectAddRequests() or expectRemoveRequests() exactly once, then
455 // cause some other thread to add or remove requests, then call waitForRequests(). We can
456 // either expect requests to be added or removed, but not both, because CountDownLatch can
457 // only count in one direction.
458 private CountDownLatch mExpectations;
459
460 // Whether we are currently expecting requests to be added or removed. Valid only if
461 // mExpectations is non-null.
462 private boolean mExpectingAdditions;
463
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700464 public MockNetworkFactory(Looper looper, Context context, String logTag,
465 NetworkCapabilities filter) {
466 super(looper, context, logTag, filter);
467 }
468
469 public int getMyRequestCount() {
470 return getRequestCount();
471 }
472
473 protected void startNetwork() {
474 mNetworkStarted.set(true);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400475 mNetworkStartedCV.open();
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700476 }
477
478 protected void stopNetwork() {
479 mNetworkStarted.set(false);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400480 mNetworkStoppedCV.open();
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700481 }
482
483 public boolean getMyStartRequested() {
484 return mNetworkStarted.get();
485 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400486
487 public ConditionVariable getNetworkStartedCV() {
488 mNetworkStartedCV.close();
489 return mNetworkStartedCV;
490 }
491
492 public ConditionVariable getNetworkStoppedCV() {
493 mNetworkStoppedCV.close();
494 return mNetworkStoppedCV;
495 }
496
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900497 @Override
498 protected void handleAddRequest(NetworkRequest request, int score) {
499 // If we're expecting anything, we must be expecting additions.
500 if (mExpectations != null && !mExpectingAdditions) {
501 fail("Can't add requests while expecting requests to be removed");
502 }
503
504 // Add the request.
505 super.handleAddRequest(request, score);
506
507 // Reduce the number of request additions we're waiting for.
508 if (mExpectingAdditions) {
509 assertTrue("Added more requests than expected", mExpectations.getCount() > 0);
510 mExpectations.countDown();
511 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400512 }
513
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900514 @Override
515 protected void handleRemoveRequest(NetworkRequest request) {
516 // If we're expecting anything, we must be expecting removals.
517 if (mExpectations != null && mExpectingAdditions) {
518 fail("Can't remove requests while expecting requests to be added");
519 }
520
521 // Remove the request.
522 super.handleRemoveRequest(request);
523
524 // Reduce the number of request removals we're waiting for.
525 if (!mExpectingAdditions) {
526 assertTrue("Removed more requests than expected", mExpectations.getCount() > 0);
527 mExpectations.countDown();
528 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400529 }
530
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900531 private void assertNoExpectations() {
532 if (mExpectations != null) {
533 fail("Can't add expectation, " + mExpectations.getCount() + " already pending");
534 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400535 }
536
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900537 // Expects that count requests will be added.
538 public void expectAddRequests(final int count) {
539 assertNoExpectations();
540 mExpectingAdditions = true;
541 mExpectations = new CountDownLatch(count);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400542 }
543
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900544 // Expects that count requests will be removed.
545 public void expectRemoveRequests(final int count) {
546 assertNoExpectations();
547 mExpectingAdditions = false;
548 mExpectations = new CountDownLatch(count);
549 }
550
551 // Waits for the expected request additions or removals to happen within a timeout.
552 public void waitForRequests() throws InterruptedException {
553 assertNotNull("Nothing to wait for", mExpectations);
554 mExpectations.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
555 final long count = mExpectations.getCount();
556 final String msg = count + " requests still not " +
557 (mExpectingAdditions ? "added" : "removed") +
558 " after " + TIMEOUT_MS + " ms";
559 assertEquals(msg, 0, count);
560 mExpectations = null;
561 }
562
563 public void waitForNetworkRequests(final int count) throws InterruptedException {
564 waitForRequests();
565 assertEquals(count, getMyRequestCount());
Paul Jensen0a2823e2015-06-12 10:31:09 -0400566 }
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700567 }
568
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900569 private class FakeWakeupMessage extends WakeupMessage {
570 private static final int UNREASONABLY_LONG_WAIT = 1000;
571
572 public FakeWakeupMessage(Context context, Handler handler, String cmdName, int cmd) {
573 super(context, handler, cmdName, cmd);
574 }
575
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900576 public FakeWakeupMessage(Context context, Handler handler, String cmdName, int cmd,
577 int arg1, int arg2, Object obj) {
578 super(context, handler, cmdName, cmd, arg1, arg2, obj);
579 }
580
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900581 @Override
582 public void schedule(long when) {
583 long delayMs = when - SystemClock.elapsedRealtime();
584 if (delayMs < 0) delayMs = 0;
585 if (delayMs > UNREASONABLY_LONG_WAIT) {
586 fail("Attempting to send msg more than " + UNREASONABLY_LONG_WAIT +
587 "ms into the future: " + delayMs);
588 }
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900589 Message msg = mHandler.obtainMessage(mCmd, mArg1, mArg2, mObj);
590 mHandler.sendMessageDelayed(msg, delayMs);
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900591 }
592
593 @Override
594 public void cancel() {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900595 mHandler.removeMessages(mCmd, mObj);
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900596 }
597
598 @Override
599 public void onAlarm() {
600 throw new AssertionError("Should never happen. Update this fake.");
601 }
602 }
603
Paul Jensencf4c2c62015-07-01 14:16:32 -0400604 // NetworkMonitor implementation allowing overriding of Internet connectivity probe result.
605 private class WrappedNetworkMonitor extends NetworkMonitor {
606 // HTTP response code fed back to NetworkMonitor for Internet connectivity probe.
607 public int gen204ProbeResult = 500;
Paul Jensen232437312016-04-06 09:51:26 -0400608 public String gen204ProbeRedirectUrl = null;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400609
610 public WrappedNetworkMonitor(Context context, Handler handler,
Hugo Benichif9fdf872016-07-28 17:53:06 +0900611 NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest,
612 IpConnectivityLog log) {
613 super(context, handler, networkAgentInfo, defaultRequest, log);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400614 }
615
616 @Override
Paul Jensen232437312016-04-06 09:51:26 -0400617 protected CaptivePortalProbeResult isCaptivePortal() {
Calvin Ond2bd69a2016-10-11 15:10:46 -0700618 if (!mIsCaptivePortalCheckEnabled) { return new CaptivePortalProbeResult(204); }
Hugo Benichid953bf82016-09-27 09:22:35 +0900619 return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl, null);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400620 }
621 }
622
Erik Kline065ab6e2016-10-02 18:02:14 +0900623 private class WrappedAvoidBadWifiTracker extends AvoidBadWifiTracker {
Lorenzo Colitti165c51c2016-09-19 01:00:19 +0900624 public boolean configRestrictsAvoidBadWifi;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400625
Erik Kline065ab6e2016-10-02 18:02:14 +0900626 public WrappedAvoidBadWifiTracker(Context c, Handler h, Runnable r) {
627 super(c, h, r);
628 }
629
630 @Override
631 public boolean configRestrictsAvoidBadWifi() {
632 return configRestrictsAvoidBadWifi;
633 }
634 }
635
636 private class WrappedConnectivityService extends ConnectivityService {
637 public WrappedAvoidBadWifiTracker wrappedAvoidBadWifiTracker;
638 private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
639
Paul Jensend7b6ca92015-05-13 14:05:12 -0400640 public WrappedConnectivityService(Context context, INetworkManagementService netManager,
Hugo Benichif9fdf872016-07-28 17:53:06 +0900641 INetworkStatsService statsService, INetworkPolicyManager policyManager,
642 IpConnectivityLog log) {
643 super(context, netManager, statsService, policyManager, log);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900644 mLingerDelayMs = TEST_LINGER_DELAY_MS;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400645 }
646
647 @Override
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900648 protected HandlerThread createHandlerThread() {
649 return new IdleableHandlerThread("WrappedConnectivityService");
650 }
651
652 @Override
Paul Jensend7b6ca92015-05-13 14:05:12 -0400653 protected int getDefaultTcpRwnd() {
654 // Prevent wrapped ConnectivityService from trying to write to SystemProperties.
655 return 0;
656 }
Paul Jensen67b0b072015-06-10 11:22:17 -0400657
658 @Override
659 protected int reserveNetId() {
660 while (true) {
661 final int netId = super.reserveNetId();
662
663 // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks
664 // can have odd side-effects, like network validations succeeding.
665 final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks();
666 boolean overlaps = false;
667 for (Network network : networks) {
668 if (netId == network.netId) {
669 overlaps = true;
670 break;
671 }
672 }
673 if (overlaps) continue;
674
675 return netId;
676 }
677 }
Paul Jensencf4c2c62015-07-01 14:16:32 -0400678
679 @Override
680 public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
681 NetworkAgentInfo nai, NetworkRequest defaultRequest) {
Hugo Benichif9fdf872016-07-28 17:53:06 +0900682 final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(
683 context, handler, nai, defaultRequest, mock(IpConnectivityLog.class));
Paul Jensencf4c2c62015-07-01 14:16:32 -0400684 mLastCreatedNetworkMonitor = monitor;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400685 return monitor;
686 }
687
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900688 @Override
Erik Kline065ab6e2016-10-02 18:02:14 +0900689 public AvoidBadWifiTracker createAvoidBadWifiTracker(
690 Context c, Handler h, Runnable r) {
691 final WrappedAvoidBadWifiTracker tracker = new WrappedAvoidBadWifiTracker(c, h, r);
692 return tracker;
693 }
694
695 public WrappedAvoidBadWifiTracker getAvoidBadWifiTracker() {
696 return (WrappedAvoidBadWifiTracker) mAvoidBadWifiTracker;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900697 }
698
Lorenzo Colitti165c51c2016-09-19 01:00:19 +0900699 @Override
Erik Kline065ab6e2016-10-02 18:02:14 +0900700 public WakeupMessage makeWakeupMessage(
701 Context context, Handler handler, String cmdName, int cmd, Object obj) {
702 return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj);
Lorenzo Colitti165c51c2016-09-19 01:00:19 +0900703 }
704
Paul Jensencf4c2c62015-07-01 14:16:32 -0400705 public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
706 return mLastCreatedNetworkMonitor;
707 }
708
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900709 public void waitForIdle(int timeoutMs) {
710 ((IdleableHandlerThread) mHandlerThread).waitForIdle(timeoutMs);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400711 }
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900712
713 public void waitForIdle() {
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900714 waitForIdle(TIMEOUT_MS);
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900715 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400716 }
717
Paul Jensen0a2823e2015-06-12 10:31:09 -0400718 private interface Criteria {
719 public boolean get();
720 }
721
Paul Jensen3d911462015-06-12 06:40:24 -0400722 /**
723 * Wait up to 500ms for {@code criteria.get()} to become true, polling.
724 * Fails if 500ms goes by before {@code criteria.get()} to become true.
725 */
Paul Jensen0a2823e2015-06-12 10:31:09 -0400726 static private void waitFor(Criteria criteria) {
727 int delays = 0;
728 while (!criteria.get()) {
729 try {
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900730 Thread.sleep(50);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400731 } catch (InterruptedException e) {
732 }
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900733 if (++delays == 10) fail();
Paul Jensen0a2823e2015-06-12 10:31:09 -0400734 }
735 }
736
Paul Jensen3d911462015-06-12 06:40:24 -0400737 /**
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900738 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open.
739 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens.
Paul Jensen3d911462015-06-12 06:40:24 -0400740 */
741 static private void waitFor(ConditionVariable conditionVariable) {
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900742 assertTrue(conditionVariable.block(TIMEOUT_MS));
Paul Jensen3d911462015-06-12 06:40:24 -0400743 }
744
Paul Jensend7b6ca92015-05-13 14:05:12 -0400745 @Override
746 public void setUp() throws Exception {
747 super.setUp();
748
Lorenzo Colitti2c1a2532015-11-27 10:52:10 +0900749 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
750 // http://b/25897652 .
751 if (Looper.myLooper() == null) {
752 Looper.prepare();
753 }
754
Paul Jensend7b6ca92015-05-13 14:05:12 -0400755 mServiceContext = new MockContext(getContext());
Lorenzo Colitti83fa2582015-08-07 12:49:01 +0900756 mService = new WrappedConnectivityService(mServiceContext,
757 mock(INetworkManagementService.class),
758 mock(INetworkStatsService.class),
Hugo Benichif9fdf872016-07-28 17:53:06 +0900759 mock(INetworkPolicyManager.class),
760 mock(IpConnectivityLog.class));
Paul Jensend7b6ca92015-05-13 14:05:12 -0400761
Paul Jensend7b6ca92015-05-13 14:05:12 -0400762 mService.systemReady();
Lorenzo Colitti531a3442016-03-01 12:55:58 +0900763 mCm = new WrappedConnectivityManager(getContext(), mService);
764 mCm.bindProcessToNetwork(null);
Calvin Ond2bd69a2016-10-11 15:10:46 -0700765
766 // Ensure that the default setting for Captive Portals is used for most tests
767 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400768 }
769
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +0900770 public void tearDown() throws Exception {
Lorenzo Colittie14d49a2016-07-20 21:35:19 +0900771 setMobileDataAlwaysOn(false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +0900772 if (mCellNetworkAgent != null) { mCellNetworkAgent.disconnect(); }
773 if (mWiFiNetworkAgent != null) { mWiFiNetworkAgent.disconnect(); }
774 mCellNetworkAgent = mWiFiNetworkAgent = null;
775 super.tearDown();
776 }
777
Paul Jensend7b6ca92015-05-13 14:05:12 -0400778 private int transportToLegacyType(int transport) {
779 switch (transport) {
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900780 case TRANSPORT_ETHERNET:
781 return TYPE_ETHERNET;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400782 case TRANSPORT_WIFI:
783 return TYPE_WIFI;
784 case TRANSPORT_CELLULAR:
785 return TYPE_MOBILE;
786 default:
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900787 throw new IllegalStateException("Unknown transport " + transport);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400788 }
789 }
790
791 private void verifyActiveNetwork(int transport) {
792 // Test getActiveNetworkInfo()
793 assertNotNull(mCm.getActiveNetworkInfo());
794 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType());
795 // Test getActiveNetwork()
796 assertNotNull(mCm.getActiveNetwork());
Robin Leed2baf792016-03-24 12:07:00 +0000797 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid()));
Paul Jensend7b6ca92015-05-13 14:05:12 -0400798 switch (transport) {
799 case TRANSPORT_WIFI:
800 assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
801 break;
802 case TRANSPORT_CELLULAR:
803 assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork());
804 break;
805 default:
806 throw new IllegalStateException("Unknown transport" + transport);
807 }
808 // Test getNetworkInfo(Network)
809 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork()));
810 assertEquals(transportToLegacyType(transport), mCm.getNetworkInfo(mCm.getActiveNetwork()).getType());
811 // Test getNetworkCapabilities(Network)
812 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork()));
813 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport));
814 }
815
816 private void verifyNoNetwork() {
817 // Test getActiveNetworkInfo()
818 assertNull(mCm.getActiveNetworkInfo());
819 // Test getActiveNetwork()
820 assertNull(mCm.getActiveNetwork());
Robin Leed2baf792016-03-24 12:07:00 +0000821 assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
Paul Jensend7b6ca92015-05-13 14:05:12 -0400822 // Test getAllNetworks()
823 assertEquals(0, mCm.getAllNetworks().length);
824 }
825
826 /**
827 * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION
828 * broadcasts are received.
829 */
830 private ConditionVariable waitForConnectivityBroadcasts(final int count) {
831 final ConditionVariable cv = new ConditionVariable();
832 mServiceContext.registerReceiver(new BroadcastReceiver() {
833 private int remaining = count;
834 public void onReceive(Context context, Intent intent) {
835 if (--remaining == 0) {
836 cv.open();
837 mServiceContext.unregisterReceiver(this);
838 }
839 }
840 }, new IntentFilter(CONNECTIVITY_ACTION));
841 return cv;
842 }
843
844 @LargeTest
845 public void testLingering() throws Exception {
Paul Jensend7b6ca92015-05-13 14:05:12 -0400846 verifyNoNetwork();
847 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
848 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
849 assertNull(mCm.getActiveNetworkInfo());
850 assertNull(mCm.getActiveNetwork());
851 // Test bringing up validated cellular.
852 ConditionVariable cv = waitForConnectivityBroadcasts(1);
853 mCellNetworkAgent.connect(true);
Paul Jensen3d911462015-06-12 06:40:24 -0400854 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400855 verifyActiveNetwork(TRANSPORT_CELLULAR);
856 assertEquals(2, mCm.getAllNetworks().length);
857 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
858 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
859 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) ||
860 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork()));
861 // Test bringing up validated WiFi.
862 cv = waitForConnectivityBroadcasts(2);
863 mWiFiNetworkAgent.connect(true);
Paul Jensen3d911462015-06-12 06:40:24 -0400864 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400865 verifyActiveNetwork(TRANSPORT_WIFI);
866 assertEquals(2, mCm.getAllNetworks().length);
867 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
868 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
869 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) ||
870 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork()));
871 // Test cellular linger timeout.
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900872 waitFor(new Criteria() {
873 public boolean get() { return mCm.getAllNetworks().length == 1; } });
Paul Jensend7b6ca92015-05-13 14:05:12 -0400874 verifyActiveNetwork(TRANSPORT_WIFI);
875 assertEquals(1, mCm.getAllNetworks().length);
876 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork());
877 // Test WiFi disconnect.
878 cv = waitForConnectivityBroadcasts(1);
879 mWiFiNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400880 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400881 verifyNoNetwork();
882 }
883
884 @LargeTest
885 public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
886 // Test bringing up unvalidated WiFi
887 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
888 ConditionVariable cv = waitForConnectivityBroadcasts(1);
889 mWiFiNetworkAgent.connect(false);
Paul Jensen3d911462015-06-12 06:40:24 -0400890 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400891 verifyActiveNetwork(TRANSPORT_WIFI);
892 // Test bringing up unvalidated cellular
893 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
894 mCellNetworkAgent.connect(false);
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900895 mService.waitForIdle();
Paul Jensend7b6ca92015-05-13 14:05:12 -0400896 verifyActiveNetwork(TRANSPORT_WIFI);
897 // Test cellular disconnect.
898 mCellNetworkAgent.disconnect();
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900899 mService.waitForIdle();
Paul Jensend7b6ca92015-05-13 14:05:12 -0400900 verifyActiveNetwork(TRANSPORT_WIFI);
901 // Test bringing up validated cellular
902 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
903 cv = waitForConnectivityBroadcasts(2);
904 mCellNetworkAgent.connect(true);
Paul Jensen3d911462015-06-12 06:40:24 -0400905 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400906 verifyActiveNetwork(TRANSPORT_CELLULAR);
907 // Test cellular disconnect.
908 cv = waitForConnectivityBroadcasts(2);
909 mCellNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400910 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400911 verifyActiveNetwork(TRANSPORT_WIFI);
912 // Test WiFi disconnect.
913 cv = waitForConnectivityBroadcasts(1);
914 mWiFiNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400915 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400916 verifyNoNetwork();
917 }
918
919 @LargeTest
920 public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
921 // Test bringing up unvalidated cellular.
922 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
923 ConditionVariable cv = waitForConnectivityBroadcasts(1);
924 mCellNetworkAgent.connect(false);
Paul Jensen3d911462015-06-12 06:40:24 -0400925 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400926 verifyActiveNetwork(TRANSPORT_CELLULAR);
927 // Test bringing up unvalidated WiFi.
928 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
929 cv = waitForConnectivityBroadcasts(2);
930 mWiFiNetworkAgent.connect(false);
Paul Jensen3d911462015-06-12 06:40:24 -0400931 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400932 verifyActiveNetwork(TRANSPORT_WIFI);
933 // Test WiFi disconnect.
934 cv = waitForConnectivityBroadcasts(2);
935 mWiFiNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400936 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400937 verifyActiveNetwork(TRANSPORT_CELLULAR);
938 // Test cellular disconnect.
939 cv = waitForConnectivityBroadcasts(1);
940 mCellNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400941 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400942 verifyNoNetwork();
943 }
944
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700945 @LargeTest
Paul Jensene0988542015-06-25 15:30:08 -0400946 public void testUnlingeringDoesNotValidate() throws Exception {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400947 // Test bringing up unvalidated WiFi.
Paul Jensene0988542015-06-25 15:30:08 -0400948 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400949 ConditionVariable cv = waitForConnectivityBroadcasts(1);
950 mWiFiNetworkAgent.connect(false);
Paul Jensene0988542015-06-25 15:30:08 -0400951 waitFor(cv);
952 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400953 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
Paul Jensene0988542015-06-25 15:30:08 -0400954 NET_CAPABILITY_VALIDATED));
Paul Jensencf4c2c62015-07-01 14:16:32 -0400955 // Test bringing up validated cellular.
956 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
Paul Jensene0988542015-06-25 15:30:08 -0400957 cv = waitForConnectivityBroadcasts(2);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400958 mCellNetworkAgent.connect(true);
Paul Jensene0988542015-06-25 15:30:08 -0400959 waitFor(cv);
960 verifyActiveNetwork(TRANSPORT_CELLULAR);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400961 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
962 NET_CAPABILITY_VALIDATED));
963 // Test cellular disconnect.
964 cv = waitForConnectivityBroadcasts(2);
965 mCellNetworkAgent.disconnect();
966 waitFor(cv);
967 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensene0988542015-06-25 15:30:08 -0400968 // Unlingering a network should not cause it to be marked as validated.
Paul Jensencf4c2c62015-07-01 14:16:32 -0400969 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
Paul Jensene0988542015-06-25 15:30:08 -0400970 NET_CAPABILITY_VALIDATED));
971 }
972
973 @LargeTest
Paul Jensen3d911462015-06-12 06:40:24 -0400974 public void testCellularOutscoresWeakWifi() throws Exception {
975 // Test bringing up validated cellular.
976 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
977 ConditionVariable cv = waitForConnectivityBroadcasts(1);
978 mCellNetworkAgent.connect(true);
979 waitFor(cv);
980 verifyActiveNetwork(TRANSPORT_CELLULAR);
981 // Test bringing up validated WiFi.
982 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
983 cv = waitForConnectivityBroadcasts(2);
984 mWiFiNetworkAgent.connect(true);
985 waitFor(cv);
986 verifyActiveNetwork(TRANSPORT_WIFI);
987 // Test WiFi getting really weak.
988 cv = waitForConnectivityBroadcasts(2);
989 mWiFiNetworkAgent.adjustScore(-11);
990 waitFor(cv);
991 verifyActiveNetwork(TRANSPORT_CELLULAR);
992 // Test WiFi restoring signal strength.
993 cv = waitForConnectivityBroadcasts(2);
994 mWiFiNetworkAgent.adjustScore(11);
995 waitFor(cv);
996 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensen3d911462015-06-12 06:40:24 -0400997 }
998
Paul Jensene0988542015-06-25 15:30:08 -0400999 @LargeTest
1000 public void testReapingNetwork() throws Exception {
1001 // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
1002 // Expect it to be torn down immediately because it satisfies no requests.
1003 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1004 ConditionVariable cv = mWiFiNetworkAgent.getDisconnectedCV();
1005 mWiFiNetworkAgent.connectWithoutInternet();
1006 waitFor(cv);
1007 // Test bringing up cellular without NET_CAPABILITY_INTERNET.
1008 // Expect it to be torn down immediately because it satisfies no requests.
1009 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1010 cv = mCellNetworkAgent.getDisconnectedCV();
1011 mCellNetworkAgent.connectWithoutInternet();
1012 waitFor(cv);
1013 // Test bringing up validated WiFi.
1014 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1015 cv = waitForConnectivityBroadcasts(1);
1016 mWiFiNetworkAgent.connect(true);
1017 waitFor(cv);
1018 verifyActiveNetwork(TRANSPORT_WIFI);
1019 // Test bringing up unvalidated cellular.
1020 // Expect it to be torn down because it could never be the highest scoring network
1021 // satisfying the default request even if it validated.
1022 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1023 cv = mCellNetworkAgent.getDisconnectedCV();
1024 mCellNetworkAgent.connect(false);
1025 waitFor(cv);
1026 verifyActiveNetwork(TRANSPORT_WIFI);
1027 cv = mWiFiNetworkAgent.getDisconnectedCV();
1028 mWiFiNetworkAgent.disconnect();
1029 waitFor(cv);
1030 }
1031
1032 @LargeTest
1033 public void testCellularFallback() throws Exception {
1034 // Test bringing up validated cellular.
1035 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1036 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1037 mCellNetworkAgent.connect(true);
1038 waitFor(cv);
1039 verifyActiveNetwork(TRANSPORT_CELLULAR);
1040 // Test bringing up validated WiFi.
1041 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1042 cv = waitForConnectivityBroadcasts(2);
1043 mWiFiNetworkAgent.connect(true);
1044 waitFor(cv);
1045 verifyActiveNetwork(TRANSPORT_WIFI);
1046 // Reevaluate WiFi (it'll instantly fail DNS).
1047 cv = waitForConnectivityBroadcasts(2);
1048 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1049 NET_CAPABILITY_VALIDATED));
1050 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork());
1051 // Should quickly fall back to Cellular.
1052 waitFor(cv);
1053 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1054 NET_CAPABILITY_VALIDATED));
1055 verifyActiveNetwork(TRANSPORT_CELLULAR);
1056 // Reevaluate cellular (it'll instantly fail DNS).
1057 cv = waitForConnectivityBroadcasts(2);
1058 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1059 NET_CAPABILITY_VALIDATED));
1060 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
1061 // Should quickly fall back to WiFi.
1062 waitFor(cv);
1063 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1064 NET_CAPABILITY_VALIDATED));
1065 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1066 NET_CAPABILITY_VALIDATED));
1067 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensene0988542015-06-25 15:30:08 -04001068 }
1069
1070 @LargeTest
1071 public void testWiFiFallback() throws Exception {
1072 // Test bringing up unvalidated WiFi.
1073 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1074 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1075 mWiFiNetworkAgent.connect(false);
1076 waitFor(cv);
1077 verifyActiveNetwork(TRANSPORT_WIFI);
1078 // Test bringing up validated cellular.
1079 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1080 cv = waitForConnectivityBroadcasts(2);
1081 mCellNetworkAgent.connect(true);
1082 waitFor(cv);
1083 verifyActiveNetwork(TRANSPORT_CELLULAR);
1084 // Reevaluate cellular (it'll instantly fail DNS).
1085 cv = waitForConnectivityBroadcasts(2);
1086 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1087 NET_CAPABILITY_VALIDATED));
1088 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
1089 // Should quickly fall back to WiFi.
1090 waitFor(cv);
1091 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1092 NET_CAPABILITY_VALIDATED));
1093 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensene0988542015-06-25 15:30:08 -04001094 }
1095
Paul Jensen3d911462015-06-12 06:40:24 -04001096 enum CallbackState {
1097 NONE,
1098 AVAILABLE,
Erik Klineacdd6392016-07-07 16:50:58 +09001099 NETWORK_CAPABILITIES,
1100 LINK_PROPERTIES,
Paul Jensen3d911462015-06-12 06:40:24 -04001101 LOSING,
Erik Kline95be6232015-11-25 12:49:38 +09001102 LOST,
1103 UNAVAILABLE
Paul Jensen3d911462015-06-12 06:40:24 -04001104 }
1105
Hugo Benichi4e1619f2016-12-20 17:05:06 +09001106 private static class CallbackInfo {
1107 public final CallbackState state;
1108 public final Network network;
1109 public final Object arg;
1110 public CallbackInfo(CallbackState s, Network n, Object o) {
1111 state = s; network = n; arg = o;
1112 }
1113 public String toString() {
1114 return String.format("%s (%s)", state, network);
1115 }
1116 @Override
1117 public boolean equals(Object o) {
1118 if (!(o instanceof CallbackInfo)) return false;
1119 // Ignore timeMs, since it's unpredictable.
1120 CallbackInfo other = (CallbackInfo) o;
1121 return (state == other.state) && Objects.equals(network, other.network);
1122 }
1123 @Override
1124 public int hashCode() {
1125 return Objects.hash(state, network);
1126 }
1127 }
1128
Lorenzo Colitti83fa2582015-08-07 12:49:01 +09001129 /**
1130 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks
1131 * this class receives, by calling expectCallback() exactly once each time a callback is
1132 * received. assertNoCallback may be called at any time.
1133 */
Paul Jensen3d911462015-06-12 06:40:24 -04001134 private class TestNetworkCallback extends NetworkCallback {
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001135 // Chosen to be much less than the linger timeout. This ensures that we can distinguish
1136 // between a LOST callback that arrives immediately and a LOST callback that arrives after
1137 // the linger timeout.
1138 private final static int TIMEOUT_MS = 50;
1139
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001140 private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
1141
Erik Klineacdd6392016-07-07 16:50:58 +09001142 protected void setLastCallback(CallbackState state, Network network, Object o) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001143 mCallbacks.offer(new CallbackInfo(state, network, o));
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001144 }
Paul Jensen3d911462015-06-12 06:40:24 -04001145
Erik Klineacdd6392016-07-07 16:50:58 +09001146 @Override
Paul Jensen3d911462015-06-12 06:40:24 -04001147 public void onAvailable(Network network) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001148 setLastCallback(CallbackState.AVAILABLE, network, null);
Paul Jensen3d911462015-06-12 06:40:24 -04001149 }
1150
Erik Klineacdd6392016-07-07 16:50:58 +09001151 @Override
Erik Kline95be6232015-11-25 12:49:38 +09001152 public void onUnavailable() {
1153 setLastCallback(CallbackState.UNAVAILABLE, null, null);
1154 }
1155
1156 @Override
Paul Jensen3d911462015-06-12 06:40:24 -04001157 public void onLosing(Network network, int maxMsToLive) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001158 setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
Paul Jensen3d911462015-06-12 06:40:24 -04001159 }
1160
Erik Klineacdd6392016-07-07 16:50:58 +09001161 @Override
Paul Jensen3d911462015-06-12 06:40:24 -04001162 public void onLost(Network network) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001163 setLastCallback(CallbackState.LOST, network, null);
1164 }
1165
Hugo Benichi4e1619f2016-12-20 17:05:06 +09001166 CallbackInfo nextCallback(int timeoutMs) {
1167 CallbackInfo cb = null;
1168 try {
1169 cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS);
1170 } catch (InterruptedException e) {
1171 }
1172 if (cb == null) {
1173 // LinkedBlockingQueue.poll() returns null if it timeouts.
1174 fail("Did not receive callback after " + timeoutMs + "ms");
1175 }
1176 return cb;
1177 }
1178
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001179 void expectCallback(CallbackState state, MockNetworkAgent mockAgent, int timeoutMs) {
1180 CallbackInfo expected = new CallbackInfo(
1181 state, (mockAgent != null) ? mockAgent.getNetwork() : null, 0);
Hugo Benichi4e1619f2016-12-20 17:05:06 +09001182 CallbackInfo actual = nextCallback(timeoutMs);
1183 assertEquals("Unexpected callback:", expected, actual);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001184 if (state == CallbackState.LOSING) {
1185 String msg = String.format(
1186 "Invalid linger time value %d, must be between %d and %d",
1187 actual.arg, 0, TEST_LINGER_DELAY_MS);
1188 int maxMsToLive = (Integer) actual.arg;
1189 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= TEST_LINGER_DELAY_MS);
1190 }
Erik Klinea2d29402016-03-16 15:31:39 +09001191 }
1192
1193 void expectCallback(CallbackState state, MockNetworkAgent mockAgent) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001194 expectCallback(state, mockAgent, TIMEOUT_MS);
Paul Jensen3d911462015-06-12 06:40:24 -04001195 }
1196
Lorenzo Colitti83fa2582015-08-07 12:49:01 +09001197 void assertNoCallback() {
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001198 mService.waitForIdle();
1199 CallbackInfo c = mCallbacks.peek();
1200 assertNull("Unexpected callback: " + c, c);
1201 }
1202 }
1203
1204 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can
1205 // only be declared in a static or top level type".
1206 static void assertNoCallbacks(TestNetworkCallback ... callbacks) {
1207 for (TestNetworkCallback c : callbacks) {
1208 c.assertNoCallback();
Paul Jensen3d911462015-06-12 06:40:24 -04001209 }
1210 }
1211
1212 @LargeTest
1213 public void testStateChangeNetworkCallbacks() throws Exception {
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001214 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
Paul Jensen3d911462015-06-12 06:40:24 -04001215 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
1216 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001217 final NetworkRequest genericRequest = new NetworkRequest.Builder()
1218 .clearCapabilities().build();
Paul Jensen3d911462015-06-12 06:40:24 -04001219 final NetworkRequest wifiRequest = new NetworkRequest.Builder()
1220 .addTransportType(TRANSPORT_WIFI).build();
1221 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1222 .addTransportType(TRANSPORT_CELLULAR).build();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001223 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001224 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
1225 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
1226
1227 // Test unvalidated networks
Paul Jensen3d911462015-06-12 06:40:24 -04001228 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1229 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1230 mCellNetworkAgent.connect(false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001231 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1232 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001233 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1234 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001235 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001236
Paul Jensen3d911462015-06-12 06:40:24 -04001237 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1238 mCellNetworkAgent.adjustScore(-1);
Lorenzo Colittie58961a2015-08-07 20:17:27 +09001239 mService.waitForIdle();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001240 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001241 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1242
Paul Jensen3d911462015-06-12 06:40:24 -04001243 cv = waitForConnectivityBroadcasts(2);
1244 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1245 mWiFiNetworkAgent.connect(false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001246 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1247 wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001248 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1249 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001250 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001251
Paul Jensen3d911462015-06-12 06:40:24 -04001252 cv = waitForConnectivityBroadcasts(2);
1253 mWiFiNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001254 genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1255 wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colitti83fa2582015-08-07 12:49:01 +09001256 cellNetworkCallback.assertNoCallback();
Paul Jensen3d911462015-06-12 06:40:24 -04001257 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001258 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001259
Paul Jensen3d911462015-06-12 06:40:24 -04001260 cv = waitForConnectivityBroadcasts(1);
1261 mCellNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001262 genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1263 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001264 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001265 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001266
1267 // Test validated networks
Paul Jensen3d911462015-06-12 06:40:24 -04001268 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1269 mCellNetworkAgent.connect(true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001270 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1271 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001272 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001273 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001274
Paul Jensen3d911462015-06-12 06:40:24 -04001275 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1276 mCellNetworkAgent.adjustScore(-1);
Lorenzo Colittie58961a2015-08-07 20:17:27 +09001277 mService.waitForIdle();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001278 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001279 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1280
Paul Jensen3d911462015-06-12 06:40:24 -04001281 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1282 mWiFiNetworkAgent.connect(true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001283 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1284 genericNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1285 wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1286 cellNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001287 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001288 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001289
Paul Jensen3d911462015-06-12 06:40:24 -04001290 mWiFiNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001291 genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1292 wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1293 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001294
Paul Jensen3d911462015-06-12 06:40:24 -04001295 mCellNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001296 genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1297 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1298 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001299 }
1300
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001301 @SmallTest
1302 public void testMultipleLingering() {
1303 NetworkRequest request = new NetworkRequest.Builder()
1304 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED)
1305 .build();
1306 TestNetworkCallback callback = new TestNetworkCallback();
1307 mCm.registerNetworkCallback(request, callback);
1308
1309 TestNetworkCallback defaultCallback = new TestNetworkCallback();
1310 mCm.registerDefaultNetworkCallback(defaultCallback);
1311
1312 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1313 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1314 mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
1315
1316 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1317 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1318 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1319
1320 mCellNetworkAgent.connect(true);
1321 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1322 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1323 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1324
1325 mWiFiNetworkAgent.connect(true);
1326 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request.
1327 // We then get LOSING when wifi validates and cell is outscored.
1328 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1329 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1330 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1331 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1332
1333 mEthernetNetworkAgent.connect(true);
1334 callback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
1335 callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
1336 defaultCallback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
1337 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1338
1339 mEthernetNetworkAgent.disconnect();
1340 callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1341 defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1342 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1343
1344 for (int i = 0; i < 4; i++) {
1345 MockNetworkAgent oldNetwork, newNetwork;
1346 if (i % 2 == 0) {
1347 mWiFiNetworkAgent.adjustScore(-15);
1348 oldNetwork = mWiFiNetworkAgent;
1349 newNetwork = mCellNetworkAgent;
1350 } else {
1351 mWiFiNetworkAgent.adjustScore(15);
1352 oldNetwork = mCellNetworkAgent;
1353 newNetwork = mWiFiNetworkAgent;
1354
1355 }
1356 callback.expectCallback(CallbackState.LOSING, oldNetwork);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001357 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no
1358 // longer lingering?
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001359 defaultCallback.expectCallback(CallbackState.AVAILABLE, newNetwork);
1360 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork());
1361 }
1362 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1363
1364 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even
1365 // if the network is still up.
1366 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
1367 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1368
1369 // Wifi no longer satisfies our listen, which is for an unmetered network.
1370 // But because its score is 55, it's still up (and the default network).
1371 defaultCallback.assertNoCallback();
1372 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1373
1374 // Disconnect our test networks.
1375 mWiFiNetworkAgent.disconnect();
1376 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1377 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1378 mCellNetworkAgent.disconnect();
1379 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1380
1381 mCm.unregisterNetworkCallback(callback);
1382 mService.waitForIdle();
1383
1384 // Check that a network is only lingered or torn down if it would not satisfy a request even
1385 // if it validated.
1386 request = new NetworkRequest.Builder().clearCapabilities().build();
1387 callback = new TestNetworkCallback();
1388
1389 mCm.registerNetworkCallback(request, callback);
1390
1391 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1392 mCellNetworkAgent.connect(false); // Score: 10
1393 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1394 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1395 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1396
1397 // Bring up wifi with a score of 20.
1398 // Cell stays up because it would satisfy the default request if it validated.
1399 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1400 mWiFiNetworkAgent.connect(false); // Score: 20
1401 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1402 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1403 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1404
1405 mWiFiNetworkAgent.disconnect();
1406 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1407 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1408 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1409 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1410
1411 // Bring up wifi with a score of 70.
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001412 // Cell is lingered because it would not satisfy any request, even if it validated.
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001413 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1414 mWiFiNetworkAgent.adjustScore(50);
1415 mWiFiNetworkAgent.connect(false); // Score: 70
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001416 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001417 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001418 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1419 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1420
1421 // Tear down wifi.
1422 mWiFiNetworkAgent.disconnect();
1423 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1424 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1425 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1426 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1427
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001428 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but
1429 // it's arguably correct to linger it, since it was the default network before it validated.
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001430 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1431 mWiFiNetworkAgent.connect(true);
1432 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001433 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001434 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1435 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1436
1437 mWiFiNetworkAgent.disconnect();
1438 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001439 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001440 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1441 mCellNetworkAgent.disconnect();
1442 callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1443 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001444
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001445 // If a network is lingering, and we add and remove a request from it, resume lingering.
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001446 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1447 mCellNetworkAgent.connect(true);
1448 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1449 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1450 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1451 mWiFiNetworkAgent.connect(true);
1452 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1453 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1454 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1455
1456 NetworkRequest cellRequest = new NetworkRequest.Builder()
1457 .addTransportType(TRANSPORT_CELLULAR).build();
1458 NetworkCallback noopCallback = new NetworkCallback();
1459 mCm.requestNetwork(cellRequest, noopCallback);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001460 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer
1461 // lingering?
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001462 mCm.unregisterNetworkCallback(noopCallback);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001463 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001464
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001465 // Similar to the above: lingering can start even after the lingered request is removed.
1466 // Disconnect wifi and switch to cell.
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001467 mWiFiNetworkAgent.disconnect();
1468 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001469 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1470 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1471
1472 // Cell is now the default network. Pin it with a cell-specific request.
1473 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525
1474 mCm.requestNetwork(cellRequest, noopCallback);
1475
1476 // Now connect wifi, and expect it to become the default network.
1477 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1478 mWiFiNetworkAgent.connect(true);
1479 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1480 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1481 // The default request is lingering on cell, but nothing happens to cell, and we send no
1482 // callbacks for it, because it's kept up by cellRequest.
1483 callback.assertNoCallback();
1484 // Now unregister cellRequest and expect cell to start lingering.
1485 mCm.unregisterNetworkCallback(noopCallback);
1486 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1487
1488 // Let linger run its course.
1489 callback.assertNoCallback();
1490 callback.expectCallback(CallbackState.LOST, mCellNetworkAgent,
1491 TEST_LINGER_DELAY_MS /* timeoutMs */);
1492
1493 // Clean up.
1494 mWiFiNetworkAgent.disconnect();
1495 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1496 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001497
1498 mCm.unregisterNetworkCallback(callback);
1499 mCm.unregisterNetworkCallback(defaultCallback);
1500 }
1501
Paul Jensen85cf78e2015-06-25 13:25:07 -04001502 private void tryNetworkFactoryRequests(int capability) throws Exception {
Paul Jensen487ffe72015-07-24 15:57:11 -04001503 // Verify NOT_RESTRICTED is set appropriately
1504 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
1505 .build().networkCapabilities;
1506 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
1507 capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
1508 capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
Paul Jensenaae613d2015-08-19 11:06:15 -04001509 capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
Paul Jensen487ffe72015-07-24 15:57:11 -04001510 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1511 } else {
1512 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1513 }
1514
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001515 NetworkCapabilities filter = new NetworkCapabilities();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001516 filter.addCapability(capability);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001517 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
1518 handlerThread.start();
Paul Jensen0a2823e2015-06-12 10:31:09 -04001519 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001520 mServiceContext, "testFactory", filter);
1521 testFactory.setScoreFilter(40);
Paul Jensen0a2823e2015-06-12 10:31:09 -04001522 ConditionVariable cv = testFactory.getNetworkStartedCV();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001523 testFactory.expectAddRequests(1);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001524 testFactory.register();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001525 testFactory.waitForNetworkRequests(1);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001526 int expectedRequestCount = 1;
1527 NetworkCallback networkCallback = null;
1528 // For non-INTERNET capabilities we cannot rely on the default request being present, so
1529 // add one.
1530 if (capability != NET_CAPABILITY_INTERNET) {
Paul Jensen85cf78e2015-06-25 13:25:07 -04001531 assertFalse(testFactory.getMyStartRequested());
1532 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
1533 networkCallback = new NetworkCallback();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001534 testFactory.expectAddRequests(1);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001535 mCm.requestNetwork(request, networkCallback);
1536 expectedRequestCount++;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001537 testFactory.waitForNetworkRequests(expectedRequestCount);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001538 }
Paul Jensen3d911462015-06-12 06:40:24 -04001539 waitFor(cv);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001540 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1541 assertTrue(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001542
Paul Jensen85cf78e2015-06-25 13:25:07 -04001543 // Now bring in a higher scored network.
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001544 MockNetworkAgent testAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001545 // Rather than create a validated network which complicates things by registering it's
1546 // own NetworkRequest during startup, just bump up the score to cancel out the
1547 // unvalidated penalty.
1548 testAgent.adjustScore(40);
1549 cv = testFactory.getNetworkStoppedCV();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001550
1551 // When testAgent connects, ConnectivityService will re-send us all current requests with
1552 // the new score. There are expectedRequestCount such requests, and we must wait for all of
1553 // them.
1554 testFactory.expectAddRequests(expectedRequestCount);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001555 testAgent.connect(false);
1556 testAgent.addCapability(capability);
Paul Jensen3d911462015-06-12 06:40:24 -04001557 waitFor(cv);
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001558 testFactory.waitForNetworkRequests(expectedRequestCount);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001559 assertFalse(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001560
Paul Jensen85cf78e2015-06-25 13:25:07 -04001561 // Bring in a bunch of requests.
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001562 testFactory.expectAddRequests(10);
1563 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001564 ConnectivityManager.NetworkCallback[] networkCallbacks =
1565 new ConnectivityManager.NetworkCallback[10];
1566 for (int i = 0; i< networkCallbacks.length; i++) {
1567 networkCallbacks[i] = new ConnectivityManager.NetworkCallback();
1568 NetworkRequest.Builder builder = new NetworkRequest.Builder();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001569 builder.addCapability(capability);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001570 mCm.requestNetwork(builder.build(), networkCallbacks[i]);
1571 }
Paul Jensen85cf78e2015-06-25 13:25:07 -04001572 testFactory.waitForNetworkRequests(10 + expectedRequestCount);
1573 assertFalse(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001574
Paul Jensen85cf78e2015-06-25 13:25:07 -04001575 // Remove the requests.
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001576 testFactory.expectRemoveRequests(10);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001577 for (int i = 0; i < networkCallbacks.length; i++) {
1578 mCm.unregisterNetworkCallback(networkCallbacks[i]);
1579 }
Paul Jensen85cf78e2015-06-25 13:25:07 -04001580 testFactory.waitForNetworkRequests(expectedRequestCount);
1581 assertFalse(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001582
Paul Jensen85cf78e2015-06-25 13:25:07 -04001583 // Drop the higher scored network.
1584 cv = testFactory.getNetworkStartedCV();
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001585 testAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -04001586 waitFor(cv);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001587 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1588 assertTrue(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001589
1590 testFactory.unregister();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001591 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001592 handlerThread.quit();
1593 }
1594
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001595 @LargeTest
Paul Jensen85cf78e2015-06-25 13:25:07 -04001596 public void testNetworkFactoryRequests() throws Exception {
1597 tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
1598 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
1599 tryNetworkFactoryRequests(NET_CAPABILITY_DUN);
1600 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA);
1601 tryNetworkFactoryRequests(NET_CAPABILITY_IMS);
1602 tryNetworkFactoryRequests(NET_CAPABILITY_CBS);
1603 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P);
1604 tryNetworkFactoryRequests(NET_CAPABILITY_IA);
1605 tryNetworkFactoryRequests(NET_CAPABILITY_RCS);
1606 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP);
1607 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS);
1608 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED);
1609 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET);
1610 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED);
1611 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN);
1612 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
1613 }
1614
1615 @LargeTest
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001616 public void testNoMutableNetworkRequests() throws Exception {
1617 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
1618 NetworkRequest.Builder builder = new NetworkRequest.Builder();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001619 builder.addCapability(NET_CAPABILITY_VALIDATED);
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001620 try {
1621 mCm.requestNetwork(builder.build(), new NetworkCallback());
1622 fail();
1623 } catch (IllegalArgumentException expected) {}
1624 try {
1625 mCm.requestNetwork(builder.build(), pendingIntent);
1626 fail();
1627 } catch (IllegalArgumentException expected) {}
1628 builder = new NetworkRequest.Builder();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001629 builder.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001630 try {
1631 mCm.requestNetwork(builder.build(), new NetworkCallback());
1632 fail();
1633 } catch (IllegalArgumentException expected) {}
1634 try {
1635 mCm.requestNetwork(builder.build(), pendingIntent);
1636 fail();
1637 } catch (IllegalArgumentException expected) {}
1638 }
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001639
Paul Jensene0988542015-06-25 15:30:08 -04001640 @LargeTest
1641 public void testMMSonWiFi() throws Exception {
1642 // Test bringing up cellular without MMS NetworkRequest gets reaped
1643 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1644 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1645 ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV();
1646 mCellNetworkAgent.connectWithoutInternet();
1647 waitFor(cv);
1648 waitFor(new Criteria() {
1649 public boolean get() { return mCm.getAllNetworks().length == 0; } });
1650 verifyNoNetwork();
1651 // Test bringing up validated WiFi.
1652 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1653 cv = waitForConnectivityBroadcasts(1);
1654 mWiFiNetworkAgent.connect(true);
1655 waitFor(cv);
1656 verifyActiveNetwork(TRANSPORT_WIFI);
1657 // Register MMS NetworkRequest
1658 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1659 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1660 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1661 mCm.requestNetwork(builder.build(), networkCallback);
1662 // Test bringing up unvalidated cellular with MMS
1663 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1664 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
Paul Jensene0988542015-06-25 15:30:08 -04001665 mCellNetworkAgent.connectWithoutInternet();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001666 networkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Paul Jensene0988542015-06-25 15:30:08 -04001667 verifyActiveNetwork(TRANSPORT_WIFI);
1668 // Test releasing NetworkRequest disconnects cellular with MMS
1669 cv = mCellNetworkAgent.getDisconnectedCV();
1670 mCm.unregisterNetworkCallback(networkCallback);
1671 waitFor(cv);
1672 verifyActiveNetwork(TRANSPORT_WIFI);
1673 }
1674
1675 @LargeTest
1676 public void testMMSonCell() throws Exception {
1677 // Test bringing up cellular without MMS
1678 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1679 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1680 mCellNetworkAgent.connect(false);
1681 waitFor(cv);
1682 verifyActiveNetwork(TRANSPORT_CELLULAR);
1683 // Register MMS NetworkRequest
1684 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1685 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1686 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1687 mCm.requestNetwork(builder.build(), networkCallback);
1688 // Test bringing up MMS cellular network
Paul Jensene0988542015-06-25 15:30:08 -04001689 MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1690 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1691 mmsNetworkAgent.connectWithoutInternet();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001692 networkCallback.expectCallback(CallbackState.AVAILABLE, mmsNetworkAgent);
Paul Jensene0988542015-06-25 15:30:08 -04001693 verifyActiveNetwork(TRANSPORT_CELLULAR);
1694 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
1695 cv = mmsNetworkAgent.getDisconnectedCV();
1696 mCm.unregisterNetworkCallback(networkCallback);
1697 waitFor(cv);
1698 verifyActiveNetwork(TRANSPORT_CELLULAR);
1699 }
1700
Paul Jensencf4c2c62015-07-01 14:16:32 -04001701 @LargeTest
1702 public void testCaptivePortal() {
1703 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1704 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1705 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1706 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1707
1708 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1709 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1710 .addCapability(NET_CAPABILITY_VALIDATED).build();
1711 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001712
1713 // Bring up a network with a captive portal.
1714 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001715 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
Paul Jensen232437312016-04-06 09:51:26 -04001716 String firstRedirectUrl = "http://example.com/firstPath";
1717 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001718 captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensen232437312016-04-06 09:51:26 -04001719 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001720
1721 // Take down network.
1722 // Expect onLost callback.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001723 mWiFiNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001724 captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001725
1726 // Bring up a network with a captive portal.
1727 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001728 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
Paul Jensen232437312016-04-06 09:51:26 -04001729 String secondRedirectUrl = "http://example.com/secondPath";
1730 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001731 captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensen232437312016-04-06 09:51:26 -04001732 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001733
1734 // Make captive portal disappear then revalidate.
1735 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001736 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
1737 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001738 captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001739
1740 // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001741 validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001742
1743 // Break network connectivity.
1744 // Expect NET_CAPABILITY_VALIDATED onLost callback.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001745 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
1746 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001747 validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001748 }
Lorenzo Colitti7914ce52015-09-08 13:21:48 +09001749
Calvin Ond2bd69a2016-10-11 15:10:46 -07001750 @LargeTest
1751 public void testAvoidOrIgnoreCaptivePortals() {
1752 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1753 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1754 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1755 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1756
1757 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1758 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1759 .addCapability(NET_CAPABILITY_VALIDATED).build();
1760 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
1761
1762 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_AVOID);
1763 // Bring up a network with a captive portal.
1764 // Expect it to fail to connect and not result in any callbacks.
1765 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1766 String firstRedirectUrl = "http://example.com/firstPath";
1767
1768 ConditionVariable disconnectCv = mWiFiNetworkAgent.getDisconnectedCV();
1769 ConditionVariable avoidCv = mWiFiNetworkAgent.getPreventReconnectReceived();
1770 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
1771 waitFor(disconnectCv);
1772 waitFor(avoidCv);
1773
1774 assertNoCallbacks(captivePortalCallback, validatedCallback);
1775
1776 // Now test ignore mode.
1777 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
1778
1779 // Bring up a network with a captive portal.
1780 // Since we're ignoring captive portals, the network will validate.
1781 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1782 String secondRedirectUrl = "http://example.com/secondPath";
1783 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
1784
1785 // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
1786 validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1787 // But there should be no CaptivePortal callback.
1788 captivePortalCallback.assertNoCallback();
1789 }
1790
Etan Cohenddb9ef02015-11-18 10:56:15 -08001791 @SmallTest
1792 public void testInvalidNetworkSpecifier() {
1793 boolean execptionCalled = true;
1794
1795 try {
1796 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1797 builder.setNetworkSpecifier(MATCH_ALL_REQUESTS_NETWORK_SPECIFIER);
1798 execptionCalled = false;
1799 } catch (IllegalArgumentException e) {
1800 // do nothing - should get here
1801 }
1802
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001803 assertTrue("NetworkRequest builder with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
Etan Cohenddb9ef02015-11-18 10:56:15 -08001804 execptionCalled);
1805
1806 try {
1807 NetworkCapabilities networkCapabilities = new NetworkCapabilities();
1808 networkCapabilities.addTransportType(TRANSPORT_WIFI)
1809 .setNetworkSpecifier(NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER);
1810 mService.requestNetwork(networkCapabilities, null, 0, null,
1811 ConnectivityManager.TYPE_WIFI);
1812 execptionCalled = false;
1813 } catch (IllegalArgumentException e) {
1814 // do nothing - should get here
1815 }
1816
1817 assertTrue("ConnectivityService requestNetwork with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
1818 execptionCalled);
1819 }
1820
Erik Klinea2d29402016-03-16 15:31:39 +09001821 @LargeTest
1822 public void testRegisterDefaultNetworkCallback() throws Exception {
1823 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
1824 mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
1825 defaultNetworkCallback.assertNoCallback();
1826
1827 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up
1828 // whenever Wi-Fi is up. Without this, the mobile network agent is
1829 // reaped before any other activity can take place.
1830 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
1831 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1832 .addTransportType(TRANSPORT_CELLULAR).build();
1833 mCm.requestNetwork(cellRequest, cellNetworkCallback);
1834 cellNetworkCallback.assertNoCallback();
1835
1836 // Bring up cell and expect CALLBACK_AVAILABLE.
1837 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1838 mCellNetworkAgent.connect(true);
1839 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1840 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1841
1842 // Bring up wifi and expect CALLBACK_AVAILABLE.
1843 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1844 mWiFiNetworkAgent.connect(true);
1845 cellNetworkCallback.assertNoCallback();
1846 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1847
1848 // Bring down cell. Expect no default network callback, since it wasn't the default.
1849 mCellNetworkAgent.disconnect();
1850 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1851 defaultNetworkCallback.assertNoCallback();
1852
1853 // Bring up cell. Expect no default network callback, since it won't be the default.
1854 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1855 mCellNetworkAgent.connect(true);
1856 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1857 defaultNetworkCallback.assertNoCallback();
1858
1859 // Bring down wifi. Expect the default network callback to notified of LOST wifi
1860 // followed by AVAILABLE cell.
1861 mWiFiNetworkAgent.disconnect();
1862 cellNetworkCallback.assertNoCallback();
1863 defaultNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1864 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1865 mCellNetworkAgent.disconnect();
1866 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1867 defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1868 }
1869
Erik Klineacdd6392016-07-07 16:50:58 +09001870 private class TestRequestUpdateCallback extends TestNetworkCallback {
1871 @Override
1872 public void onCapabilitiesChanged(Network network, NetworkCapabilities netCap) {
1873 setLastCallback(CallbackState.NETWORK_CAPABILITIES, network, netCap);
1874 }
1875
1876 @Override
1877 public void onLinkPropertiesChanged(Network network, LinkProperties linkProp) {
1878 setLastCallback(CallbackState.LINK_PROPERTIES, network, linkProp);
1879 }
1880 }
1881
1882 @LargeTest
1883 public void testRequestCallbackUpdates() throws Exception {
1884 // File a network request for mobile.
1885 final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback();
1886 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1887 .addTransportType(TRANSPORT_CELLULAR).build();
1888 mCm.requestNetwork(cellRequest, cellNetworkCallback);
1889
1890 // Bring up the mobile network.
1891 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1892 mCellNetworkAgent.connect(true);
1893
1894 // We should get onAvailable().
1895 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1896 // We should get onCapabilitiesChanged(), when the mobile network successfully validates.
1897 cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
1898 cellNetworkCallback.assertNoCallback();
1899
1900 // Update LinkProperties.
1901 final LinkProperties lp = new LinkProperties();
1902 lp.setInterfaceName("foonet_data0");
1903 mCellNetworkAgent.sendLinkProperties(lp);
1904 // We should get onLinkPropertiesChanged().
1905 cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
1906 cellNetworkCallback.assertNoCallback();
1907
1908 // Register a garden variety default network request.
1909 final TestNetworkCallback dfltNetworkCallback = new TestRequestUpdateCallback();
1910 mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
1911 // Only onAvailable() is called; no other information is delivered.
1912 dfltNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1913 dfltNetworkCallback.assertNoCallback();
1914
1915 // Request a NetworkCapabilities update; only the requesting callback is notified.
1916 mCm.requestNetworkCapabilities(dfltNetworkCallback);
1917 dfltNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
1918 cellNetworkCallback.assertNoCallback();
1919 dfltNetworkCallback.assertNoCallback();
1920
1921 // Request a LinkProperties update; only the requesting callback is notified.
1922 mCm.requestLinkProperties(dfltNetworkCallback);
1923 dfltNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
1924 cellNetworkCallback.assertNoCallback();
1925 dfltNetworkCallback.assertNoCallback();
1926
1927 mCm.unregisterNetworkCallback(dfltNetworkCallback);
1928 mCm.unregisterNetworkCallback(cellNetworkCallback);
1929 }
1930
Calvin Ond2bd69a2016-10-11 15:10:46 -07001931 private void setCaptivePortalMode(int mode) {
1932 ContentResolver cr = mServiceContext.getContentResolver();
1933 Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
1934 }
1935
Lorenzo Colittie14d49a2016-07-20 21:35:19 +09001936 private void setMobileDataAlwaysOn(boolean enable) {
1937 ContentResolver cr = mServiceContext.getContentResolver();
1938 Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0);
1939 mService.updateMobileDataAlwaysOn();
1940 mService.waitForIdle();
1941 }
1942
1943 private boolean isForegroundNetwork(MockNetworkAgent network) {
1944 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork());
1945 assertNotNull(nc);
1946 return nc.hasCapability(NET_CAPABILITY_FOREGROUND);
1947 }
1948
1949 @SmallTest
1950 public void testBackgroundNetworks() throws Exception {
1951 // Create a background request. We can't do this ourselves because ConnectivityService
1952 // doesn't have an API for it. So just turn on mobile data always on.
1953 setMobileDataAlwaysOn(true);
1954 final NetworkRequest request = new NetworkRequest.Builder().build();
1955 final NetworkRequest fgRequest = new NetworkRequest.Builder()
1956 .addCapability(NET_CAPABILITY_FOREGROUND).build();
1957 final TestNetworkCallback callback = new TestNetworkCallback();
1958 final TestNetworkCallback fgCallback = new TestNetworkCallback();
1959 mCm.registerNetworkCallback(request, callback);
1960 mCm.registerNetworkCallback(fgRequest, fgCallback);
1961
1962 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1963 mCellNetworkAgent.connect(true);
1964 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1965 fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1966 assertTrue(isForegroundNetwork(mCellNetworkAgent));
1967
1968 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1969 mWiFiNetworkAgent.connect(true);
1970
1971 // When wifi connects, cell lingers.
1972 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1973 fgCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1974 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1975 fgCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1976 assertTrue(isForegroundNetwork(mCellNetworkAgent));
1977 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
1978
1979 // When lingering is complete, cell is still there but is now in the background.
1980 fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent, TEST_LINGER_DELAY_MS);
1981 callback.assertNoCallback();
1982 assertFalse(isForegroundNetwork(mCellNetworkAgent));
1983 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
1984
1985 // File a cell request and check that cell comes into the foreground.
1986 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1987 .addTransportType(TRANSPORT_CELLULAR).build();
1988 final TestNetworkCallback cellCallback = new TestNetworkCallback();
1989 mCm.requestNetwork(cellRequest, cellCallback);
1990 cellCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1991 fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1992 callback.assertNoCallback(); // Because the network is already up.
1993 assertTrue(isForegroundNetwork(mCellNetworkAgent));
1994 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
1995
1996 // Release the request. The network immediately goes into the background, since it was not
1997 // lingering.
1998 mCm.unregisterNetworkCallback(cellCallback);
1999 fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2000 callback.assertNoCallback();
2001 assertFalse(isForegroundNetwork(mCellNetworkAgent));
2002 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
2003
2004 // Disconnect wifi and check that cell is foreground again.
2005 mWiFiNetworkAgent.disconnect();
2006 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2007 fgCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2008 fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2009 assertTrue(isForegroundNetwork(mCellNetworkAgent));
2010
2011 mCm.unregisterNetworkCallback(callback);
2012 mCm.unregisterNetworkCallback(fgCallback);
2013 }
2014
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002015 @SmallTest
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09002016 public void testRequestBenchmark() throws Exception {
2017 // Benchmarks connecting and switching performance in the presence of a large number of
2018 // NetworkRequests.
2019 // 1. File NUM_REQUESTS requests.
2020 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire.
2021 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing
2022 // and NUM_REQUESTS onAvailable callbacks to fire.
2023 // See how long it took.
2024 final int NUM_REQUESTS = 90;
2025 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
2026 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS];
2027 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS);
2028 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS);
2029
2030 final int REGISTER_TIME_LIMIT_MS = 100;
2031 long startTime = System.currentTimeMillis();
2032 for (int i = 0; i < NUM_REQUESTS; i++) {
2033 callbacks[i] = new NetworkCallback() {
2034 @Override public void onAvailable(Network n) { availableLatch.countDown(); }
2035 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); }
2036 };
2037 mCm.registerNetworkCallback(request, callbacks[i]);
2038 }
2039 long timeTaken = System.currentTimeMillis() - startTime;
2040 String msg = String.format("Register %d callbacks: %dms, acceptable %dms",
2041 NUM_REQUESTS, timeTaken, REGISTER_TIME_LIMIT_MS);
2042 Log.d(TAG, msg);
2043 assertTrue(msg, timeTaken < REGISTER_TIME_LIMIT_MS);
2044
2045 final int CONNECT_TIME_LIMIT_MS = 30;
2046 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2047 // Don't request that the network validate, because otherwise connect() will block until
2048 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired,
2049 // and we won't actually measure anything.
2050 mCellNetworkAgent.connect(false);
2051 startTime = System.currentTimeMillis();
2052 if (!availableLatch.await(CONNECT_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
2053 fail(String.format("Only dispatched %d/%d onAvailable callbacks in %dms",
2054 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
2055 CONNECT_TIME_LIMIT_MS));
2056 }
2057 timeTaken = System.currentTimeMillis() - startTime;
2058 Log.d(TAG, String.format("Connect, %d callbacks: %dms, acceptable %dms",
2059 NUM_REQUESTS, timeTaken, CONNECT_TIME_LIMIT_MS));
2060
2061 final int SWITCH_TIME_LIMIT_MS = 30;
2062 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2063 // Give wifi a high enough score that we'll linger cell when wifi comes up.
2064 mWiFiNetworkAgent.adjustScore(40);
2065 mWiFiNetworkAgent.connect(false);
2066 startTime = System.currentTimeMillis();
2067 if (!losingLatch.await(SWITCH_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
2068 fail(String.format("Only dispatched %d/%d onLosing callbacks in %dms",
2069 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, SWITCH_TIME_LIMIT_MS));
2070 }
2071 timeTaken = System.currentTimeMillis() - startTime;
2072 Log.d(TAG, String.format("Linger, %d callbacks: %dms, acceptable %dms",
2073 NUM_REQUESTS, timeTaken, SWITCH_TIME_LIMIT_MS));
2074
2075 final int UNREGISTER_TIME_LIMIT_MS = 10;
2076 startTime = System.currentTimeMillis();
2077 for (int i = 0; i < NUM_REQUESTS; i++) {
2078 mCm.unregisterNetworkCallback(callbacks[i]);
2079 }
2080 timeTaken = System.currentTimeMillis() - startTime;
2081 msg = String.format("Unregister %d callbacks: %dms, acceptable %dms",
2082 NUM_REQUESTS, timeTaken, UNREGISTER_TIME_LIMIT_MS);
2083 Log.d(TAG, msg);
2084 assertTrue(msg, timeTaken < UNREGISTER_TIME_LIMIT_MS);
2085 }
2086
2087 @SmallTest
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002088 public void testMobileDataAlwaysOn() throws Exception {
2089 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2090 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2091 .addTransportType(TRANSPORT_CELLULAR).build();
2092 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
2093
2094 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory");
2095 handlerThread.start();
2096 NetworkCapabilities filter = new NetworkCapabilities()
2097 .addTransportType(TRANSPORT_CELLULAR)
2098 .addCapability(NET_CAPABILITY_INTERNET);
2099 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
2100 mServiceContext, "testFactory", filter);
2101 testFactory.setScoreFilter(40);
2102
2103 // Register the factory and expect it to start looking for a network.
2104 testFactory.expectAddRequests(1);
2105 testFactory.register();
2106 testFactory.waitForNetworkRequests(1);
2107 assertTrue(testFactory.getMyStartRequested());
2108
2109 // Bring up wifi. The factory stops looking for a network.
2110 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2111 testFactory.expectAddRequests(2); // Because the default request changes score twice.
2112 mWiFiNetworkAgent.connect(true);
2113 testFactory.waitForNetworkRequests(1);
2114 assertFalse(testFactory.getMyStartRequested());
2115
2116 ContentResolver cr = mServiceContext.getContentResolver();
2117
2118 // Turn on mobile data always on. The factory starts looking again.
2119 testFactory.expectAddRequests(1);
Lorenzo Colittie14d49a2016-07-20 21:35:19 +09002120 setMobileDataAlwaysOn(true);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002121 testFactory.waitForNetworkRequests(2);
2122 assertTrue(testFactory.getMyStartRequested());
2123
2124 // Bring up cell data and check that the factory stops looking.
2125 assertEquals(1, mCm.getAllNetworks().length);
2126 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2127 testFactory.expectAddRequests(2); // Because the cell request changes score twice.
2128 mCellNetworkAgent.connect(true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09002129 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002130 testFactory.waitForNetworkRequests(2);
2131 assertFalse(testFactory.getMyStartRequested()); // Because the cell network outscores us.
2132
2133 // Check that cell data stays up.
2134 mService.waitForIdle();
2135 verifyActiveNetwork(TRANSPORT_WIFI);
2136 assertEquals(2, mCm.getAllNetworks().length);
2137
2138 // Turn off mobile data always on and expect the request to disappear...
2139 testFactory.expectRemoveRequests(1);
Lorenzo Colittie14d49a2016-07-20 21:35:19 +09002140 setMobileDataAlwaysOn(false);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002141 testFactory.waitForNetworkRequests(1);
2142
2143 // ... and cell data to be torn down.
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09002144 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002145 assertEquals(1, mCm.getAllNetworks().length);
2146
2147 testFactory.unregister();
2148 mCm.unregisterNetworkCallback(cellNetworkCallback);
2149 handlerThread.quit();
2150 }
2151
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002152 @SmallTest
2153 public void testAvoidBadWifiSetting() throws Exception {
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002154 final ContentResolver cr = mServiceContext.getContentResolver();
Erik Kline065ab6e2016-10-02 18:02:14 +09002155 final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002156 final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
2157
Erik Kline065ab6e2016-10-02 18:02:14 +09002158 tracker.configRestrictsAvoidBadWifi = false;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002159 String[] values = new String[] {null, "0", "1"};
2160 for (int i = 0; i < values.length; i++) {
2161 Settings.Global.putInt(cr, settingName, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002162 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002163 mService.waitForIdle();
2164 String msg = String.format("config=false, setting=%s", values[i]);
2165 assertTrue(msg, mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002166 assertFalse(msg, tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002167 }
2168
Erik Kline065ab6e2016-10-02 18:02:14 +09002169 tracker.configRestrictsAvoidBadWifi = true;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002170
2171 Settings.Global.putInt(cr, settingName, 0);
Erik Kline065ab6e2016-10-02 18:02:14 +09002172 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002173 mService.waitForIdle();
2174 assertFalse(mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002175 assertFalse(tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002176
2177 Settings.Global.putInt(cr, settingName, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002178 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002179 mService.waitForIdle();
2180 assertTrue(mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002181 assertFalse(tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002182
2183 Settings.Global.putString(cr, settingName, null);
Erik Kline065ab6e2016-10-02 18:02:14 +09002184 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002185 mService.waitForIdle();
2186 assertFalse(mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002187 assertTrue(tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002188 }
2189
2190 @SmallTest
2191 public void testAvoidBadWifi() throws Exception {
Erik Kline065ab6e2016-10-02 18:02:14 +09002192 final ContentResolver cr = mServiceContext.getContentResolver();
2193 final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002194
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002195 // Pretend we're on a carrier that restricts switching away from bad wifi.
Erik Kline065ab6e2016-10-02 18:02:14 +09002196 tracker.configRestrictsAvoidBadWifi = true;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002197
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002198 // File a request for cell to ensure it doesn't go down.
2199 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2200 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2201 .addTransportType(TRANSPORT_CELLULAR).build();
2202 mCm.requestNetwork(cellRequest, cellNetworkCallback);
2203
2204 TestNetworkCallback defaultCallback = new TestNetworkCallback();
2205 mCm.registerDefaultNetworkCallback(defaultCallback);
2206
2207 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder()
2208 .addTransportType(TRANSPORT_WIFI)
2209 .addCapability(NET_CAPABILITY_VALIDATED)
2210 .build();
2211 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback();
2212 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback);
2213
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002214 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 0);
Erik Kline065ab6e2016-10-02 18:02:14 +09002215 tracker.reevaluate();
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002216
2217 // Bring up validated cell.
2218 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2219 mCellNetworkAgent.connect(true);
2220 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2221 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2222 Network cellNetwork = mCellNetworkAgent.getNetwork();
2223
2224 // Bring up validated wifi.
2225 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2226 mWiFiNetworkAgent.connect(true);
2227 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2228 validatedWifiCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2229 Network wifiNetwork = mWiFiNetworkAgent.getNetwork();
2230
2231 // Fail validation on wifi.
2232 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
2233 mCm.reportNetworkConnectivity(wifiNetwork, false);
2234 validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2235
2236 // Because avoid bad wifi is off, we don't switch to cellular.
2237 defaultCallback.assertNoCallback();
2238 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2239 NET_CAPABILITY_VALIDATED));
2240 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2241 NET_CAPABILITY_VALIDATED));
2242 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2243
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002244 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect
2245 // that we switch back to cell.
Erik Kline065ab6e2016-10-02 18:02:14 +09002246 tracker.configRestrictsAvoidBadWifi = false;
2247 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002248 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2249 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2250
2251 // Switch back to a restrictive carrier.
Erik Kline065ab6e2016-10-02 18:02:14 +09002252 tracker.configRestrictsAvoidBadWifi = true;
2253 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002254 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2255 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2256
2257 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell.
2258 mCm.setAvoidUnvalidated(wifiNetwork);
2259 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2260 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2261 NET_CAPABILITY_VALIDATED));
2262 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2263 NET_CAPABILITY_VALIDATED));
2264 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2265
2266 // Disconnect and reconnect wifi to clear the one-time switch above.
2267 mWiFiNetworkAgent.disconnect();
2268 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2269 mWiFiNetworkAgent.connect(true);
2270 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2271 validatedWifiCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2272 wifiNetwork = mWiFiNetworkAgent.getNetwork();
2273
2274 // Fail validation on wifi and expect the dialog to appear.
2275 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
2276 mCm.reportNetworkConnectivity(wifiNetwork, false);
2277 validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2278
2279 // Simulate the user selecting "switch" and checking the don't ask again checkbox.
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002280 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002281 tracker.reevaluate();
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002282
2283 // We now switch to cell.
2284 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2285 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2286 NET_CAPABILITY_VALIDATED));
2287 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2288 NET_CAPABILITY_VALIDATED));
2289 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2290
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002291 // Simulate the user turning the cellular fallback setting off and then on.
2292 // We switch to wifi and then to cell.
2293 Settings.Global.putString(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
Erik Kline065ab6e2016-10-02 18:02:14 +09002294 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002295 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2296 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2297 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002298 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002299 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2300 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2301
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002302 // If cell goes down, we switch to wifi.
2303 mCellNetworkAgent.disconnect();
2304 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2305 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2306 validatedWifiCallback.assertNoCallback();
2307
2308 mCm.unregisterNetworkCallback(cellNetworkCallback);
2309 mCm.unregisterNetworkCallback(validatedWifiCallback);
2310 mCm.unregisterNetworkCallback(defaultCallback);
2311 }
2312
Erik Kline95be6232015-11-25 12:49:38 +09002313 /**
2314 * Validate that a satisfied network request does not trigger onUnavailable() once the
2315 * time-out period expires.
2316 */
2317 @SmallTest
2318 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
2319 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2320 NetworkCapabilities.TRANSPORT_WIFI).build();
2321 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2322 mCm.requestNetwork(nr, networkCallback, 10);
2323
2324 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2325 mWiFiNetworkAgent.connect(false);
2326 networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2327
2328 // pass timeout and validate that UNAVAILABLE is not called
2329 try {
2330 Thread.sleep(15);
2331 } catch (InterruptedException e) {
2332 }
2333 networkCallback.assertNoCallback();
2334 }
2335
2336 /**
2337 * Validate that when a time-out is specified for a network request the onUnavailable()
2338 * callback is called when time-out expires. Then validate that if network request is
2339 * (somehow) satisfied - the callback isn't called later.
2340 */
2341 @SmallTest
2342 public void testTimedoutNetworkRequest() {
2343 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2344 NetworkCapabilities.TRANSPORT_WIFI).build();
2345 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2346 mCm.requestNetwork(nr, networkCallback, 10);
2347
2348 // pass timeout and validate that UNAVAILABLE is called
2349 networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
2350
2351 // create a network satisfying request - validate that request not triggered
2352 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2353 mWiFiNetworkAgent.connect(false);
2354 networkCallback.assertNoCallback();
2355 }
2356
2357 /**
2358 * Validate that when a network request is unregistered (cancelled) the time-out for that
2359 * request doesn't trigger the onUnavailable() callback.
2360 */
2361 @SmallTest
2362 public void testTimedoutAfterUnregisteredNetworkRequest() {
2363 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2364 NetworkCapabilities.TRANSPORT_WIFI).build();
2365 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2366 mCm.requestNetwork(nr, networkCallback, 10);
2367
2368 // remove request
2369 mCm.unregisterNetworkCallback(networkCallback);
2370
2371 // pass timeout and validate that no callbacks
2372 // Note: doesn't validate that nothing called from CS since even if called the CM already
2373 // unregisters the callback and won't pass it through!
2374 try {
2375 Thread.sleep(15);
2376 } catch (InterruptedException e) {
2377 }
2378 networkCallback.assertNoCallback();
2379
2380 // create a network satisfying request - validate that request not triggered
2381 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2382 mWiFiNetworkAgent.connect(false);
2383 networkCallback.assertNoCallback();
2384 }
2385
Lorenzo Colitti7914ce52015-09-08 13:21:48 +09002386 private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
2387
2388 public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
2389
2390 private class CallbackValue {
2391 public CallbackType callbackType;
2392 public int error;
2393
2394 public CallbackValue(CallbackType type) {
2395 this.callbackType = type;
2396 this.error = PacketKeepalive.SUCCESS;
2397 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR);
2398 }
2399
2400 public CallbackValue(CallbackType type, int error) {
2401 this.callbackType = type;
2402 this.error = error;
2403 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR);
2404 }
2405
2406 @Override
2407 public boolean equals(Object o) {
2408 return o instanceof CallbackValue &&
2409 this.callbackType == ((CallbackValue) o).callbackType &&
2410 this.error == ((CallbackValue) o).error;
2411 }
2412
2413 @Override
2414 public String toString() {
2415 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error);
2416 }
2417 }
2418
2419 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>();
2420
2421 @Override
2422 public void onStarted() {
2423 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED));
2424 }
2425
2426 @Override
2427 public void onStopped() {
2428 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED));
2429 }
2430
2431 @Override
2432 public void onError(int error) {
2433 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
2434 }
2435
2436 private void expectCallback(CallbackValue callbackValue) {
2437 try {
2438 assertEquals(
2439 callbackValue,
2440 mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
2441 } catch (InterruptedException e) {
2442 fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
2443 }
2444 }
2445
2446 public void expectStarted() {
2447 expectCallback(new CallbackValue(CallbackType.ON_STARTED));
2448 }
2449
2450 public void expectStopped() {
2451 expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
2452 }
2453
2454 public void expectError(int error) {
2455 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
2456 }
2457 }
2458
2459 private Network connectKeepaliveNetwork(LinkProperties lp) {
2460 // Ensure the network is disconnected before we do anything.
2461 if (mWiFiNetworkAgent != null) {
2462 assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
2463 }
2464
2465 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2466 ConditionVariable cv = waitForConnectivityBroadcasts(1);
2467 mWiFiNetworkAgent.connect(true);
2468 waitFor(cv);
2469 verifyActiveNetwork(TRANSPORT_WIFI);
2470 mWiFiNetworkAgent.sendLinkProperties(lp);
2471 mService.waitForIdle();
2472 return mWiFiNetworkAgent.getNetwork();
2473 }
2474
2475 public void testPacketKeepalives() throws Exception {
2476 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
2477 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
2478 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
2479 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
2480 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888");
2481
2482 LinkProperties lp = new LinkProperties();
2483 lp.setInterfaceName("wlan12");
2484 lp.addLinkAddress(new LinkAddress(myIPv6, 64));
2485 lp.addLinkAddress(new LinkAddress(myIPv4, 25));
2486 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234")));
2487 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
2488
2489 Network notMyNet = new Network(61234);
2490 Network myNet = connectKeepaliveNetwork(lp);
2491
2492 TestKeepaliveCallback callback = new TestKeepaliveCallback();
2493 PacketKeepalive ka;
2494
2495 // Attempt to start keepalives with invalid parameters and check for errors.
2496 ka = mCm.startNattKeepalive(notMyNet, 25, callback, myIPv4, 1234, dstIPv4);
2497 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
2498
2499 ka = mCm.startNattKeepalive(myNet, 19, callback, notMyIPv4, 1234, dstIPv4);
2500 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL);
2501
2502 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 1234, dstIPv6);
2503 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2504
2505 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv4);
2506 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2507
2508 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv6);
2509 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); // NAT-T is IPv4-only.
2510
2511 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
2512 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
2513
2514 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
2515 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
2516
2517 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2518 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
2519
2520 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2521 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
2522
2523 // Check that a started keepalive can be stopped.
2524 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
2525 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2526 callback.expectStarted();
2527 mWiFiNetworkAgent.setStopKeepaliveError(PacketKeepalive.SUCCESS);
2528 ka.stop();
2529 callback.expectStopped();
2530
2531 // Check that deleting the IP address stops the keepalive.
2532 LinkProperties bogusLp = new LinkProperties(lp);
2533 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2534 callback.expectStarted();
2535 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25));
2536 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25));
2537 mWiFiNetworkAgent.sendLinkProperties(bogusLp);
2538 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2539 mWiFiNetworkAgent.sendLinkProperties(lp);
2540
2541 // Check that a started keepalive is stopped correctly when the network disconnects.
2542 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2543 callback.expectStarted();
2544 mWiFiNetworkAgent.disconnect();
2545 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
2546
2547 // ... and that stopping it after that has no adverse effects.
2548 assertNull(mCm.getNetworkCapabilities(myNet));
2549 ka.stop();
2550
2551 // Reconnect.
2552 myNet = connectKeepaliveNetwork(lp);
2553 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
2554
2555 // Check things work as expected when the keepalive is stopped and the network disconnects.
2556 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2557 callback.expectStarted();
2558 ka.stop();
2559 mWiFiNetworkAgent.disconnect();
2560 mService.waitForIdle();
2561 callback.expectStopped();
2562
2563 // Reconnect.
2564 myNet = connectKeepaliveNetwork(lp);
2565 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
2566
2567 // Check that keepalive slots start from 1 and increment. The first one gets slot 1.
2568 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
2569 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2570 callback.expectStarted();
2571
2572 // The second one gets slot 2.
2573 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
2574 TestKeepaliveCallback callback2 = new TestKeepaliveCallback();
2575 PacketKeepalive ka2 = mCm.startNattKeepalive(myNet, 25, callback2, myIPv4, 6789, dstIPv4);
2576 callback2.expectStarted();
2577
2578 // Now stop the first one and create a third. This also gets slot 1.
2579 ka.stop();
2580 callback.expectStopped();
2581
2582 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
2583 TestKeepaliveCallback callback3 = new TestKeepaliveCallback();
2584 PacketKeepalive ka3 = mCm.startNattKeepalive(myNet, 25, callback3, myIPv4, 9876, dstIPv4);
2585 callback3.expectStarted();
2586
2587 ka2.stop();
2588 callback2.expectStopped();
2589
2590 ka3.stop();
2591 callback3.expectStopped();
2592 }
Udam Sainib7c24872016-01-04 12:16:14 -08002593
2594 @SmallTest
2595 public void testGetCaptivePortalServerUrl() throws Exception {
2596 String url = mCm.getCaptivePortalServerUrl();
2597 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url);
2598 }
Lorenzo Colitti531a3442016-03-01 12:55:58 +09002599
2600 private static class TestNetworkPinner extends NetworkPinner {
2601 public static boolean awaitPin(int timeoutMs) {
2602 synchronized(sLock) {
2603 if (sNetwork == null) {
2604 try {
2605 sLock.wait(timeoutMs);
2606 } catch (InterruptedException e) {}
2607 }
2608 return sNetwork != null;
2609 }
2610 }
2611
2612 public static boolean awaitUnpin(int timeoutMs) {
2613 synchronized(sLock) {
2614 if (sNetwork != null) {
2615 try {
2616 sLock.wait(timeoutMs);
2617 } catch (InterruptedException e) {}
2618 }
2619 return sNetwork == null;
2620 }
2621 }
2622 }
2623
2624 private void assertPinnedToWifiWithCellDefault() {
2625 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
2626 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
2627 }
2628
2629 private void assertPinnedToWifiWithWifiDefault() {
2630 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
2631 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
2632 }
2633
2634 private void assertNotPinnedToWifi() {
2635 assertNull(mCm.getBoundNetworkForProcess());
2636 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
2637 }
2638
2639 @SmallTest
2640 public void testNetworkPinner() {
2641 NetworkRequest wifiRequest = new NetworkRequest.Builder()
2642 .addTransportType(TRANSPORT_WIFI)
2643 .build();
2644 assertNull(mCm.getBoundNetworkForProcess());
2645
2646 TestNetworkPinner.pin(mServiceContext, wifiRequest);
2647 assertNull(mCm.getBoundNetworkForProcess());
2648
2649 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2650 mCellNetworkAgent.connect(true);
2651 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2652 mWiFiNetworkAgent.connect(false);
2653
2654 // When wi-fi connects, expect to be pinned.
2655 assertTrue(TestNetworkPinner.awaitPin(100));
2656 assertPinnedToWifiWithCellDefault();
2657
2658 // Disconnect and expect the pin to drop.
2659 mWiFiNetworkAgent.disconnect();
2660 assertTrue(TestNetworkPinner.awaitUnpin(100));
2661 assertNotPinnedToWifi();
2662
2663 // Reconnecting does not cause the pin to come back.
2664 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2665 mWiFiNetworkAgent.connect(false);
2666 assertFalse(TestNetworkPinner.awaitPin(100));
2667 assertNotPinnedToWifi();
2668
2669 // Pinning while connected causes the pin to take effect immediately.
2670 TestNetworkPinner.pin(mServiceContext, wifiRequest);
2671 assertTrue(TestNetworkPinner.awaitPin(100));
2672 assertPinnedToWifiWithCellDefault();
2673
2674 // Explicitly unpin and expect to use the default network again.
2675 TestNetworkPinner.unpin();
2676 assertNotPinnedToWifi();
2677
2678 // Disconnect cell and wifi.
2679 ConditionVariable cv = waitForConnectivityBroadcasts(3); // cell down, wifi up, wifi down.
2680 mCellNetworkAgent.disconnect();
2681 mWiFiNetworkAgent.disconnect();
2682 waitFor(cv);
2683
2684 // Pinning takes effect even if the pinned network is the default when the pin is set...
2685 TestNetworkPinner.pin(mServiceContext, wifiRequest);
2686 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2687 mWiFiNetworkAgent.connect(false);
2688 assertTrue(TestNetworkPinner.awaitPin(100));
2689 assertPinnedToWifiWithWifiDefault();
2690
2691 // ... and is maintained even when that network is no longer the default.
2692 cv = waitForConnectivityBroadcasts(1);
2693 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2694 mCellNetworkAgent.connect(true);
2695 waitFor(cv);
2696 assertPinnedToWifiWithCellDefault();
2697 }
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04002698
2699 @SmallTest
2700 public void testNetworkRequestMaximum() {
2701 final int MAX_REQUESTS = 100;
2702 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
2703 NetworkRequest networkRequest = new NetworkRequest.Builder().build();
2704 ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>();
2705 try {
2706 for (int i = 0; i < MAX_REQUESTS; i++) {
2707 NetworkCallback networkCallback = new NetworkCallback();
2708 mCm.requestNetwork(networkRequest, networkCallback);
2709 networkCallbacks.add(networkCallback);
2710 }
2711 fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
2712 } catch (IllegalArgumentException expected) {}
2713 for (NetworkCallback networkCallback : networkCallbacks) {
2714 mCm.unregisterNetworkCallback(networkCallback);
2715 }
2716 networkCallbacks.clear();
2717
2718 try {
2719 for (int i = 0; i < MAX_REQUESTS; i++) {
2720 NetworkCallback networkCallback = new NetworkCallback();
2721 mCm.registerNetworkCallback(networkRequest, networkCallback);
2722 networkCallbacks.add(networkCallback);
2723 }
2724 fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
2725 } catch (IllegalArgumentException expected) {}
2726 for (NetworkCallback networkCallback : networkCallbacks) {
2727 mCm.unregisterNetworkCallback(networkCallback);
2728 }
2729 networkCallbacks.clear();
2730
2731 ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
2732 try {
2733 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
2734 PendingIntent pendingIntent =
2735 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
2736 mCm.requestNetwork(networkRequest, pendingIntent);
2737 pendingIntents.add(pendingIntent);
2738 }
2739 fail("Registering " + MAX_REQUESTS +
2740 " PendingIntent NetworkRequests did not throw exception");
2741 } catch (IllegalArgumentException expected) {}
2742 for (PendingIntent pendingIntent : pendingIntents) {
2743 mCm.unregisterNetworkCallback(pendingIntent);
2744 }
2745 pendingIntents.clear();
2746
2747 try {
2748 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
2749 PendingIntent pendingIntent =
2750 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
2751 mCm.registerNetworkCallback(networkRequest, pendingIntent);
2752 pendingIntents.add(pendingIntent);
2753 }
2754 fail("Registering " + MAX_REQUESTS +
2755 " PendingIntent NetworkCallbacks did not throw exception");
2756 } catch (IllegalArgumentException expected) {}
2757 for (PendingIntent pendingIntent : pendingIntents) {
2758 mCm.unregisterNetworkCallback(pendingIntent);
2759 }
2760 pendingIntents.clear();
2761 mService.waitForIdle(5000);
2762
2763 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed.
2764 for (int i = 0; i < MAX_REQUESTS; i++) {
2765 NetworkCallback networkCallback = new NetworkCallback();
2766 mCm.requestNetwork(networkRequest, networkCallback);
2767 mCm.unregisterNetworkCallback(networkCallback);
2768 }
2769 mService.waitForIdle();
2770 for (int i = 0; i < MAX_REQUESTS; i++) {
2771 NetworkCallback networkCallback = new NetworkCallback();
2772 mCm.registerNetworkCallback(networkRequest, networkCallback);
2773 mCm.unregisterNetworkCallback(networkCallback);
2774 }
2775 mService.waitForIdle();
2776 for (int i = 0; i < MAX_REQUESTS; i++) {
2777 PendingIntent pendingIntent =
2778 PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0);
2779 mCm.requestNetwork(networkRequest, pendingIntent);
2780 mCm.unregisterNetworkCallback(pendingIntent);
2781 }
2782 mService.waitForIdle();
2783 for (int i = 0; i < MAX_REQUESTS; i++) {
2784 PendingIntent pendingIntent =
2785 PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);
2786 mCm.registerNetworkCallback(networkRequest, pendingIntent);
2787 mCm.unregisterNetworkCallback(pendingIntent);
2788 }
2789 }
Jeff Sharkeyfb878b62012-07-26 18:32:30 -07002790}