blob: 885e8a74b29074f7b5f75b704ef1bef787630666 [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 Benichic8c10272016-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 Colitti281a17c2016-10-28 12:56:03 +090079import com.android.internal.util.test.BroadcastInterceptingContext;
Lorenzo Colitti7df1a822016-10-28 12:37:38 +090080import com.android.internal.util.test.FakeSettingsProvider;
Paul Jensencf4c2c62015-07-01 14:16:32 -040081import com.android.server.connectivity.NetworkAgentInfo;
Paul Jensend7b6ca92015-05-13 14:05:12 -040082import com.android.server.connectivity.NetworkMonitor;
Paul Jensen232437312016-04-06 09:51:26 -040083import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
Lorenzo Colitti531a3442016-03-01 12:55:58 +090084import com.android.server.net.NetworkPinner;
Paul Jensend7b6ca92015-05-13 14:05:12 -040085
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070086import java.net.InetAddress;
Paul Jensen4e1d3fd2016-04-08 13:56:52 -040087import java.util.ArrayList;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +090088import java.util.Arrays;
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +090089import java.util.Objects;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +090090import java.util.concurrent.CountDownLatch;
Lorenzo Colitti7914ce52015-09-08 13:21:48 +090091import java.util.concurrent.LinkedBlockingQueue;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +090092import java.util.concurrent.TimeUnit;
Robert Greenwalt348e98d2015-06-05 17:55:36 -070093import java.util.concurrent.atomic.AtomicBoolean;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070094
95/**
96 * Tests for {@link ConnectivityService}.
Paul Jensend7b6ca92015-05-13 14:05:12 -040097 *
98 * Build, install and run with:
99 * runtest frameworks-services -c com.android.server.ConnectivityServiceTest
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700100 */
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700101public class ConnectivityServiceTest extends AndroidTestCase {
102 private static final String TAG = "ConnectivityServiceTest";
103
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900104 private static final int TIMEOUT_MS = 500;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900105 private static final int TEST_LINGER_DELAY_MS = 120;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900106
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700107 private BroadcastInterceptingContext mServiceContext;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400108 private WrappedConnectivityService mService;
Lorenzo Colitti531a3442016-03-01 12:55:58 +0900109 private WrappedConnectivityManager mCm;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400110 private MockNetworkAgent mWiFiNetworkAgent;
111 private MockNetworkAgent mCellNetworkAgent;
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900112 private MockNetworkAgent mEthernetNetworkAgent;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700113
Lorenzo Colitti531a3442016-03-01 12:55:58 +0900114 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
115 // do not go through ConnectivityService but talk to netd directly, so they don't automatically
116 // reflect the state of our test ConnectivityService.
117 private class WrappedConnectivityManager extends ConnectivityManager {
118 private Network mFakeBoundNetwork;
119
120 public synchronized boolean bindProcessToNetwork(Network network) {
121 mFakeBoundNetwork = network;
122 return true;
123 }
124
125 public synchronized Network getBoundNetworkForProcess() {
126 return mFakeBoundNetwork;
127 }
128
129 public WrappedConnectivityManager(Context context, ConnectivityService service) {
130 super(context, service);
131 }
132 }
133
Paul Jensend7b6ca92015-05-13 14:05:12 -0400134 private class MockContext extends BroadcastInterceptingContext {
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900135 private final MockContentResolver mContentResolver;
136
Paul Jensend7b6ca92015-05-13 14:05:12 -0400137 MockContext(Context base) {
138 super(base);
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900139 mContentResolver = new MockContentResolver();
140 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Paul Jensend7b6ca92015-05-13 14:05:12 -0400141 }
142
143 @Override
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900144 public Object getSystemService(String name) {
Lorenzo Colitti73b209382016-09-15 22:18:09 +0900145 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
146 if (Context.NOTIFICATION_SERVICE.equals(name)) return mock(NotificationManager.class);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400147 return super.getSystemService(name);
148 }
Lorenzo Colitti6d553f62016-06-05 02:20:29 +0900149
150 @Override
151 public ContentResolver getContentResolver() {
152 return mContentResolver;
153 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400154 }
155
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900156 /**
157 * A subclass of HandlerThread that allows callers to wait for it to become idle. waitForIdle
158 * will return immediately if the handler is already idle.
159 */
160 private class IdleableHandlerThread extends HandlerThread {
161 private IdleHandler mIdleHandler;
162
163 public IdleableHandlerThread(String name) {
164 super(name);
165 }
166
167 public void waitForIdle(int timeoutMs) {
168 final ConditionVariable cv = new ConditionVariable();
169 final MessageQueue queue = getLooper().getQueue();
170
171 synchronized (queue) {
172 if (queue.isIdle()) {
173 return;
174 }
175
176 assertNull("BUG: only one idle handler allowed", mIdleHandler);
177 mIdleHandler = new IdleHandler() {
178 public boolean queueIdle() {
Lorenzo Colitti5eaaf742016-03-02 21:47:42 +0900179 synchronized (queue) {
180 cv.open();
181 mIdleHandler = null;
182 return false; // Remove the handler.
183 }
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900184 }
185 };
186 queue.addIdleHandler(mIdleHandler);
187 }
188
189 if (!cv.block(timeoutMs)) {
190 fail("HandlerThread " + getName() +
191 " did not become idle after " + timeoutMs + " ms");
192 queue.removeIdleHandler(mIdleHandler);
193 }
194 }
195 }
196
197 // Tests that IdleableHandlerThread works as expected.
198 public void testIdleableHandlerThread() {
199 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
200
201 // Tests that waitForIdle returns immediately if the service is already idle.
202 for (int i = 0; i < attempts; i++) {
203 mService.waitForIdle();
204 }
205
206 // Bring up a network that we can use to send messages to ConnectivityService.
207 ConditionVariable cv = waitForConnectivityBroadcasts(1);
208 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
209 mWiFiNetworkAgent.connect(false);
210 waitFor(cv);
211 Network n = mWiFiNetworkAgent.getNetwork();
212 assertNotNull(n);
213
214 // Tests that calling waitForIdle waits for messages to be processed.
215 for (int i = 0; i < attempts; i++) {
216 mWiFiNetworkAgent.setSignalStrength(i);
217 mService.waitForIdle();
218 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
219 }
Hugo Benichic8c10272016-10-17 15:54:51 +0900220 }
221
222 @FlakyTest(tolerance = 3)
223 public void testNotWaitingForIdleCausesRaceConditions() {
224 // Bring up a network that we can use to send messages to ConnectivityService.
225 ConditionVariable cv = waitForConnectivityBroadcasts(1);
226 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
227 mWiFiNetworkAgent.connect(false);
228 waitFor(cv);
229 Network n = mWiFiNetworkAgent.getNetwork();
230 assertNotNull(n);
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900231
232 // Ensure that not calling waitForIdle causes a race condition.
Hugo Benichic8c10272016-10-17 15:54:51 +0900233 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900234 for (int i = 0; i < attempts; i++) {
235 mWiFiNetworkAgent.setSignalStrength(i);
236 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
237 // We hit a race condition, as expected. Pass the test.
238 return;
239 }
240 }
241
242 // No race? There is a bug in this test.
243 fail("expected race condition at least once in " + attempts + " attempts");
244 }
245
Paul Jensend7b6ca92015-05-13 14:05:12 -0400246 private class MockNetworkAgent {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400247 private final WrappedNetworkMonitor mWrappedNetworkMonitor;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400248 private final NetworkInfo mNetworkInfo;
249 private final NetworkCapabilities mNetworkCapabilities;
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900250 private final IdleableHandlerThread mHandlerThread;
Paul Jensene0988542015-06-25 15:30:08 -0400251 private final ConditionVariable mDisconnected = new ConditionVariable();
Paul Jensen232437312016-04-06 09:51:26 -0400252 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
Calvin Onbe96da12016-10-11 15:10:46 -0700253 private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
Paul Jensen3d911462015-06-12 06:40:24 -0400254 private int mScore;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400255 private NetworkAgent mNetworkAgent;
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900256 private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
257 private int mStopKeepaliveError = PacketKeepalive.NO_KEEPALIVE;
258 private Integer mExpectedKeepaliveSlot = null;
Paul Jensen232437312016-04-06 09:51:26 -0400259 // Contains the redirectUrl from networkStatus(). Before reading, wait for
260 // mNetworkStatusReceived.
261 private String mRedirectUrl;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400262
263 MockNetworkAgent(int transport) {
264 final int type = transportToLegacyType(transport);
265 final String typeName = ConnectivityManager.getNetworkTypeName(type);
266 mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
267 mNetworkCapabilities = new NetworkCapabilities();
268 mNetworkCapabilities.addTransportType(transport);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400269 switch (transport) {
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900270 case TRANSPORT_ETHERNET:
271 mScore = 70;
272 break;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400273 case TRANSPORT_WIFI:
Paul Jensen3d911462015-06-12 06:40:24 -0400274 mScore = 60;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400275 break;
276 case TRANSPORT_CELLULAR:
Paul Jensen3d911462015-06-12 06:40:24 -0400277 mScore = 50;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400278 break;
279 default:
280 throw new UnsupportedOperationException("unimplemented network type");
281 }
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900282 mHandlerThread = new IdleableHandlerThread("Mock-" + typeName);
283 mHandlerThread.start();
284 mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
285 "Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
286 new LinkProperties(), mScore, new NetworkMisc()) {
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900287 @Override
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900288 public void unwanted() { mDisconnected.open(); }
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900289
290 @Override
291 public void startPacketKeepalive(Message msg) {
292 int slot = msg.arg1;
293 if (mExpectedKeepaliveSlot != null) {
294 assertEquals((int) mExpectedKeepaliveSlot, slot);
295 }
296 onPacketKeepaliveEvent(slot, mStartKeepaliveError);
297 }
298
299 @Override
300 public void stopPacketKeepalive(Message msg) {
301 onPacketKeepaliveEvent(msg.arg1, mStopKeepaliveError);
302 }
Paul Jensen232437312016-04-06 09:51:26 -0400303
304 @Override
305 public void networkStatus(int status, String redirectUrl) {
306 mRedirectUrl = redirectUrl;
307 mNetworkStatusReceived.open();
308 }
Calvin Onbe96da12016-10-11 15:10:46 -0700309
310 @Override
311 protected void preventAutomaticReconnect() {
312 mPreventReconnectReceived.open();
313 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400314 };
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900315 // Waits for the NetworkAgent to be registered, which includes the creation of the
316 // NetworkMonitor.
317 mService.waitForIdle();
Paul Jensencf4c2c62015-07-01 14:16:32 -0400318 mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor();
Paul Jensen3d911462015-06-12 06:40:24 -0400319 }
320
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900321 public void waitForIdle(int timeoutMs) {
322 mHandlerThread.waitForIdle(timeoutMs);
323 }
324
325 public void waitForIdle() {
326 waitForIdle(TIMEOUT_MS);
327 }
328
Paul Jensen3d911462015-06-12 06:40:24 -0400329 public void adjustScore(int change) {
330 mScore += change;
331 mNetworkAgent.sendNetworkScore(mScore);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400332 }
333
Paul Jensen85cf78e2015-06-25 13:25:07 -0400334 public void addCapability(int capability) {
335 mNetworkCapabilities.addCapability(capability);
336 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
337 }
338
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900339 public void removeCapability(int capability) {
340 mNetworkCapabilities.removeCapability(capability);
341 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
342 }
343
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900344 public void setSignalStrength(int signalStrength) {
345 mNetworkCapabilities.setSignalStrength(signalStrength);
346 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
347 }
348
Paul Jensene0988542015-06-25 15:30:08 -0400349 public void connectWithoutInternet() {
350 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
351 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
352 }
353
Paul Jensend7b6ca92015-05-13 14:05:12 -0400354 /**
Paul Jensene0988542015-06-25 15:30:08 -0400355 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET.
Paul Jensend7b6ca92015-05-13 14:05:12 -0400356 * @param validated Indicate if network should pretend to be validated.
357 */
358 public void connect(boolean validated) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900359 assertEquals("MockNetworkAgents can only be connected once",
360 mNetworkInfo.getDetailedState(), DetailedState.IDLE);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400361 assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET));
362
Paul Jensend7b6ca92015-05-13 14:05:12 -0400363 NetworkCallback callback = null;
364 final ConditionVariable validatedCv = new ConditionVariable();
365 if (validated) {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400366 mWrappedNetworkMonitor.gen204ProbeResult = 204;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400367 NetworkRequest request = new NetworkRequest.Builder()
368 .addTransportType(mNetworkCapabilities.getTransportTypes()[0])
369 .build();
370 callback = new NetworkCallback() {
371 public void onCapabilitiesChanged(Network network,
372 NetworkCapabilities networkCapabilities) {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400373 if (network.equals(getNetwork()) &&
374 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
Paul Jensend7b6ca92015-05-13 14:05:12 -0400375 validatedCv.open();
376 }
377 }
378 };
Paul Jensencf4c2c62015-07-01 14:16:32 -0400379 mCm.registerNetworkCallback(request, callback);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400380 }
Paul Jensencf4c2c62015-07-01 14:16:32 -0400381 addCapability(NET_CAPABILITY_INTERNET);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400382
Paul Jensene0988542015-06-25 15:30:08 -0400383 connectWithoutInternet();
Paul Jensend7b6ca92015-05-13 14:05:12 -0400384
385 if (validated) {
386 // Wait for network to validate.
Paul Jensen3d911462015-06-12 06:40:24 -0400387 waitFor(validatedCv);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400388 mWrappedNetworkMonitor.gen204ProbeResult = 500;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400389 }
390
391 if (callback != null) mCm.unregisterNetworkCallback(callback);
392 }
393
Paul Jensen232437312016-04-06 09:51:26 -0400394 public void connectWithCaptivePortal(String redirectUrl) {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400395 mWrappedNetworkMonitor.gen204ProbeResult = 200;
Paul Jensen232437312016-04-06 09:51:26 -0400396 mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400397 connect(false);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400398 }
399
Paul Jensend7b6ca92015-05-13 14:05:12 -0400400 public void disconnect() {
401 mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
402 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
403 }
404
405 public Network getNetwork() {
406 return new Network(mNetworkAgent.netId);
407 }
Paul Jensene0988542015-06-25 15:30:08 -0400408
Calvin Onbe96da12016-10-11 15:10:46 -0700409 public ConditionVariable getPreventReconnectReceived() {
410 return mPreventReconnectReceived;
411 }
412
Paul Jensene0988542015-06-25 15:30:08 -0400413 public ConditionVariable getDisconnectedCV() {
414 return mDisconnected;
415 }
Paul Jensencf4c2c62015-07-01 14:16:32 -0400416
417 public WrappedNetworkMonitor getWrappedNetworkMonitor() {
418 return mWrappedNetworkMonitor;
419 }
Lorenzo Colitti7914ce52015-09-08 13:21:48 +0900420
421 public void sendLinkProperties(LinkProperties lp) {
422 mNetworkAgent.sendLinkProperties(lp);
423 }
424
425 public void setStartKeepaliveError(int error) {
426 mStartKeepaliveError = error;
427 }
428
429 public void setStopKeepaliveError(int error) {
430 mStopKeepaliveError = error;
431 }
432
433 public void setExpectedKeepaliveSlot(Integer slot) {
434 mExpectedKeepaliveSlot = slot;
435 }
Paul Jensen232437312016-04-06 09:51:26 -0400436
437 public String waitForRedirectUrl() {
438 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
439 return mRedirectUrl;
440 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400441 }
442
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900443 /**
444 * A NetworkFactory that allows tests to wait until any in-flight NetworkRequest add or remove
445 * operations have been processed. Before ConnectivityService can add or remove any requests,
446 * the factory must be told to expect those operations by calling expectAddRequests or
447 * expectRemoveRequests.
448 */
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700449 private static class MockNetworkFactory extends NetworkFactory {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400450 private final ConditionVariable mNetworkStartedCV = new ConditionVariable();
451 private final ConditionVariable mNetworkStoppedCV = new ConditionVariable();
Paul Jensencf4c2c62015-07-01 14:16:32 -0400452 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700453
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900454 // Used to expect that requests be removed or added on a separate thread, without sleeping.
455 // Callers can call either expectAddRequests() or expectRemoveRequests() exactly once, then
456 // cause some other thread to add or remove requests, then call waitForRequests(). We can
457 // either expect requests to be added or removed, but not both, because CountDownLatch can
458 // only count in one direction.
459 private CountDownLatch mExpectations;
460
461 // Whether we are currently expecting requests to be added or removed. Valid only if
462 // mExpectations is non-null.
463 private boolean mExpectingAdditions;
464
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700465 public MockNetworkFactory(Looper looper, Context context, String logTag,
466 NetworkCapabilities filter) {
467 super(looper, context, logTag, filter);
468 }
469
470 public int getMyRequestCount() {
471 return getRequestCount();
472 }
473
474 protected void startNetwork() {
475 mNetworkStarted.set(true);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400476 mNetworkStartedCV.open();
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700477 }
478
479 protected void stopNetwork() {
480 mNetworkStarted.set(false);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400481 mNetworkStoppedCV.open();
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700482 }
483
484 public boolean getMyStartRequested() {
485 return mNetworkStarted.get();
486 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400487
488 public ConditionVariable getNetworkStartedCV() {
489 mNetworkStartedCV.close();
490 return mNetworkStartedCV;
491 }
492
493 public ConditionVariable getNetworkStoppedCV() {
494 mNetworkStoppedCV.close();
495 return mNetworkStoppedCV;
496 }
497
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900498 @Override
499 protected void handleAddRequest(NetworkRequest request, int score) {
500 // If we're expecting anything, we must be expecting additions.
501 if (mExpectations != null && !mExpectingAdditions) {
502 fail("Can't add requests while expecting requests to be removed");
503 }
504
505 // Add the request.
506 super.handleAddRequest(request, score);
507
508 // Reduce the number of request additions we're waiting for.
509 if (mExpectingAdditions) {
510 assertTrue("Added more requests than expected", mExpectations.getCount() > 0);
511 mExpectations.countDown();
512 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400513 }
514
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900515 @Override
516 protected void handleRemoveRequest(NetworkRequest request) {
517 // If we're expecting anything, we must be expecting removals.
518 if (mExpectations != null && mExpectingAdditions) {
519 fail("Can't remove requests while expecting requests to be added");
520 }
521
522 // Remove the request.
523 super.handleRemoveRequest(request);
524
525 // Reduce the number of request removals we're waiting for.
526 if (!mExpectingAdditions) {
527 assertTrue("Removed more requests than expected", mExpectations.getCount() > 0);
528 mExpectations.countDown();
529 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400530 }
531
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900532 private void assertNoExpectations() {
533 if (mExpectations != null) {
534 fail("Can't add expectation, " + mExpectations.getCount() + " already pending");
535 }
Paul Jensen0a2823e2015-06-12 10:31:09 -0400536 }
537
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900538 // Expects that count requests will be added.
539 public void expectAddRequests(final int count) {
540 assertNoExpectations();
541 mExpectingAdditions = true;
542 mExpectations = new CountDownLatch(count);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400543 }
544
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900545 // Expects that count requests will be removed.
546 public void expectRemoveRequests(final int count) {
547 assertNoExpectations();
548 mExpectingAdditions = false;
549 mExpectations = new CountDownLatch(count);
550 }
551
552 // Waits for the expected request additions or removals to happen within a timeout.
553 public void waitForRequests() throws InterruptedException {
554 assertNotNull("Nothing to wait for", mExpectations);
555 mExpectations.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
556 final long count = mExpectations.getCount();
557 final String msg = count + " requests still not " +
558 (mExpectingAdditions ? "added" : "removed") +
559 " after " + TIMEOUT_MS + " ms";
560 assertEquals(msg, 0, count);
561 mExpectations = null;
562 }
563
564 public void waitForNetworkRequests(final int count) throws InterruptedException {
565 waitForRequests();
566 assertEquals(count, getMyRequestCount());
Paul Jensen0a2823e2015-06-12 10:31:09 -0400567 }
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700568 }
569
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900570 private class FakeWakeupMessage extends WakeupMessage {
571 private static final int UNREASONABLY_LONG_WAIT = 1000;
572
573 public FakeWakeupMessage(Context context, Handler handler, String cmdName, int cmd) {
574 super(context, handler, cmdName, cmd);
575 }
576
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900577 public FakeWakeupMessage(Context context, Handler handler, String cmdName, int cmd,
578 int arg1, int arg2, Object obj) {
579 super(context, handler, cmdName, cmd, arg1, arg2, obj);
580 }
581
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900582 @Override
583 public void schedule(long when) {
584 long delayMs = when - SystemClock.elapsedRealtime();
585 if (delayMs < 0) delayMs = 0;
586 if (delayMs > UNREASONABLY_LONG_WAIT) {
587 fail("Attempting to send msg more than " + UNREASONABLY_LONG_WAIT +
588 "ms into the future: " + delayMs);
589 }
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900590 Message msg = mHandler.obtainMessage(mCmd, mArg1, mArg2, mObj);
591 mHandler.sendMessageDelayed(msg, delayMs);
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900592 }
593
594 @Override
595 public void cancel() {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900596 mHandler.removeMessages(mCmd, mObj);
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900597 }
598
599 @Override
600 public void onAlarm() {
601 throw new AssertionError("Should never happen. Update this fake.");
602 }
603 }
604
Paul Jensencf4c2c62015-07-01 14:16:32 -0400605 // NetworkMonitor implementation allowing overriding of Internet connectivity probe result.
606 private class WrappedNetworkMonitor extends NetworkMonitor {
607 // HTTP response code fed back to NetworkMonitor for Internet connectivity probe.
608 public int gen204ProbeResult = 500;
Paul Jensen232437312016-04-06 09:51:26 -0400609 public String gen204ProbeRedirectUrl = null;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400610
611 public WrappedNetworkMonitor(Context context, Handler handler,
Hugo Benichif9fdf872016-07-28 17:53:06 +0900612 NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest,
613 IpConnectivityLog log) {
614 super(context, handler, networkAgentInfo, defaultRequest, log);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400615 }
616
617 @Override
Paul Jensen232437312016-04-06 09:51:26 -0400618 protected CaptivePortalProbeResult isCaptivePortal() {
Calvin Onbe96da12016-10-11 15:10:46 -0700619 if (!mIsCaptivePortalCheckEnabled) { return new CaptivePortalProbeResult(204); }
Hugo Benichid953bf82016-09-27 09:22:35 +0900620 return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl, null);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400621 }
622 }
623
Erik Kline065ab6e2016-10-02 18:02:14 +0900624 private class WrappedAvoidBadWifiTracker extends AvoidBadWifiTracker {
Lorenzo Colitti165c51c2016-09-19 01:00:19 +0900625 public boolean configRestrictsAvoidBadWifi;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400626
Erik Kline065ab6e2016-10-02 18:02:14 +0900627 public WrappedAvoidBadWifiTracker(Context c, Handler h, Runnable r) {
628 super(c, h, r);
629 }
630
631 @Override
632 public boolean configRestrictsAvoidBadWifi() {
633 return configRestrictsAvoidBadWifi;
634 }
635 }
636
637 private class WrappedConnectivityService extends ConnectivityService {
638 public WrappedAvoidBadWifiTracker wrappedAvoidBadWifiTracker;
639 private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
640
Paul Jensend7b6ca92015-05-13 14:05:12 -0400641 public WrappedConnectivityService(Context context, INetworkManagementService netManager,
Hugo Benichif9fdf872016-07-28 17:53:06 +0900642 INetworkStatsService statsService, INetworkPolicyManager policyManager,
643 IpConnectivityLog log) {
644 super(context, netManager, statsService, policyManager, log);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900645 mLingerDelayMs = TEST_LINGER_DELAY_MS;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400646 }
647
648 @Override
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900649 protected HandlerThread createHandlerThread() {
650 return new IdleableHandlerThread("WrappedConnectivityService");
651 }
652
653 @Override
Paul Jensend7b6ca92015-05-13 14:05:12 -0400654 protected int getDefaultTcpRwnd() {
655 // Prevent wrapped ConnectivityService from trying to write to SystemProperties.
656 return 0;
657 }
Paul Jensen67b0b072015-06-10 11:22:17 -0400658
659 @Override
660 protected int reserveNetId() {
661 while (true) {
662 final int netId = super.reserveNetId();
663
664 // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks
665 // can have odd side-effects, like network validations succeeding.
666 final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks();
667 boolean overlaps = false;
668 for (Network network : networks) {
669 if (netId == network.netId) {
670 overlaps = true;
671 break;
672 }
673 }
674 if (overlaps) continue;
675
676 return netId;
677 }
678 }
Paul Jensencf4c2c62015-07-01 14:16:32 -0400679
680 @Override
681 public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
682 NetworkAgentInfo nai, NetworkRequest defaultRequest) {
Hugo Benichif9fdf872016-07-28 17:53:06 +0900683 final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(
684 context, handler, nai, defaultRequest, mock(IpConnectivityLog.class));
Paul Jensencf4c2c62015-07-01 14:16:32 -0400685 mLastCreatedNetworkMonitor = monitor;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400686 return monitor;
687 }
688
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900689 @Override
Erik Kline065ab6e2016-10-02 18:02:14 +0900690 public AvoidBadWifiTracker createAvoidBadWifiTracker(
691 Context c, Handler h, Runnable r) {
692 final WrappedAvoidBadWifiTracker tracker = new WrappedAvoidBadWifiTracker(c, h, r);
693 return tracker;
694 }
695
696 public WrappedAvoidBadWifiTracker getAvoidBadWifiTracker() {
697 return (WrappedAvoidBadWifiTracker) mAvoidBadWifiTracker;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900698 }
699
Lorenzo Colitti165c51c2016-09-19 01:00:19 +0900700 @Override
Erik Kline065ab6e2016-10-02 18:02:14 +0900701 public WakeupMessage makeWakeupMessage(
702 Context context, Handler handler, String cmdName, int cmd, Object obj) {
703 return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj);
Lorenzo Colitti165c51c2016-09-19 01:00:19 +0900704 }
705
Paul Jensencf4c2c62015-07-01 14:16:32 -0400706 public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
707 return mLastCreatedNetworkMonitor;
708 }
709
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900710 public void waitForIdle(int timeoutMs) {
711 ((IdleableHandlerThread) mHandlerThread).waitForIdle(timeoutMs);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400712 }
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900713
714 public void waitForIdle() {
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900715 waitForIdle(TIMEOUT_MS);
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900716 }
Paul Jensend7b6ca92015-05-13 14:05:12 -0400717 }
718
Paul Jensen0a2823e2015-06-12 10:31:09 -0400719 private interface Criteria {
720 public boolean get();
721 }
722
Paul Jensen3d911462015-06-12 06:40:24 -0400723 /**
724 * Wait up to 500ms for {@code criteria.get()} to become true, polling.
725 * Fails if 500ms goes by before {@code criteria.get()} to become true.
726 */
Paul Jensen0a2823e2015-06-12 10:31:09 -0400727 static private void waitFor(Criteria criteria) {
728 int delays = 0;
729 while (!criteria.get()) {
730 try {
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900731 Thread.sleep(50);
Paul Jensen0a2823e2015-06-12 10:31:09 -0400732 } catch (InterruptedException e) {
733 }
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900734 if (++delays == 10) fail();
Paul Jensen0a2823e2015-06-12 10:31:09 -0400735 }
736 }
737
Paul Jensen3d911462015-06-12 06:40:24 -0400738 /**
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900739 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open.
740 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens.
Paul Jensen3d911462015-06-12 06:40:24 -0400741 */
742 static private void waitFor(ConditionVariable conditionVariable) {
Lorenzo Colittiffa390b2015-08-08 01:55:44 +0900743 assertTrue(conditionVariable.block(TIMEOUT_MS));
Paul Jensen3d911462015-06-12 06:40:24 -0400744 }
745
Paul Jensend7b6ca92015-05-13 14:05:12 -0400746 @Override
747 public void setUp() throws Exception {
748 super.setUp();
749
Lorenzo Colitti2c1a2532015-11-27 10:52:10 +0900750 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
751 // http://b/25897652 .
752 if (Looper.myLooper() == null) {
753 Looper.prepare();
754 }
755
Paul Jensend7b6ca92015-05-13 14:05:12 -0400756 mServiceContext = new MockContext(getContext());
Lorenzo Colitti83fa2582015-08-07 12:49:01 +0900757 mService = new WrappedConnectivityService(mServiceContext,
758 mock(INetworkManagementService.class),
759 mock(INetworkStatsService.class),
Hugo Benichif9fdf872016-07-28 17:53:06 +0900760 mock(INetworkPolicyManager.class),
761 mock(IpConnectivityLog.class));
Paul Jensend7b6ca92015-05-13 14:05:12 -0400762
Paul Jensend7b6ca92015-05-13 14:05:12 -0400763 mService.systemReady();
Lorenzo Colitti531a3442016-03-01 12:55:58 +0900764 mCm = new WrappedConnectivityManager(getContext(), mService);
765 mCm.bindProcessToNetwork(null);
Calvin Onbe96da12016-10-11 15:10:46 -0700766
767 // Ensure that the default setting for Captive Portals is used for most tests
768 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400769 }
770
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +0900771 public void tearDown() throws Exception {
Lorenzo Colittie14d49a2016-07-20 21:35:19 +0900772 setMobileDataAlwaysOn(false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +0900773 if (mCellNetworkAgent != null) { mCellNetworkAgent.disconnect(); }
774 if (mWiFiNetworkAgent != null) { mWiFiNetworkAgent.disconnect(); }
775 mCellNetworkAgent = mWiFiNetworkAgent = null;
776 super.tearDown();
777 }
778
Paul Jensend7b6ca92015-05-13 14:05:12 -0400779 private int transportToLegacyType(int transport) {
780 switch (transport) {
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900781 case TRANSPORT_ETHERNET:
782 return TYPE_ETHERNET;
Paul Jensend7b6ca92015-05-13 14:05:12 -0400783 case TRANSPORT_WIFI:
784 return TYPE_WIFI;
785 case TRANSPORT_CELLULAR:
786 return TYPE_MOBILE;
787 default:
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +0900788 throw new IllegalStateException("Unknown transport " + transport);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400789 }
790 }
791
792 private void verifyActiveNetwork(int transport) {
793 // Test getActiveNetworkInfo()
794 assertNotNull(mCm.getActiveNetworkInfo());
795 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType());
796 // Test getActiveNetwork()
797 assertNotNull(mCm.getActiveNetwork());
Robin Leed2baf792016-03-24 12:07:00 +0000798 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid()));
Paul Jensend7b6ca92015-05-13 14:05:12 -0400799 switch (transport) {
800 case TRANSPORT_WIFI:
801 assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
802 break;
803 case TRANSPORT_CELLULAR:
804 assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork());
805 break;
806 default:
807 throw new IllegalStateException("Unknown transport" + transport);
808 }
809 // Test getNetworkInfo(Network)
810 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork()));
811 assertEquals(transportToLegacyType(transport), mCm.getNetworkInfo(mCm.getActiveNetwork()).getType());
812 // Test getNetworkCapabilities(Network)
813 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork()));
814 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport));
815 }
816
817 private void verifyNoNetwork() {
818 // Test getActiveNetworkInfo()
819 assertNull(mCm.getActiveNetworkInfo());
820 // Test getActiveNetwork()
821 assertNull(mCm.getActiveNetwork());
Robin Leed2baf792016-03-24 12:07:00 +0000822 assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
Paul Jensend7b6ca92015-05-13 14:05:12 -0400823 // Test getAllNetworks()
824 assertEquals(0, mCm.getAllNetworks().length);
825 }
826
827 /**
828 * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION
829 * broadcasts are received.
830 */
831 private ConditionVariable waitForConnectivityBroadcasts(final int count) {
832 final ConditionVariable cv = new ConditionVariable();
833 mServiceContext.registerReceiver(new BroadcastReceiver() {
834 private int remaining = count;
835 public void onReceive(Context context, Intent intent) {
836 if (--remaining == 0) {
837 cv.open();
838 mServiceContext.unregisterReceiver(this);
839 }
840 }
841 }, new IntentFilter(CONNECTIVITY_ACTION));
842 return cv;
843 }
844
845 @LargeTest
846 public void testLingering() throws Exception {
Paul Jensend7b6ca92015-05-13 14:05:12 -0400847 verifyNoNetwork();
848 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
849 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
850 assertNull(mCm.getActiveNetworkInfo());
851 assertNull(mCm.getActiveNetwork());
852 // Test bringing up validated cellular.
853 ConditionVariable cv = waitForConnectivityBroadcasts(1);
854 mCellNetworkAgent.connect(true);
Paul Jensen3d911462015-06-12 06:40:24 -0400855 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400856 verifyActiveNetwork(TRANSPORT_CELLULAR);
857 assertEquals(2, mCm.getAllNetworks().length);
858 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
859 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
860 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) ||
861 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork()));
862 // Test bringing up validated WiFi.
863 cv = waitForConnectivityBroadcasts(2);
864 mWiFiNetworkAgent.connect(true);
Paul Jensen3d911462015-06-12 06:40:24 -0400865 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400866 verifyActiveNetwork(TRANSPORT_WIFI);
867 assertEquals(2, mCm.getAllNetworks().length);
868 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
869 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
870 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) ||
871 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork()));
872 // Test cellular linger timeout.
Lorenzo Colittibfecba22016-02-21 01:09:26 +0900873 waitFor(new Criteria() {
874 public boolean get() { return mCm.getAllNetworks().length == 1; } });
Paul Jensend7b6ca92015-05-13 14:05:12 -0400875 verifyActiveNetwork(TRANSPORT_WIFI);
876 assertEquals(1, mCm.getAllNetworks().length);
877 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork());
878 // Test WiFi disconnect.
879 cv = waitForConnectivityBroadcasts(1);
880 mWiFiNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400881 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400882 verifyNoNetwork();
883 }
884
885 @LargeTest
886 public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
887 // Test bringing up unvalidated WiFi
888 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
889 ConditionVariable cv = waitForConnectivityBroadcasts(1);
890 mWiFiNetworkAgent.connect(false);
Paul Jensen3d911462015-06-12 06:40:24 -0400891 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400892 verifyActiveNetwork(TRANSPORT_WIFI);
893 // Test bringing up unvalidated cellular
894 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
895 mCellNetworkAgent.connect(false);
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900896 mService.waitForIdle();
Paul Jensend7b6ca92015-05-13 14:05:12 -0400897 verifyActiveNetwork(TRANSPORT_WIFI);
898 // Test cellular disconnect.
899 mCellNetworkAgent.disconnect();
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900900 mService.waitForIdle();
Paul Jensend7b6ca92015-05-13 14:05:12 -0400901 verifyActiveNetwork(TRANSPORT_WIFI);
902 // Test bringing up validated cellular
903 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
904 cv = waitForConnectivityBroadcasts(2);
905 mCellNetworkAgent.connect(true);
Paul Jensen3d911462015-06-12 06:40:24 -0400906 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400907 verifyActiveNetwork(TRANSPORT_CELLULAR);
908 // Test cellular disconnect.
909 cv = waitForConnectivityBroadcasts(2);
910 mCellNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400911 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400912 verifyActiveNetwork(TRANSPORT_WIFI);
913 // Test WiFi disconnect.
914 cv = waitForConnectivityBroadcasts(1);
915 mWiFiNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400916 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400917 verifyNoNetwork();
918 }
919
920 @LargeTest
921 public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
922 // Test bringing up unvalidated cellular.
923 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
924 ConditionVariable cv = waitForConnectivityBroadcasts(1);
925 mCellNetworkAgent.connect(false);
Paul Jensen3d911462015-06-12 06:40:24 -0400926 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400927 verifyActiveNetwork(TRANSPORT_CELLULAR);
928 // Test bringing up unvalidated WiFi.
929 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
930 cv = waitForConnectivityBroadcasts(2);
931 mWiFiNetworkAgent.connect(false);
Paul Jensen3d911462015-06-12 06:40:24 -0400932 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400933 verifyActiveNetwork(TRANSPORT_WIFI);
934 // Test WiFi disconnect.
935 cv = waitForConnectivityBroadcasts(2);
936 mWiFiNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400937 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400938 verifyActiveNetwork(TRANSPORT_CELLULAR);
939 // Test cellular disconnect.
940 cv = waitForConnectivityBroadcasts(1);
941 mCellNetworkAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -0400942 waitFor(cv);
Paul Jensend7b6ca92015-05-13 14:05:12 -0400943 verifyNoNetwork();
944 }
945
Robert Greenwalt348e98d2015-06-05 17:55:36 -0700946 @LargeTest
Paul Jensene0988542015-06-25 15:30:08 -0400947 public void testUnlingeringDoesNotValidate() throws Exception {
Paul Jensencf4c2c62015-07-01 14:16:32 -0400948 // Test bringing up unvalidated WiFi.
Paul Jensene0988542015-06-25 15:30:08 -0400949 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400950 ConditionVariable cv = waitForConnectivityBroadcasts(1);
951 mWiFiNetworkAgent.connect(false);
Paul Jensene0988542015-06-25 15:30:08 -0400952 waitFor(cv);
953 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400954 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
Paul Jensene0988542015-06-25 15:30:08 -0400955 NET_CAPABILITY_VALIDATED));
Paul Jensencf4c2c62015-07-01 14:16:32 -0400956 // Test bringing up validated cellular.
957 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
Paul Jensene0988542015-06-25 15:30:08 -0400958 cv = waitForConnectivityBroadcasts(2);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400959 mCellNetworkAgent.connect(true);
Paul Jensene0988542015-06-25 15:30:08 -0400960 waitFor(cv);
961 verifyActiveNetwork(TRANSPORT_CELLULAR);
Paul Jensencf4c2c62015-07-01 14:16:32 -0400962 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
963 NET_CAPABILITY_VALIDATED));
964 // Test cellular disconnect.
965 cv = waitForConnectivityBroadcasts(2);
966 mCellNetworkAgent.disconnect();
967 waitFor(cv);
968 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensene0988542015-06-25 15:30:08 -0400969 // Unlingering a network should not cause it to be marked as validated.
Paul Jensencf4c2c62015-07-01 14:16:32 -0400970 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
Paul Jensene0988542015-06-25 15:30:08 -0400971 NET_CAPABILITY_VALIDATED));
972 }
973
974 @LargeTest
Paul Jensen3d911462015-06-12 06:40:24 -0400975 public void testCellularOutscoresWeakWifi() throws Exception {
976 // Test bringing up validated cellular.
977 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
978 ConditionVariable cv = waitForConnectivityBroadcasts(1);
979 mCellNetworkAgent.connect(true);
980 waitFor(cv);
981 verifyActiveNetwork(TRANSPORT_CELLULAR);
982 // Test bringing up validated WiFi.
983 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
984 cv = waitForConnectivityBroadcasts(2);
985 mWiFiNetworkAgent.connect(true);
986 waitFor(cv);
987 verifyActiveNetwork(TRANSPORT_WIFI);
988 // Test WiFi getting really weak.
989 cv = waitForConnectivityBroadcasts(2);
990 mWiFiNetworkAgent.adjustScore(-11);
991 waitFor(cv);
992 verifyActiveNetwork(TRANSPORT_CELLULAR);
993 // Test WiFi restoring signal strength.
994 cv = waitForConnectivityBroadcasts(2);
995 mWiFiNetworkAgent.adjustScore(11);
996 waitFor(cv);
997 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensen3d911462015-06-12 06:40:24 -0400998 }
999
Paul Jensene0988542015-06-25 15:30:08 -04001000 @LargeTest
1001 public void testReapingNetwork() throws Exception {
1002 // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
1003 // Expect it to be torn down immediately because it satisfies no requests.
1004 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1005 ConditionVariable cv = mWiFiNetworkAgent.getDisconnectedCV();
1006 mWiFiNetworkAgent.connectWithoutInternet();
1007 waitFor(cv);
1008 // Test bringing up cellular without NET_CAPABILITY_INTERNET.
1009 // Expect it to be torn down immediately because it satisfies no requests.
1010 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1011 cv = mCellNetworkAgent.getDisconnectedCV();
1012 mCellNetworkAgent.connectWithoutInternet();
1013 waitFor(cv);
1014 // Test bringing up validated WiFi.
1015 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1016 cv = waitForConnectivityBroadcasts(1);
1017 mWiFiNetworkAgent.connect(true);
1018 waitFor(cv);
1019 verifyActiveNetwork(TRANSPORT_WIFI);
1020 // Test bringing up unvalidated cellular.
1021 // Expect it to be torn down because it could never be the highest scoring network
1022 // satisfying the default request even if it validated.
1023 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1024 cv = mCellNetworkAgent.getDisconnectedCV();
1025 mCellNetworkAgent.connect(false);
1026 waitFor(cv);
1027 verifyActiveNetwork(TRANSPORT_WIFI);
1028 cv = mWiFiNetworkAgent.getDisconnectedCV();
1029 mWiFiNetworkAgent.disconnect();
1030 waitFor(cv);
1031 }
1032
1033 @LargeTest
1034 public void testCellularFallback() throws Exception {
1035 // Test bringing up validated cellular.
1036 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1037 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1038 mCellNetworkAgent.connect(true);
1039 waitFor(cv);
1040 verifyActiveNetwork(TRANSPORT_CELLULAR);
1041 // Test bringing up validated WiFi.
1042 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1043 cv = waitForConnectivityBroadcasts(2);
1044 mWiFiNetworkAgent.connect(true);
1045 waitFor(cv);
1046 verifyActiveNetwork(TRANSPORT_WIFI);
1047 // Reevaluate WiFi (it'll instantly fail DNS).
1048 cv = waitForConnectivityBroadcasts(2);
1049 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1050 NET_CAPABILITY_VALIDATED));
1051 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork());
1052 // Should quickly fall back to Cellular.
1053 waitFor(cv);
1054 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1055 NET_CAPABILITY_VALIDATED));
1056 verifyActiveNetwork(TRANSPORT_CELLULAR);
1057 // Reevaluate cellular (it'll instantly fail DNS).
1058 cv = waitForConnectivityBroadcasts(2);
1059 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1060 NET_CAPABILITY_VALIDATED));
1061 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
1062 // Should quickly fall back to WiFi.
1063 waitFor(cv);
1064 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1065 NET_CAPABILITY_VALIDATED));
1066 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
1067 NET_CAPABILITY_VALIDATED));
1068 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensene0988542015-06-25 15:30:08 -04001069 }
1070
1071 @LargeTest
1072 public void testWiFiFallback() throws Exception {
1073 // Test bringing up unvalidated WiFi.
1074 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1075 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1076 mWiFiNetworkAgent.connect(false);
1077 waitFor(cv);
1078 verifyActiveNetwork(TRANSPORT_WIFI);
1079 // Test bringing up validated cellular.
1080 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1081 cv = waitForConnectivityBroadcasts(2);
1082 mCellNetworkAgent.connect(true);
1083 waitFor(cv);
1084 verifyActiveNetwork(TRANSPORT_CELLULAR);
1085 // Reevaluate cellular (it'll instantly fail DNS).
1086 cv = waitForConnectivityBroadcasts(2);
1087 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1088 NET_CAPABILITY_VALIDATED));
1089 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
1090 // Should quickly fall back to WiFi.
1091 waitFor(cv);
1092 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
1093 NET_CAPABILITY_VALIDATED));
1094 verifyActiveNetwork(TRANSPORT_WIFI);
Paul Jensene0988542015-06-25 15:30:08 -04001095 }
1096
Paul Jensen3d911462015-06-12 06:40:24 -04001097 enum CallbackState {
1098 NONE,
1099 AVAILABLE,
Erik Klineacdd6392016-07-07 16:50:58 +09001100 NETWORK_CAPABILITIES,
1101 LINK_PROPERTIES,
Paul Jensen3d911462015-06-12 06:40:24 -04001102 LOSING,
Erik Kline57faba92015-11-25 12:49:38 +09001103 LOST,
1104 UNAVAILABLE
Paul Jensen3d911462015-06-12 06:40:24 -04001105 }
1106
Lorenzo Colitti83fa2582015-08-07 12:49:01 +09001107 /**
1108 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks
1109 * this class receives, by calling expectCallback() exactly once each time a callback is
1110 * received. assertNoCallback may be called at any time.
1111 */
Paul Jensen3d911462015-06-12 06:40:24 -04001112 private class TestNetworkCallback extends NetworkCallback {
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001113 // Chosen to be much less than the linger timeout. This ensures that we can distinguish
1114 // between a LOST callback that arrives immediately and a LOST callback that arrives after
1115 // the linger timeout.
1116 private final static int TIMEOUT_MS = 50;
1117
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001118 private class CallbackInfo {
1119 public final CallbackState state;
1120 public final Network network;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001121 public Object arg;
1122 public CallbackInfo(CallbackState s, Network n, Object o) {
1123 state = s; network = n; arg = o;
1124 }
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001125 public String toString() { return String.format("%s (%s)", state, network); }
1126 public boolean equals(Object o) {
1127 if (!(o instanceof CallbackInfo)) return false;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001128 // Ignore timeMs, since it's unpredictable.
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001129 CallbackInfo other = (CallbackInfo) o;
1130 return state == other.state && Objects.equals(network, other.network);
1131 }
1132 }
1133 private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
1134
Erik Klineacdd6392016-07-07 16:50:58 +09001135 protected void setLastCallback(CallbackState state, Network network, Object o) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001136 mCallbacks.offer(new CallbackInfo(state, network, o));
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001137 }
Paul Jensen3d911462015-06-12 06:40:24 -04001138
Erik Klineacdd6392016-07-07 16:50:58 +09001139 @Override
Paul Jensen3d911462015-06-12 06:40:24 -04001140 public void onAvailable(Network network) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001141 setLastCallback(CallbackState.AVAILABLE, network, null);
Paul Jensen3d911462015-06-12 06:40:24 -04001142 }
1143
Erik Klineacdd6392016-07-07 16:50:58 +09001144 @Override
Erik Kline57faba92015-11-25 12:49:38 +09001145 public void onUnavailable() {
1146 setLastCallback(CallbackState.UNAVAILABLE, null, null);
1147 }
1148
1149 @Override
Paul Jensen3d911462015-06-12 06:40:24 -04001150 public void onLosing(Network network, int maxMsToLive) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001151 setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
Paul Jensen3d911462015-06-12 06:40:24 -04001152 }
1153
Erik Klineacdd6392016-07-07 16:50:58 +09001154 @Override
Paul Jensen3d911462015-06-12 06:40:24 -04001155 public void onLost(Network network) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001156 setLastCallback(CallbackState.LOST, network, null);
1157 }
1158
1159 void expectCallback(CallbackState state, MockNetworkAgent mockAgent, int timeoutMs) {
1160 CallbackInfo expected = new CallbackInfo(
1161 state, (mockAgent != null) ? mockAgent.getNetwork() : null, 0);
1162 CallbackInfo actual;
1163 try {
1164 actual = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS);
1165 assertEquals("Unexpected callback:", expected, actual);
1166 } catch (InterruptedException e) {
1167 fail("Did not receive expected " + expected + " after " + TIMEOUT_MS + "ms");
1168 actual = null; // Or the compiler can't tell it's never used uninitialized.
1169 }
1170 if (state == CallbackState.LOSING) {
1171 String msg = String.format(
1172 "Invalid linger time value %d, must be between %d and %d",
1173 actual.arg, 0, TEST_LINGER_DELAY_MS);
1174 int maxMsToLive = (Integer) actual.arg;
1175 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= TEST_LINGER_DELAY_MS);
1176 }
Erik Klinea2d29402016-03-16 15:31:39 +09001177 }
1178
1179 void expectCallback(CallbackState state, MockNetworkAgent mockAgent) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001180 expectCallback(state, mockAgent, TIMEOUT_MS);
Paul Jensen3d911462015-06-12 06:40:24 -04001181 }
1182
Lorenzo Colitti83fa2582015-08-07 12:49:01 +09001183 void assertNoCallback() {
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001184 mService.waitForIdle();
1185 CallbackInfo c = mCallbacks.peek();
1186 assertNull("Unexpected callback: " + c, c);
1187 }
1188 }
1189
1190 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can
1191 // only be declared in a static or top level type".
1192 static void assertNoCallbacks(TestNetworkCallback ... callbacks) {
1193 for (TestNetworkCallback c : callbacks) {
1194 c.assertNoCallback();
Paul Jensen3d911462015-06-12 06:40:24 -04001195 }
1196 }
1197
1198 @LargeTest
1199 public void testStateChangeNetworkCallbacks() throws Exception {
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001200 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
Paul Jensen3d911462015-06-12 06:40:24 -04001201 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
1202 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001203 final NetworkRequest genericRequest = new NetworkRequest.Builder()
1204 .clearCapabilities().build();
Paul Jensen3d911462015-06-12 06:40:24 -04001205 final NetworkRequest wifiRequest = new NetworkRequest.Builder()
1206 .addTransportType(TRANSPORT_WIFI).build();
1207 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1208 .addTransportType(TRANSPORT_CELLULAR).build();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001209 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001210 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
1211 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
1212
1213 // Test unvalidated networks
Paul Jensen3d911462015-06-12 06:40:24 -04001214 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1215 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1216 mCellNetworkAgent.connect(false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001217 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1218 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001219 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1220 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001221 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001222
Paul Jensen3d911462015-06-12 06:40:24 -04001223 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1224 mCellNetworkAgent.adjustScore(-1);
Lorenzo Colittie58961a2015-08-07 20:17:27 +09001225 mService.waitForIdle();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001226 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001227 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1228
Paul Jensen3d911462015-06-12 06:40:24 -04001229 cv = waitForConnectivityBroadcasts(2);
1230 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1231 mWiFiNetworkAgent.connect(false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001232 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1233 wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001234 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1235 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001236 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001237
Paul Jensen3d911462015-06-12 06:40:24 -04001238 cv = waitForConnectivityBroadcasts(2);
1239 mWiFiNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001240 genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1241 wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colitti83fa2582015-08-07 12:49:01 +09001242 cellNetworkCallback.assertNoCallback();
Paul Jensen3d911462015-06-12 06:40:24 -04001243 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001244 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001245
Paul Jensen3d911462015-06-12 06:40:24 -04001246 cv = waitForConnectivityBroadcasts(1);
1247 mCellNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001248 genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1249 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001250 waitFor(cv);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001251 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001252
1253 // Test validated networks
Paul Jensen3d911462015-06-12 06:40:24 -04001254 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1255 mCellNetworkAgent.connect(true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001256 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1257 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001258 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001259 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001260
Paul Jensen3d911462015-06-12 06:40:24 -04001261 // This should not trigger spurious onAvailable() callbacks, b/21762680.
1262 mCellNetworkAgent.adjustScore(-1);
Lorenzo Colittie58961a2015-08-07 20:17:27 +09001263 mService.waitForIdle();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001264 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001265 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1266
Paul Jensen3d911462015-06-12 06:40:24 -04001267 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1268 mWiFiNetworkAgent.connect(true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001269 genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1270 genericNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1271 wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1272 cellNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Paul Jensen3d911462015-06-12 06:40:24 -04001273 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001274 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001275
Paul Jensen3d911462015-06-12 06:40:24 -04001276 mWiFiNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001277 genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1278 wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1279 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001280
Paul Jensen3d911462015-06-12 06:40:24 -04001281 mCellNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001282 genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1283 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1284 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
Paul Jensen3d911462015-06-12 06:40:24 -04001285 }
1286
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001287 @SmallTest
1288 public void testMultipleLingering() {
1289 NetworkRequest request = new NetworkRequest.Builder()
1290 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED)
1291 .build();
1292 TestNetworkCallback callback = new TestNetworkCallback();
1293 mCm.registerNetworkCallback(request, callback);
1294
1295 TestNetworkCallback defaultCallback = new TestNetworkCallback();
1296 mCm.registerDefaultNetworkCallback(defaultCallback);
1297
1298 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1299 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1300 mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
1301
1302 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1303 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1304 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
1305
1306 mCellNetworkAgent.connect(true);
1307 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1308 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1309 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1310
1311 mWiFiNetworkAgent.connect(true);
1312 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request.
1313 // We then get LOSING when wifi validates and cell is outscored.
1314 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1315 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1316 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1317 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1318
1319 mEthernetNetworkAgent.connect(true);
1320 callback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
1321 callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
1322 defaultCallback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
1323 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1324
1325 mEthernetNetworkAgent.disconnect();
1326 callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1327 defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
1328 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1329
1330 for (int i = 0; i < 4; i++) {
1331 MockNetworkAgent oldNetwork, newNetwork;
1332 if (i % 2 == 0) {
1333 mWiFiNetworkAgent.adjustScore(-15);
1334 oldNetwork = mWiFiNetworkAgent;
1335 newNetwork = mCellNetworkAgent;
1336 } else {
1337 mWiFiNetworkAgent.adjustScore(15);
1338 oldNetwork = mCellNetworkAgent;
1339 newNetwork = mWiFiNetworkAgent;
1340
1341 }
1342 callback.expectCallback(CallbackState.LOSING, oldNetwork);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001343 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no
1344 // longer lingering?
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001345 defaultCallback.expectCallback(CallbackState.AVAILABLE, newNetwork);
1346 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork());
1347 }
1348 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1349
1350 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even
1351 // if the network is still up.
1352 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
1353 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1354
1355 // Wifi no longer satisfies our listen, which is for an unmetered network.
1356 // But because its score is 55, it's still up (and the default network).
1357 defaultCallback.assertNoCallback();
1358 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1359
1360 // Disconnect our test networks.
1361 mWiFiNetworkAgent.disconnect();
1362 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1363 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1364 mCellNetworkAgent.disconnect();
1365 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1366
1367 mCm.unregisterNetworkCallback(callback);
1368 mService.waitForIdle();
1369
1370 // Check that a network is only lingered or torn down if it would not satisfy a request even
1371 // if it validated.
1372 request = new NetworkRequest.Builder().clearCapabilities().build();
1373 callback = new TestNetworkCallback();
1374
1375 mCm.registerNetworkCallback(request, callback);
1376
1377 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1378 mCellNetworkAgent.connect(false); // Score: 10
1379 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1380 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1381 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1382
1383 // Bring up wifi with a score of 20.
1384 // Cell stays up because it would satisfy the default request if it validated.
1385 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1386 mWiFiNetworkAgent.connect(false); // Score: 20
1387 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1388 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1389 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1390
1391 mWiFiNetworkAgent.disconnect();
1392 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1393 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1394 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1395 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1396
1397 // Bring up wifi with a score of 70.
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001398 // Cell is lingered because it would not satisfy any request, even if it validated.
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001399 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1400 mWiFiNetworkAgent.adjustScore(50);
1401 mWiFiNetworkAgent.connect(false); // Score: 70
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001402 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001403 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001404 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1405 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1406
1407 // Tear down wifi.
1408 mWiFiNetworkAgent.disconnect();
1409 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1410 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1411 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1412 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1413
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001414 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but
1415 // it's arguably correct to linger it, since it was the default network before it validated.
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001416 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1417 mWiFiNetworkAgent.connect(true);
1418 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001419 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001420 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1421 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
1422
1423 mWiFiNetworkAgent.disconnect();
1424 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001425 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001426 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1427 mCellNetworkAgent.disconnect();
1428 callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1429 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001430
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001431 // If a network is lingering, and we add and remove a request from it, resume lingering.
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001432 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1433 mCellNetworkAgent.connect(true);
1434 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1435 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1436 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1437 mWiFiNetworkAgent.connect(true);
1438 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1439 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1440 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1441
1442 NetworkRequest cellRequest = new NetworkRequest.Builder()
1443 .addTransportType(TRANSPORT_CELLULAR).build();
1444 NetworkCallback noopCallback = new NetworkCallback();
1445 mCm.requestNetwork(cellRequest, noopCallback);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001446 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer
1447 // lingering?
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001448 mCm.unregisterNetworkCallback(noopCallback);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001449 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001450
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001451 // Similar to the above: lingering can start even after the lingered request is removed.
1452 // Disconnect wifi and switch to cell.
Lorenzo Colitti09e20212016-07-04 16:24:16 +09001453 mWiFiNetworkAgent.disconnect();
1454 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001455 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1456 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1457
1458 // Cell is now the default network. Pin it with a cell-specific request.
1459 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525
1460 mCm.requestNetwork(cellRequest, noopCallback);
1461
1462 // Now connect wifi, and expect it to become the default network.
1463 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1464 mWiFiNetworkAgent.connect(true);
1465 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1466 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1467 // The default request is lingering on cell, but nothing happens to cell, and we send no
1468 // callbacks for it, because it's kept up by cellRequest.
1469 callback.assertNoCallback();
1470 // Now unregister cellRequest and expect cell to start lingering.
1471 mCm.unregisterNetworkCallback(noopCallback);
1472 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1473
1474 // Let linger run its course.
1475 callback.assertNoCallback();
1476 callback.expectCallback(CallbackState.LOST, mCellNetworkAgent,
1477 TEST_LINGER_DELAY_MS /* timeoutMs */);
1478
1479 // Clean up.
1480 mWiFiNetworkAgent.disconnect();
1481 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1482 defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Lorenzo Colitti7369d8d12016-06-28 21:28:28 +09001483
1484 mCm.unregisterNetworkCallback(callback);
1485 mCm.unregisterNetworkCallback(defaultCallback);
1486 }
1487
Paul Jensen85cf78e2015-06-25 13:25:07 -04001488 private void tryNetworkFactoryRequests(int capability) throws Exception {
Paul Jensen487ffe72015-07-24 15:57:11 -04001489 // Verify NOT_RESTRICTED is set appropriately
1490 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
1491 .build().networkCapabilities;
1492 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
1493 capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
1494 capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
Paul Jensenaae613d2015-08-19 11:06:15 -04001495 capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
Paul Jensen487ffe72015-07-24 15:57:11 -04001496 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1497 } else {
1498 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1499 }
1500
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001501 NetworkCapabilities filter = new NetworkCapabilities();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001502 filter.addCapability(capability);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001503 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
1504 handlerThread.start();
Paul Jensen0a2823e2015-06-12 10:31:09 -04001505 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001506 mServiceContext, "testFactory", filter);
1507 testFactory.setScoreFilter(40);
Paul Jensen0a2823e2015-06-12 10:31:09 -04001508 ConditionVariable cv = testFactory.getNetworkStartedCV();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001509 testFactory.expectAddRequests(1);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001510 testFactory.register();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001511 testFactory.waitForNetworkRequests(1);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001512 int expectedRequestCount = 1;
1513 NetworkCallback networkCallback = null;
1514 // For non-INTERNET capabilities we cannot rely on the default request being present, so
1515 // add one.
1516 if (capability != NET_CAPABILITY_INTERNET) {
Paul Jensen85cf78e2015-06-25 13:25:07 -04001517 assertFalse(testFactory.getMyStartRequested());
1518 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
1519 networkCallback = new NetworkCallback();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001520 testFactory.expectAddRequests(1);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001521 mCm.requestNetwork(request, networkCallback);
1522 expectedRequestCount++;
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001523 testFactory.waitForNetworkRequests(expectedRequestCount);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001524 }
Paul Jensen3d911462015-06-12 06:40:24 -04001525 waitFor(cv);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001526 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1527 assertTrue(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001528
Paul Jensen85cf78e2015-06-25 13:25:07 -04001529 // Now bring in a higher scored network.
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001530 MockNetworkAgent testAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001531 // Rather than create a validated network which complicates things by registering it's
1532 // own NetworkRequest during startup, just bump up the score to cancel out the
1533 // unvalidated penalty.
1534 testAgent.adjustScore(40);
1535 cv = testFactory.getNetworkStoppedCV();
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001536
1537 // When testAgent connects, ConnectivityService will re-send us all current requests with
1538 // the new score. There are expectedRequestCount such requests, and we must wait for all of
1539 // them.
1540 testFactory.expectAddRequests(expectedRequestCount);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001541 testAgent.connect(false);
1542 testAgent.addCapability(capability);
Paul Jensen3d911462015-06-12 06:40:24 -04001543 waitFor(cv);
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001544 testFactory.waitForNetworkRequests(expectedRequestCount);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001545 assertFalse(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001546
Paul Jensen85cf78e2015-06-25 13:25:07 -04001547 // Bring in a bunch of requests.
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001548 testFactory.expectAddRequests(10);
1549 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001550 ConnectivityManager.NetworkCallback[] networkCallbacks =
1551 new ConnectivityManager.NetworkCallback[10];
1552 for (int i = 0; i< networkCallbacks.length; i++) {
1553 networkCallbacks[i] = new ConnectivityManager.NetworkCallback();
1554 NetworkRequest.Builder builder = new NetworkRequest.Builder();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001555 builder.addCapability(capability);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001556 mCm.requestNetwork(builder.build(), networkCallbacks[i]);
1557 }
Paul Jensen85cf78e2015-06-25 13:25:07 -04001558 testFactory.waitForNetworkRequests(10 + expectedRequestCount);
1559 assertFalse(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001560
Paul Jensen85cf78e2015-06-25 13:25:07 -04001561 // Remove the requests.
Lorenzo Colittiffa390b2015-08-08 01:55:44 +09001562 testFactory.expectRemoveRequests(10);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001563 for (int i = 0; i < networkCallbacks.length; i++) {
1564 mCm.unregisterNetworkCallback(networkCallbacks[i]);
1565 }
Paul Jensen85cf78e2015-06-25 13:25:07 -04001566 testFactory.waitForNetworkRequests(expectedRequestCount);
1567 assertFalse(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001568
Paul Jensen85cf78e2015-06-25 13:25:07 -04001569 // Drop the higher scored network.
1570 cv = testFactory.getNetworkStartedCV();
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001571 testAgent.disconnect();
Paul Jensen3d911462015-06-12 06:40:24 -04001572 waitFor(cv);
Paul Jensen85cf78e2015-06-25 13:25:07 -04001573 assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
1574 assertTrue(testFactory.getMyStartRequested());
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001575
1576 testFactory.unregister();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001577 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback);
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001578 handlerThread.quit();
1579 }
1580
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001581 @LargeTest
Paul Jensen85cf78e2015-06-25 13:25:07 -04001582 public void testNetworkFactoryRequests() throws Exception {
1583 tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
1584 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
1585 tryNetworkFactoryRequests(NET_CAPABILITY_DUN);
1586 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA);
1587 tryNetworkFactoryRequests(NET_CAPABILITY_IMS);
1588 tryNetworkFactoryRequests(NET_CAPABILITY_CBS);
1589 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P);
1590 tryNetworkFactoryRequests(NET_CAPABILITY_IA);
1591 tryNetworkFactoryRequests(NET_CAPABILITY_RCS);
1592 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP);
1593 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS);
1594 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED);
1595 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET);
1596 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED);
1597 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN);
1598 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
1599 }
1600
1601 @LargeTest
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001602 public void testNoMutableNetworkRequests() throws Exception {
1603 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
1604 NetworkRequest.Builder builder = new NetworkRequest.Builder();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001605 builder.addCapability(NET_CAPABILITY_VALIDATED);
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001606 try {
1607 mCm.requestNetwork(builder.build(), new NetworkCallback());
1608 fail();
1609 } catch (IllegalArgumentException expected) {}
1610 try {
1611 mCm.requestNetwork(builder.build(), pendingIntent);
1612 fail();
1613 } catch (IllegalArgumentException expected) {}
1614 builder = new NetworkRequest.Builder();
Paul Jensen85cf78e2015-06-25 13:25:07 -04001615 builder.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
Paul Jensenbb2e0e92015-06-16 15:11:58 -04001616 try {
1617 mCm.requestNetwork(builder.build(), new NetworkCallback());
1618 fail();
1619 } catch (IllegalArgumentException expected) {}
1620 try {
1621 mCm.requestNetwork(builder.build(), pendingIntent);
1622 fail();
1623 } catch (IllegalArgumentException expected) {}
1624 }
Robert Greenwalt348e98d2015-06-05 17:55:36 -07001625
Paul Jensene0988542015-06-25 15:30:08 -04001626 @LargeTest
1627 public void testMMSonWiFi() throws Exception {
1628 // Test bringing up cellular without MMS NetworkRequest gets reaped
1629 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1630 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1631 ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV();
1632 mCellNetworkAgent.connectWithoutInternet();
1633 waitFor(cv);
1634 waitFor(new Criteria() {
1635 public boolean get() { return mCm.getAllNetworks().length == 0; } });
1636 verifyNoNetwork();
1637 // Test bringing up validated WiFi.
1638 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1639 cv = waitForConnectivityBroadcasts(1);
1640 mWiFiNetworkAgent.connect(true);
1641 waitFor(cv);
1642 verifyActiveNetwork(TRANSPORT_WIFI);
1643 // Register MMS NetworkRequest
1644 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1645 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1646 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1647 mCm.requestNetwork(builder.build(), networkCallback);
1648 // Test bringing up unvalidated cellular with MMS
1649 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1650 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
Paul Jensene0988542015-06-25 15:30:08 -04001651 mCellNetworkAgent.connectWithoutInternet();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001652 networkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Paul Jensene0988542015-06-25 15:30:08 -04001653 verifyActiveNetwork(TRANSPORT_WIFI);
1654 // Test releasing NetworkRequest disconnects cellular with MMS
1655 cv = mCellNetworkAgent.getDisconnectedCV();
1656 mCm.unregisterNetworkCallback(networkCallback);
1657 waitFor(cv);
1658 verifyActiveNetwork(TRANSPORT_WIFI);
1659 }
1660
1661 @LargeTest
1662 public void testMMSonCell() throws Exception {
1663 // Test bringing up cellular without MMS
1664 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1665 ConditionVariable cv = waitForConnectivityBroadcasts(1);
1666 mCellNetworkAgent.connect(false);
1667 waitFor(cv);
1668 verifyActiveNetwork(TRANSPORT_CELLULAR);
1669 // Register MMS NetworkRequest
1670 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1671 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1672 final TestNetworkCallback networkCallback = new TestNetworkCallback();
1673 mCm.requestNetwork(builder.build(), networkCallback);
1674 // Test bringing up MMS cellular network
Paul Jensene0988542015-06-25 15:30:08 -04001675 MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1676 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1677 mmsNetworkAgent.connectWithoutInternet();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001678 networkCallback.expectCallback(CallbackState.AVAILABLE, mmsNetworkAgent);
Paul Jensene0988542015-06-25 15:30:08 -04001679 verifyActiveNetwork(TRANSPORT_CELLULAR);
1680 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
1681 cv = mmsNetworkAgent.getDisconnectedCV();
1682 mCm.unregisterNetworkCallback(networkCallback);
1683 waitFor(cv);
1684 verifyActiveNetwork(TRANSPORT_CELLULAR);
1685 }
1686
Paul Jensencf4c2c62015-07-01 14:16:32 -04001687 @LargeTest
1688 public void testCaptivePortal() {
1689 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1690 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1691 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1692 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1693
1694 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1695 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1696 .addCapability(NET_CAPABILITY_VALIDATED).build();
1697 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001698
1699 // Bring up a network with a captive portal.
1700 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001701 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
Paul Jensen232437312016-04-06 09:51:26 -04001702 String firstRedirectUrl = "http://example.com/firstPath";
1703 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001704 captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensen232437312016-04-06 09:51:26 -04001705 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001706
1707 // Take down network.
1708 // Expect onLost callback.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001709 mWiFiNetworkAgent.disconnect();
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001710 captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001711
1712 // Bring up a network with a captive portal.
1713 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001714 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
Paul Jensen232437312016-04-06 09:51:26 -04001715 String secondRedirectUrl = "http://example.com/secondPath";
1716 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001717 captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensen232437312016-04-06 09:51:26 -04001718 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001719
1720 // Make captive portal disappear then revalidate.
1721 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001722 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
1723 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001724 captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001725
1726 // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001727 validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001728
1729 // Break network connectivity.
1730 // Expect NET_CAPABILITY_VALIDATED onLost callback.
Paul Jensencf4c2c62015-07-01 14:16:32 -04001731 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
1732 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001733 validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
Paul Jensencf4c2c62015-07-01 14:16:32 -04001734 }
Lorenzo Colitti7914ce52015-09-08 13:21:48 +09001735
Calvin Onbe96da12016-10-11 15:10:46 -07001736 @LargeTest
1737 public void testAvoidOrIgnoreCaptivePortals() {
1738 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1739 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1740 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1741 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1742
1743 final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1744 final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1745 .addCapability(NET_CAPABILITY_VALIDATED).build();
1746 mCm.registerNetworkCallback(validatedRequest, validatedCallback);
1747
1748 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_AVOID);
1749 // Bring up a network with a captive portal.
1750 // Expect it to fail to connect and not result in any callbacks.
1751 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1752 String firstRedirectUrl = "http://example.com/firstPath";
1753
1754 ConditionVariable disconnectCv = mWiFiNetworkAgent.getDisconnectedCV();
1755 ConditionVariable avoidCv = mWiFiNetworkAgent.getPreventReconnectReceived();
1756 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
1757 waitFor(disconnectCv);
1758 waitFor(avoidCv);
1759
1760 assertNoCallbacks(captivePortalCallback, validatedCallback);
1761
1762 // Now test ignore mode.
1763 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
1764
1765 // Bring up a network with a captive portal.
1766 // Since we're ignoring captive portals, the network will validate.
1767 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1768 String secondRedirectUrl = "http://example.com/secondPath";
1769 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
1770
1771 // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
1772 validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1773 // But there should be no CaptivePortal callback.
1774 captivePortalCallback.assertNoCallback();
1775 }
1776
Etan Cohenddb9ef02015-11-18 10:56:15 -08001777 @SmallTest
1778 public void testInvalidNetworkSpecifier() {
1779 boolean execptionCalled = true;
1780
1781 try {
1782 NetworkRequest.Builder builder = new NetworkRequest.Builder();
1783 builder.setNetworkSpecifier(MATCH_ALL_REQUESTS_NETWORK_SPECIFIER);
1784 execptionCalled = false;
1785 } catch (IllegalArgumentException e) {
1786 // do nothing - should get here
1787 }
1788
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09001789 assertTrue("NetworkRequest builder with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
Etan Cohenddb9ef02015-11-18 10:56:15 -08001790 execptionCalled);
1791
1792 try {
1793 NetworkCapabilities networkCapabilities = new NetworkCapabilities();
1794 networkCapabilities.addTransportType(TRANSPORT_WIFI)
1795 .setNetworkSpecifier(NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER);
1796 mService.requestNetwork(networkCapabilities, null, 0, null,
1797 ConnectivityManager.TYPE_WIFI);
1798 execptionCalled = false;
1799 } catch (IllegalArgumentException e) {
1800 // do nothing - should get here
1801 }
1802
1803 assertTrue("ConnectivityService requestNetwork with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
1804 execptionCalled);
1805 }
1806
Erik Klinea2d29402016-03-16 15:31:39 +09001807 @LargeTest
1808 public void testRegisterDefaultNetworkCallback() throws Exception {
1809 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
1810 mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
1811 defaultNetworkCallback.assertNoCallback();
1812
1813 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up
1814 // whenever Wi-Fi is up. Without this, the mobile network agent is
1815 // reaped before any other activity can take place.
1816 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
1817 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1818 .addTransportType(TRANSPORT_CELLULAR).build();
1819 mCm.requestNetwork(cellRequest, cellNetworkCallback);
1820 cellNetworkCallback.assertNoCallback();
1821
1822 // Bring up cell and expect CALLBACK_AVAILABLE.
1823 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1824 mCellNetworkAgent.connect(true);
1825 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1826 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1827
1828 // Bring up wifi and expect CALLBACK_AVAILABLE.
1829 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1830 mWiFiNetworkAgent.connect(true);
1831 cellNetworkCallback.assertNoCallback();
1832 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1833
1834 // Bring down cell. Expect no default network callback, since it wasn't the default.
1835 mCellNetworkAgent.disconnect();
1836 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1837 defaultNetworkCallback.assertNoCallback();
1838
1839 // Bring up cell. Expect no default network callback, since it won't be the default.
1840 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1841 mCellNetworkAgent.connect(true);
1842 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1843 defaultNetworkCallback.assertNoCallback();
1844
1845 // Bring down wifi. Expect the default network callback to notified of LOST wifi
1846 // followed by AVAILABLE cell.
1847 mWiFiNetworkAgent.disconnect();
1848 cellNetworkCallback.assertNoCallback();
1849 defaultNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1850 defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1851 mCellNetworkAgent.disconnect();
1852 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1853 defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1854 }
1855
Erik Klineacdd6392016-07-07 16:50:58 +09001856 private class TestRequestUpdateCallback extends TestNetworkCallback {
1857 @Override
1858 public void onCapabilitiesChanged(Network network, NetworkCapabilities netCap) {
1859 setLastCallback(CallbackState.NETWORK_CAPABILITIES, network, netCap);
1860 }
1861
1862 @Override
1863 public void onLinkPropertiesChanged(Network network, LinkProperties linkProp) {
1864 setLastCallback(CallbackState.LINK_PROPERTIES, network, linkProp);
1865 }
1866 }
1867
1868 @LargeTest
1869 public void testRequestCallbackUpdates() throws Exception {
1870 // File a network request for mobile.
1871 final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback();
1872 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1873 .addTransportType(TRANSPORT_CELLULAR).build();
1874 mCm.requestNetwork(cellRequest, cellNetworkCallback);
1875
1876 // Bring up the mobile network.
1877 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1878 mCellNetworkAgent.connect(true);
1879
1880 // We should get onAvailable().
1881 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1882 // We should get onCapabilitiesChanged(), when the mobile network successfully validates.
1883 cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
1884 cellNetworkCallback.assertNoCallback();
1885
1886 // Update LinkProperties.
1887 final LinkProperties lp = new LinkProperties();
1888 lp.setInterfaceName("foonet_data0");
1889 mCellNetworkAgent.sendLinkProperties(lp);
1890 // We should get onLinkPropertiesChanged().
1891 cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
1892 cellNetworkCallback.assertNoCallback();
1893
1894 // Register a garden variety default network request.
1895 final TestNetworkCallback dfltNetworkCallback = new TestRequestUpdateCallback();
1896 mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
1897 // Only onAvailable() is called; no other information is delivered.
1898 dfltNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1899 dfltNetworkCallback.assertNoCallback();
1900
1901 // Request a NetworkCapabilities update; only the requesting callback is notified.
1902 mCm.requestNetworkCapabilities(dfltNetworkCallback);
1903 dfltNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
1904 cellNetworkCallback.assertNoCallback();
1905 dfltNetworkCallback.assertNoCallback();
1906
1907 // Request a LinkProperties update; only the requesting callback is notified.
1908 mCm.requestLinkProperties(dfltNetworkCallback);
1909 dfltNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
1910 cellNetworkCallback.assertNoCallback();
1911 dfltNetworkCallback.assertNoCallback();
1912
1913 mCm.unregisterNetworkCallback(dfltNetworkCallback);
1914 mCm.unregisterNetworkCallback(cellNetworkCallback);
1915 }
1916
Calvin Onbe96da12016-10-11 15:10:46 -07001917 private void setCaptivePortalMode(int mode) {
1918 ContentResolver cr = mServiceContext.getContentResolver();
1919 Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
1920 }
1921
Lorenzo Colittie14d49a2016-07-20 21:35:19 +09001922 private void setMobileDataAlwaysOn(boolean enable) {
1923 ContentResolver cr = mServiceContext.getContentResolver();
1924 Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0);
1925 mService.updateMobileDataAlwaysOn();
1926 mService.waitForIdle();
1927 }
1928
1929 private boolean isForegroundNetwork(MockNetworkAgent network) {
1930 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork());
1931 assertNotNull(nc);
1932 return nc.hasCapability(NET_CAPABILITY_FOREGROUND);
1933 }
1934
1935 @SmallTest
1936 public void testBackgroundNetworks() throws Exception {
1937 // Create a background request. We can't do this ourselves because ConnectivityService
1938 // doesn't have an API for it. So just turn on mobile data always on.
1939 setMobileDataAlwaysOn(true);
1940 final NetworkRequest request = new NetworkRequest.Builder().build();
1941 final NetworkRequest fgRequest = new NetworkRequest.Builder()
1942 .addCapability(NET_CAPABILITY_FOREGROUND).build();
1943 final TestNetworkCallback callback = new TestNetworkCallback();
1944 final TestNetworkCallback fgCallback = new TestNetworkCallback();
1945 mCm.registerNetworkCallback(request, callback);
1946 mCm.registerNetworkCallback(fgRequest, fgCallback);
1947
1948 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1949 mCellNetworkAgent.connect(true);
1950 callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1951 fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1952 assertTrue(isForegroundNetwork(mCellNetworkAgent));
1953
1954 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1955 mWiFiNetworkAgent.connect(true);
1956
1957 // When wifi connects, cell lingers.
1958 callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1959 fgCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
1960 callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1961 fgCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
1962 assertTrue(isForegroundNetwork(mCellNetworkAgent));
1963 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
1964
1965 // When lingering is complete, cell is still there but is now in the background.
1966 fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent, TEST_LINGER_DELAY_MS);
1967 callback.assertNoCallback();
1968 assertFalse(isForegroundNetwork(mCellNetworkAgent));
1969 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
1970
1971 // File a cell request and check that cell comes into the foreground.
1972 final NetworkRequest cellRequest = new NetworkRequest.Builder()
1973 .addTransportType(TRANSPORT_CELLULAR).build();
1974 final TestNetworkCallback cellCallback = new TestNetworkCallback();
1975 mCm.requestNetwork(cellRequest, cellCallback);
1976 cellCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1977 fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1978 callback.assertNoCallback(); // Because the network is already up.
1979 assertTrue(isForegroundNetwork(mCellNetworkAgent));
1980 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
1981
1982 // Release the request. The network immediately goes into the background, since it was not
1983 // lingering.
1984 mCm.unregisterNetworkCallback(cellCallback);
1985 fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
1986 callback.assertNoCallback();
1987 assertFalse(isForegroundNetwork(mCellNetworkAgent));
1988 assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
1989
1990 // Disconnect wifi and check that cell is foreground again.
1991 mWiFiNetworkAgent.disconnect();
1992 callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1993 fgCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
1994 fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
1995 assertTrue(isForegroundNetwork(mCellNetworkAgent));
1996
1997 mCm.unregisterNetworkCallback(callback);
1998 mCm.unregisterNetworkCallback(fgCallback);
1999 }
2000
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002001 @SmallTest
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09002002 public void testRequestBenchmark() throws Exception {
2003 // Benchmarks connecting and switching performance in the presence of a large number of
2004 // NetworkRequests.
2005 // 1. File NUM_REQUESTS requests.
2006 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire.
2007 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing
2008 // and NUM_REQUESTS onAvailable callbacks to fire.
2009 // See how long it took.
2010 final int NUM_REQUESTS = 90;
2011 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
2012 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS];
2013 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS);
2014 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS);
2015
2016 final int REGISTER_TIME_LIMIT_MS = 100;
2017 long startTime = System.currentTimeMillis();
2018 for (int i = 0; i < NUM_REQUESTS; i++) {
2019 callbacks[i] = new NetworkCallback() {
2020 @Override public void onAvailable(Network n) { availableLatch.countDown(); }
2021 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); }
2022 };
2023 mCm.registerNetworkCallback(request, callbacks[i]);
2024 }
2025 long timeTaken = System.currentTimeMillis() - startTime;
2026 String msg = String.format("Register %d callbacks: %dms, acceptable %dms",
2027 NUM_REQUESTS, timeTaken, REGISTER_TIME_LIMIT_MS);
2028 Log.d(TAG, msg);
2029 assertTrue(msg, timeTaken < REGISTER_TIME_LIMIT_MS);
2030
2031 final int CONNECT_TIME_LIMIT_MS = 30;
2032 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2033 // Don't request that the network validate, because otherwise connect() will block until
2034 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired,
2035 // and we won't actually measure anything.
2036 mCellNetworkAgent.connect(false);
2037 startTime = System.currentTimeMillis();
2038 if (!availableLatch.await(CONNECT_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
2039 fail(String.format("Only dispatched %d/%d onAvailable callbacks in %dms",
2040 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
2041 CONNECT_TIME_LIMIT_MS));
2042 }
2043 timeTaken = System.currentTimeMillis() - startTime;
2044 Log.d(TAG, String.format("Connect, %d callbacks: %dms, acceptable %dms",
2045 NUM_REQUESTS, timeTaken, CONNECT_TIME_LIMIT_MS));
2046
2047 final int SWITCH_TIME_LIMIT_MS = 30;
2048 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2049 // Give wifi a high enough score that we'll linger cell when wifi comes up.
2050 mWiFiNetworkAgent.adjustScore(40);
2051 mWiFiNetworkAgent.connect(false);
2052 startTime = System.currentTimeMillis();
2053 if (!losingLatch.await(SWITCH_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
2054 fail(String.format("Only dispatched %d/%d onLosing callbacks in %dms",
2055 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, SWITCH_TIME_LIMIT_MS));
2056 }
2057 timeTaken = System.currentTimeMillis() - startTime;
2058 Log.d(TAG, String.format("Linger, %d callbacks: %dms, acceptable %dms",
2059 NUM_REQUESTS, timeTaken, SWITCH_TIME_LIMIT_MS));
2060
2061 final int UNREGISTER_TIME_LIMIT_MS = 10;
2062 startTime = System.currentTimeMillis();
2063 for (int i = 0; i < NUM_REQUESTS; i++) {
2064 mCm.unregisterNetworkCallback(callbacks[i]);
2065 }
2066 timeTaken = System.currentTimeMillis() - startTime;
2067 msg = String.format("Unregister %d callbacks: %dms, acceptable %dms",
2068 NUM_REQUESTS, timeTaken, UNREGISTER_TIME_LIMIT_MS);
2069 Log.d(TAG, msg);
2070 assertTrue(msg, timeTaken < UNREGISTER_TIME_LIMIT_MS);
2071 }
2072
2073 @SmallTest
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002074 public void testMobileDataAlwaysOn() throws Exception {
2075 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2076 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2077 .addTransportType(TRANSPORT_CELLULAR).build();
2078 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
2079
2080 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory");
2081 handlerThread.start();
2082 NetworkCapabilities filter = new NetworkCapabilities()
2083 .addTransportType(TRANSPORT_CELLULAR)
2084 .addCapability(NET_CAPABILITY_INTERNET);
2085 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
2086 mServiceContext, "testFactory", filter);
2087 testFactory.setScoreFilter(40);
2088
2089 // Register the factory and expect it to start looking for a network.
2090 testFactory.expectAddRequests(1);
2091 testFactory.register();
2092 testFactory.waitForNetworkRequests(1);
2093 assertTrue(testFactory.getMyStartRequested());
2094
2095 // Bring up wifi. The factory stops looking for a network.
2096 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2097 testFactory.expectAddRequests(2); // Because the default request changes score twice.
2098 mWiFiNetworkAgent.connect(true);
2099 testFactory.waitForNetworkRequests(1);
2100 assertFalse(testFactory.getMyStartRequested());
2101
2102 ContentResolver cr = mServiceContext.getContentResolver();
2103
2104 // Turn on mobile data always on. The factory starts looking again.
2105 testFactory.expectAddRequests(1);
Lorenzo Colittie14d49a2016-07-20 21:35:19 +09002106 setMobileDataAlwaysOn(true);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002107 testFactory.waitForNetworkRequests(2);
2108 assertTrue(testFactory.getMyStartRequested());
2109
2110 // Bring up cell data and check that the factory stops looking.
2111 assertEquals(1, mCm.getAllNetworks().length);
2112 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2113 testFactory.expectAddRequests(2); // Because the cell request changes score twice.
2114 mCellNetworkAgent.connect(true);
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09002115 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002116 testFactory.waitForNetworkRequests(2);
2117 assertFalse(testFactory.getMyStartRequested()); // Because the cell network outscores us.
2118
2119 // Check that cell data stays up.
2120 mService.waitForIdle();
2121 verifyActiveNetwork(TRANSPORT_WIFI);
2122 assertEquals(2, mCm.getAllNetworks().length);
2123
2124 // Turn off mobile data always on and expect the request to disappear...
2125 testFactory.expectRemoveRequests(1);
Lorenzo Colittie14d49a2016-07-20 21:35:19 +09002126 setMobileDataAlwaysOn(false);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002127 testFactory.waitForNetworkRequests(1);
2128
2129 // ... and cell data to be torn down.
Lorenzo Colitti6ee0a922016-06-27 16:44:07 +09002130 cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09002131 assertEquals(1, mCm.getAllNetworks().length);
2132
2133 testFactory.unregister();
2134 mCm.unregisterNetworkCallback(cellNetworkCallback);
2135 handlerThread.quit();
2136 }
2137
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002138 @SmallTest
2139 public void testAvoidBadWifiSetting() throws Exception {
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002140 final ContentResolver cr = mServiceContext.getContentResolver();
Erik Kline065ab6e2016-10-02 18:02:14 +09002141 final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002142 final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
2143
Erik Kline065ab6e2016-10-02 18:02:14 +09002144 tracker.configRestrictsAvoidBadWifi = false;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002145 String[] values = new String[] {null, "0", "1"};
2146 for (int i = 0; i < values.length; i++) {
2147 Settings.Global.putInt(cr, settingName, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002148 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002149 mService.waitForIdle();
2150 String msg = String.format("config=false, setting=%s", values[i]);
2151 assertTrue(msg, mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002152 assertFalse(msg, tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002153 }
2154
Erik Kline065ab6e2016-10-02 18:02:14 +09002155 tracker.configRestrictsAvoidBadWifi = true;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002156
2157 Settings.Global.putInt(cr, settingName, 0);
Erik Kline065ab6e2016-10-02 18:02:14 +09002158 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002159 mService.waitForIdle();
2160 assertFalse(mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002161 assertFalse(tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002162
2163 Settings.Global.putInt(cr, settingName, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002164 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002165 mService.waitForIdle();
2166 assertTrue(mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002167 assertFalse(tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002168
2169 Settings.Global.putString(cr, settingName, null);
Erik Kline065ab6e2016-10-02 18:02:14 +09002170 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002171 mService.waitForIdle();
2172 assertFalse(mService.avoidBadWifi());
Erik Kline065ab6e2016-10-02 18:02:14 +09002173 assertTrue(tracker.shouldNotifyWifiUnvalidated());
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002174 }
2175
2176 @SmallTest
2177 public void testAvoidBadWifi() throws Exception {
Erik Kline065ab6e2016-10-02 18:02:14 +09002178 final ContentResolver cr = mServiceContext.getContentResolver();
2179 final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002180
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002181 // Pretend we're on a carrier that restricts switching away from bad wifi.
Erik Kline065ab6e2016-10-02 18:02:14 +09002182 tracker.configRestrictsAvoidBadWifi = true;
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002183
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002184 // File a request for cell to ensure it doesn't go down.
2185 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
2186 final NetworkRequest cellRequest = new NetworkRequest.Builder()
2187 .addTransportType(TRANSPORT_CELLULAR).build();
2188 mCm.requestNetwork(cellRequest, cellNetworkCallback);
2189
2190 TestNetworkCallback defaultCallback = new TestNetworkCallback();
2191 mCm.registerDefaultNetworkCallback(defaultCallback);
2192
2193 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder()
2194 .addTransportType(TRANSPORT_WIFI)
2195 .addCapability(NET_CAPABILITY_VALIDATED)
2196 .build();
2197 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback();
2198 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback);
2199
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002200 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 0);
Erik Kline065ab6e2016-10-02 18:02:14 +09002201 tracker.reevaluate();
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002202
2203 // Bring up validated cell.
2204 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2205 mCellNetworkAgent.connect(true);
2206 cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2207 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2208 Network cellNetwork = mCellNetworkAgent.getNetwork();
2209
2210 // Bring up validated wifi.
2211 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2212 mWiFiNetworkAgent.connect(true);
2213 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2214 validatedWifiCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2215 Network wifiNetwork = mWiFiNetworkAgent.getNetwork();
2216
2217 // Fail validation on wifi.
2218 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
2219 mCm.reportNetworkConnectivity(wifiNetwork, false);
2220 validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2221
2222 // Because avoid bad wifi is off, we don't switch to cellular.
2223 defaultCallback.assertNoCallback();
2224 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2225 NET_CAPABILITY_VALIDATED));
2226 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2227 NET_CAPABILITY_VALIDATED));
2228 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2229
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002230 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect
2231 // that we switch back to cell.
Erik Kline065ab6e2016-10-02 18:02:14 +09002232 tracker.configRestrictsAvoidBadWifi = false;
2233 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002234 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2235 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2236
2237 // Switch back to a restrictive carrier.
Erik Kline065ab6e2016-10-02 18:02:14 +09002238 tracker.configRestrictsAvoidBadWifi = true;
2239 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002240 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2241 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2242
2243 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell.
2244 mCm.setAvoidUnvalidated(wifiNetwork);
2245 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2246 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2247 NET_CAPABILITY_VALIDATED));
2248 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2249 NET_CAPABILITY_VALIDATED));
2250 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2251
2252 // Disconnect and reconnect wifi to clear the one-time switch above.
2253 mWiFiNetworkAgent.disconnect();
2254 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2255 mWiFiNetworkAgent.connect(true);
2256 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2257 validatedWifiCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2258 wifiNetwork = mWiFiNetworkAgent.getNetwork();
2259
2260 // Fail validation on wifi and expect the dialog to appear.
2261 mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
2262 mCm.reportNetworkConnectivity(wifiNetwork, false);
2263 validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
2264
2265 // Simulate the user selecting "switch" and checking the don't ask again checkbox.
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002266 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002267 tracker.reevaluate();
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002268
2269 // We now switch to cell.
2270 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2271 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
2272 NET_CAPABILITY_VALIDATED));
2273 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
2274 NET_CAPABILITY_VALIDATED));
2275 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2276
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002277 // Simulate the user turning the cellular fallback setting off and then on.
2278 // We switch to wifi and then to cell.
2279 Settings.Global.putString(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
Erik Kline065ab6e2016-10-02 18:02:14 +09002280 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002281 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2282 assertEquals(mCm.getActiveNetwork(), wifiNetwork);
2283 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
Erik Kline065ab6e2016-10-02 18:02:14 +09002284 tracker.reevaluate();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09002285 defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
2286 assertEquals(mCm.getActiveNetwork(), cellNetwork);
2287
Lorenzo Colitti73b209382016-09-15 22:18:09 +09002288 // If cell goes down, we switch to wifi.
2289 mCellNetworkAgent.disconnect();
2290 defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
2291 defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2292 validatedWifiCallback.assertNoCallback();
2293
2294 mCm.unregisterNetworkCallback(cellNetworkCallback);
2295 mCm.unregisterNetworkCallback(validatedWifiCallback);
2296 mCm.unregisterNetworkCallback(defaultCallback);
2297 }
2298
Erik Kline57faba92015-11-25 12:49:38 +09002299 /**
2300 * Validate that a satisfied network request does not trigger onUnavailable() once the
2301 * time-out period expires.
2302 */
2303 @SmallTest
2304 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
2305 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2306 NetworkCapabilities.TRANSPORT_WIFI).build();
2307 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2308 mCm.requestNetwork(nr, networkCallback, 10);
2309
2310 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2311 mWiFiNetworkAgent.connect(false);
2312 networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
2313
2314 // pass timeout and validate that UNAVAILABLE is not called
2315 try {
2316 Thread.sleep(15);
2317 } catch (InterruptedException e) {
2318 }
2319 networkCallback.assertNoCallback();
2320 }
2321
2322 /**
2323 * Validate that when a time-out is specified for a network request the onUnavailable()
2324 * callback is called when time-out expires. Then validate that if network request is
2325 * (somehow) satisfied - the callback isn't called later.
2326 */
2327 @SmallTest
2328 public void testTimedoutNetworkRequest() {
2329 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2330 NetworkCapabilities.TRANSPORT_WIFI).build();
2331 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2332 mCm.requestNetwork(nr, networkCallback, 10);
2333
2334 // pass timeout and validate that UNAVAILABLE is called
2335 networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
2336
2337 // create a network satisfying request - validate that request not triggered
2338 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2339 mWiFiNetworkAgent.connect(false);
2340 networkCallback.assertNoCallback();
2341 }
2342
2343 /**
2344 * Validate that when a network request is unregistered (cancelled) the time-out for that
2345 * request doesn't trigger the onUnavailable() callback.
2346 */
2347 @SmallTest
2348 public void testTimedoutAfterUnregisteredNetworkRequest() {
2349 NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
2350 NetworkCapabilities.TRANSPORT_WIFI).build();
2351 final TestNetworkCallback networkCallback = new TestNetworkCallback();
2352 mCm.requestNetwork(nr, networkCallback, 10);
2353
2354 // remove request
2355 mCm.unregisterNetworkCallback(networkCallback);
2356
2357 // pass timeout and validate that no callbacks
2358 // Note: doesn't validate that nothing called from CS since even if called the CM already
2359 // unregisters the callback and won't pass it through!
2360 try {
2361 Thread.sleep(15);
2362 } catch (InterruptedException e) {
2363 }
2364 networkCallback.assertNoCallback();
2365
2366 // create a network satisfying request - validate that request not triggered
2367 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2368 mWiFiNetworkAgent.connect(false);
2369 networkCallback.assertNoCallback();
2370 }
2371
Lorenzo Colitti7914ce52015-09-08 13:21:48 +09002372 private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
2373
2374 public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
2375
2376 private class CallbackValue {
2377 public CallbackType callbackType;
2378 public int error;
2379
2380 public CallbackValue(CallbackType type) {
2381 this.callbackType = type;
2382 this.error = PacketKeepalive.SUCCESS;
2383 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR);
2384 }
2385
2386 public CallbackValue(CallbackType type, int error) {
2387 this.callbackType = type;
2388 this.error = error;
2389 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR);
2390 }
2391
2392 @Override
2393 public boolean equals(Object o) {
2394 return o instanceof CallbackValue &&
2395 this.callbackType == ((CallbackValue) o).callbackType &&
2396 this.error == ((CallbackValue) o).error;
2397 }
2398
2399 @Override
2400 public String toString() {
2401 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error);
2402 }
2403 }
2404
2405 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>();
2406
2407 @Override
2408 public void onStarted() {
2409 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED));
2410 }
2411
2412 @Override
2413 public void onStopped() {
2414 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED));
2415 }
2416
2417 @Override
2418 public void onError(int error) {
2419 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
2420 }
2421
2422 private void expectCallback(CallbackValue callbackValue) {
2423 try {
2424 assertEquals(
2425 callbackValue,
2426 mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
2427 } catch (InterruptedException e) {
2428 fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
2429 }
2430 }
2431
2432 public void expectStarted() {
2433 expectCallback(new CallbackValue(CallbackType.ON_STARTED));
2434 }
2435
2436 public void expectStopped() {
2437 expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
2438 }
2439
2440 public void expectError(int error) {
2441 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
2442 }
2443 }
2444
2445 private Network connectKeepaliveNetwork(LinkProperties lp) {
2446 // Ensure the network is disconnected before we do anything.
2447 if (mWiFiNetworkAgent != null) {
2448 assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
2449 }
2450
2451 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2452 ConditionVariable cv = waitForConnectivityBroadcasts(1);
2453 mWiFiNetworkAgent.connect(true);
2454 waitFor(cv);
2455 verifyActiveNetwork(TRANSPORT_WIFI);
2456 mWiFiNetworkAgent.sendLinkProperties(lp);
2457 mService.waitForIdle();
2458 return mWiFiNetworkAgent.getNetwork();
2459 }
2460
2461 public void testPacketKeepalives() throws Exception {
2462 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
2463 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
2464 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
2465 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
2466 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888");
2467
2468 LinkProperties lp = new LinkProperties();
2469 lp.setInterfaceName("wlan12");
2470 lp.addLinkAddress(new LinkAddress(myIPv6, 64));
2471 lp.addLinkAddress(new LinkAddress(myIPv4, 25));
2472 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234")));
2473 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
2474
2475 Network notMyNet = new Network(61234);
2476 Network myNet = connectKeepaliveNetwork(lp);
2477
2478 TestKeepaliveCallback callback = new TestKeepaliveCallback();
2479 PacketKeepalive ka;
2480
2481 // Attempt to start keepalives with invalid parameters and check for errors.
2482 ka = mCm.startNattKeepalive(notMyNet, 25, callback, myIPv4, 1234, dstIPv4);
2483 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
2484
2485 ka = mCm.startNattKeepalive(myNet, 19, callback, notMyIPv4, 1234, dstIPv4);
2486 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL);
2487
2488 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 1234, dstIPv6);
2489 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2490
2491 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv4);
2492 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2493
2494 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv6);
2495 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); // NAT-T is IPv4-only.
2496
2497 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
2498 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
2499
2500 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
2501 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
2502
2503 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2504 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
2505
2506 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2507 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
2508
2509 // Check that a started keepalive can be stopped.
2510 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
2511 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2512 callback.expectStarted();
2513 mWiFiNetworkAgent.setStopKeepaliveError(PacketKeepalive.SUCCESS);
2514 ka.stop();
2515 callback.expectStopped();
2516
2517 // Check that deleting the IP address stops the keepalive.
2518 LinkProperties bogusLp = new LinkProperties(lp);
2519 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2520 callback.expectStarted();
2521 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25));
2522 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25));
2523 mWiFiNetworkAgent.sendLinkProperties(bogusLp);
2524 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
2525 mWiFiNetworkAgent.sendLinkProperties(lp);
2526
2527 // Check that a started keepalive is stopped correctly when the network disconnects.
2528 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2529 callback.expectStarted();
2530 mWiFiNetworkAgent.disconnect();
2531 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
2532
2533 // ... and that stopping it after that has no adverse effects.
2534 assertNull(mCm.getNetworkCapabilities(myNet));
2535 ka.stop();
2536
2537 // Reconnect.
2538 myNet = connectKeepaliveNetwork(lp);
2539 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
2540
2541 // Check things work as expected when the keepalive is stopped and the network disconnects.
2542 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2543 callback.expectStarted();
2544 ka.stop();
2545 mWiFiNetworkAgent.disconnect();
2546 mService.waitForIdle();
2547 callback.expectStopped();
2548
2549 // Reconnect.
2550 myNet = connectKeepaliveNetwork(lp);
2551 mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
2552
2553 // Check that keepalive slots start from 1 and increment. The first one gets slot 1.
2554 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
2555 ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
2556 callback.expectStarted();
2557
2558 // The second one gets slot 2.
2559 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
2560 TestKeepaliveCallback callback2 = new TestKeepaliveCallback();
2561 PacketKeepalive ka2 = mCm.startNattKeepalive(myNet, 25, callback2, myIPv4, 6789, dstIPv4);
2562 callback2.expectStarted();
2563
2564 // Now stop the first one and create a third. This also gets slot 1.
2565 ka.stop();
2566 callback.expectStopped();
2567
2568 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
2569 TestKeepaliveCallback callback3 = new TestKeepaliveCallback();
2570 PacketKeepalive ka3 = mCm.startNattKeepalive(myNet, 25, callback3, myIPv4, 9876, dstIPv4);
2571 callback3.expectStarted();
2572
2573 ka2.stop();
2574 callback2.expectStopped();
2575
2576 ka3.stop();
2577 callback3.expectStopped();
2578 }
Udam Sainib7c24872016-01-04 12:16:14 -08002579
2580 @SmallTest
2581 public void testGetCaptivePortalServerUrl() throws Exception {
2582 String url = mCm.getCaptivePortalServerUrl();
2583 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url);
2584 }
Lorenzo Colitti531a3442016-03-01 12:55:58 +09002585
2586 private static class TestNetworkPinner extends NetworkPinner {
2587 public static boolean awaitPin(int timeoutMs) {
2588 synchronized(sLock) {
2589 if (sNetwork == null) {
2590 try {
2591 sLock.wait(timeoutMs);
2592 } catch (InterruptedException e) {}
2593 }
2594 return sNetwork != null;
2595 }
2596 }
2597
2598 public static boolean awaitUnpin(int timeoutMs) {
2599 synchronized(sLock) {
2600 if (sNetwork != null) {
2601 try {
2602 sLock.wait(timeoutMs);
2603 } catch (InterruptedException e) {}
2604 }
2605 return sNetwork == null;
2606 }
2607 }
2608 }
2609
2610 private void assertPinnedToWifiWithCellDefault() {
2611 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
2612 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
2613 }
2614
2615 private void assertPinnedToWifiWithWifiDefault() {
2616 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess());
2617 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
2618 }
2619
2620 private void assertNotPinnedToWifi() {
2621 assertNull(mCm.getBoundNetworkForProcess());
2622 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
2623 }
2624
2625 @SmallTest
2626 public void testNetworkPinner() {
2627 NetworkRequest wifiRequest = new NetworkRequest.Builder()
2628 .addTransportType(TRANSPORT_WIFI)
2629 .build();
2630 assertNull(mCm.getBoundNetworkForProcess());
2631
2632 TestNetworkPinner.pin(mServiceContext, wifiRequest);
2633 assertNull(mCm.getBoundNetworkForProcess());
2634
2635 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
2636 mCellNetworkAgent.connect(true);
2637 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2638 mWiFiNetworkAgent.connect(false);
2639
2640 // When wi-fi connects, expect to be pinned.
2641 assertTrue(TestNetworkPinner.awaitPin(100));
2642 assertPinnedToWifiWithCellDefault();
2643
2644 // Disconnect and expect the pin to drop.
2645 mWiFiNetworkAgent.disconnect();
2646 assertTrue(TestNetworkPinner.awaitUnpin(100));
2647 assertNotPinnedToWifi();
2648
2649 // Reconnecting does not cause the pin to come back.
2650 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2651 mWiFiNetworkAgent.connect(false);
2652 assertFalse(TestNetworkPinner.awaitPin(100));
2653 assertNotPinnedToWifi();
2654
2655 // Pinning while connected causes the pin to take effect immediately.
2656 TestNetworkPinner.pin(mServiceContext, wifiRequest);
2657 assertTrue(TestNetworkPinner.awaitPin(100));
2658 assertPinnedToWifiWithCellDefault();
2659
2660 // Explicitly unpin and expect to use the default network again.
2661 TestNetworkPinner.unpin();
2662 assertNotPinnedToWifi();
2663
2664 // Disconnect cell and wifi.
2665 ConditionVariable cv = waitForConnectivityBroadcasts(3); // cell down, wifi up, wifi down.
2666 mCellNetworkAgent.disconnect();
2667 mWiFiNetworkAgent.disconnect();
2668 waitFor(cv);
2669
2670 // Pinning takes effect even if the pinned network is the default when the pin is set...
2671 TestNetworkPinner.pin(mServiceContext, wifiRequest);
2672 mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2673 mWiFiNetworkAgent.connect(false);
2674 assertTrue(TestNetworkPinner.awaitPin(100));
2675 assertPinnedToWifiWithWifiDefault();
2676
2677 // ... and is maintained even when that network is no longer the default.
2678 cv = waitForConnectivityBroadcasts(1);
2679 mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
2680 mCellNetworkAgent.connect(true);
2681 waitFor(cv);
2682 assertPinnedToWifiWithCellDefault();
2683 }
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04002684
2685 @SmallTest
2686 public void testNetworkRequestMaximum() {
2687 final int MAX_REQUESTS = 100;
2688 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
2689 NetworkRequest networkRequest = new NetworkRequest.Builder().build();
2690 ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>();
2691 try {
2692 for (int i = 0; i < MAX_REQUESTS; i++) {
2693 NetworkCallback networkCallback = new NetworkCallback();
2694 mCm.requestNetwork(networkRequest, networkCallback);
2695 networkCallbacks.add(networkCallback);
2696 }
2697 fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
2698 } catch (IllegalArgumentException expected) {}
2699 for (NetworkCallback networkCallback : networkCallbacks) {
2700 mCm.unregisterNetworkCallback(networkCallback);
2701 }
2702 networkCallbacks.clear();
2703
2704 try {
2705 for (int i = 0; i < MAX_REQUESTS; i++) {
2706 NetworkCallback networkCallback = new NetworkCallback();
2707 mCm.registerNetworkCallback(networkRequest, networkCallback);
2708 networkCallbacks.add(networkCallback);
2709 }
2710 fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
2711 } catch (IllegalArgumentException expected) {}
2712 for (NetworkCallback networkCallback : networkCallbacks) {
2713 mCm.unregisterNetworkCallback(networkCallback);
2714 }
2715 networkCallbacks.clear();
2716
2717 ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
2718 try {
2719 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
2720 PendingIntent pendingIntent =
2721 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
2722 mCm.requestNetwork(networkRequest, pendingIntent);
2723 pendingIntents.add(pendingIntent);
2724 }
2725 fail("Registering " + MAX_REQUESTS +
2726 " PendingIntent NetworkRequests did not throw exception");
2727 } catch (IllegalArgumentException expected) {}
2728 for (PendingIntent pendingIntent : pendingIntents) {
2729 mCm.unregisterNetworkCallback(pendingIntent);
2730 }
2731 pendingIntents.clear();
2732
2733 try {
2734 for (int i = 0; i < MAX_REQUESTS + 1; i++) {
2735 PendingIntent pendingIntent =
2736 PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
2737 mCm.registerNetworkCallback(networkRequest, pendingIntent);
2738 pendingIntents.add(pendingIntent);
2739 }
2740 fail("Registering " + MAX_REQUESTS +
2741 " PendingIntent NetworkCallbacks did not throw exception");
2742 } catch (IllegalArgumentException expected) {}
2743 for (PendingIntent pendingIntent : pendingIntents) {
2744 mCm.unregisterNetworkCallback(pendingIntent);
2745 }
2746 pendingIntents.clear();
2747 mService.waitForIdle(5000);
2748
2749 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed.
2750 for (int i = 0; i < MAX_REQUESTS; i++) {
2751 NetworkCallback networkCallback = new NetworkCallback();
2752 mCm.requestNetwork(networkRequest, networkCallback);
2753 mCm.unregisterNetworkCallback(networkCallback);
2754 }
2755 mService.waitForIdle();
2756 for (int i = 0; i < MAX_REQUESTS; i++) {
2757 NetworkCallback networkCallback = new NetworkCallback();
2758 mCm.registerNetworkCallback(networkRequest, networkCallback);
2759 mCm.unregisterNetworkCallback(networkCallback);
2760 }
2761 mService.waitForIdle();
2762 for (int i = 0; i < MAX_REQUESTS; i++) {
2763 PendingIntent pendingIntent =
2764 PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0);
2765 mCm.requestNetwork(networkRequest, pendingIntent);
2766 mCm.unregisterNetworkCallback(pendingIntent);
2767 }
2768 mService.waitForIdle();
2769 for (int i = 0; i < MAX_REQUESTS; i++) {
2770 PendingIntent pendingIntent =
2771 PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);
2772 mCm.registerNetworkCallback(networkRequest, pendingIntent);
2773 mCm.unregisterNetworkCallback(pendingIntent);
2774 }
2775 }
Jeff Sharkeyfb878b62012-07-26 18:32:30 -07002776}