blob: 88dbd7c6863c58f3c435a987621ecadc0a7cb151 [file] [log] [blame]
The Android Open Source Projectf8057102009-03-15 16:47:16 -07001/*
Scott Sub45eaae2009-04-30 16:53:23 -07002 * Copyright (C) 2009 The Android Open Source Project
The Android Open Source Projectf8057102009-03-15 16:47:16 -07003 *
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 android.net.cts;
18
Jim Guggemos63073b92015-07-21 20:08:24 -060019import android.app.PendingIntent;
Brian Muramatsuce420462011-01-14 17:38:16 -080020import android.content.BroadcastReceiver;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070021import android.content.Context;
Brian Muramatsuce420462011-01-14 17:38:16 -080022import android.content.Intent;
23import android.content.IntentFilter;
24import android.content.pm.PackageManager;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070025import android.net.ConnectivityManager;
Jim Guggemosb30c71f2015-07-14 15:15:04 -060026import android.net.Network;
Jim Guggemosfe560eb2015-07-14 12:03:12 -060027import android.net.NetworkCapabilities;
Robert Greenwalt26a17a52013-03-11 14:32:33 -070028import android.net.NetworkConfig;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070029import android.net.NetworkInfo;
30import android.net.NetworkInfo.DetailedState;
31import android.net.NetworkInfo.State;
Jim Guggemosfe560eb2015-07-14 12:03:12 -060032import android.net.NetworkRequest;
Brian Muramatsuce420462011-01-14 17:38:16 -080033import android.net.wifi.WifiManager;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070034import android.test.AndroidTestCase;
Brian Muramatsuce420462011-01-14 17:38:16 -080035import android.util.Log;
Liangcai Li9f5e3f42014-01-10 16:01:46 +080036import android.os.SystemProperties;
Brian Muramatsuce420462011-01-14 17:38:16 -080037
Paul Jensen67ab58d2014-09-25 10:07:21 -040038import com.android.internal.telephony.PhoneConstants;
39
Robert Greenwalt26a17a52013-03-11 14:32:33 -070040import java.util.ArrayList;
41import java.util.HashMap;
Brian Muramatsu9fc70972011-08-17 14:16:48 -070042import java.util.HashSet;
Robert Greenwalt26a17a52013-03-11 14:32:33 -070043import java.util.List;
Brian Muramatsu9fc70972011-08-17 14:16:48 -070044import java.util.Set;
Brian Muramatsuce420462011-01-14 17:38:16 -080045import java.util.concurrent.CountDownLatch;
46import java.util.concurrent.TimeUnit;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070047
The Android Open Source Projectf8057102009-03-15 16:47:16 -070048public class ConnectivityManagerTest extends AndroidTestCase {
49
Brian Muramatsuce420462011-01-14 17:38:16 -080050 private static final String TAG = ConnectivityManagerTest.class.getSimpleName();
51
52 private static final String FEATURE_ENABLE_HIPRI = "enableHIPRI";
53
Scott Sub45eaae2009-04-30 16:53:23 -070054 public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE;
55 public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070056 private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1
Brian Muramatsua3712c02011-03-31 14:18:43 -070057
Jim Guggemos63073b92015-07-21 20:08:24 -060058 // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent.
59 private static final String NETWORK_CALLBACK_ACTION =
60 "ConnectivityManagerTest.NetworkCallbackAction";
61
Xia Wangf93284c2011-03-04 22:11:29 -080062 // device could have only one interface: data, wifi.
63 private static final int MIN_NUM_NETWORK_TYPES = 1;
Scott Sub45eaae2009-04-30 16:53:23 -070064
The Android Open Source Projectf8057102009-03-15 16:47:16 -070065 private ConnectivityManager mCm;
Brian Muramatsuce420462011-01-14 17:38:16 -080066 private WifiManager mWifiManager;
67 private PackageManager mPackageManager;
Robert Greenwalt26a17a52013-03-11 14:32:33 -070068 private final HashMap<Integer, NetworkConfig> mNetworks =
69 new HashMap<Integer, NetworkConfig>();
The Android Open Source Projectf8057102009-03-15 16:47:16 -070070
71 @Override
72 protected void setUp() throws Exception {
73 super.setUp();
Scott Sub45eaae2009-04-30 16:53:23 -070074 mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
Brian Muramatsuce420462011-01-14 17:38:16 -080075 mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
76 mPackageManager = getContext().getPackageManager();
The Android Open Source Projectf8057102009-03-15 16:47:16 -070077
Johan Redestigbcb89bc2013-10-30 14:14:58 +010078 // Get com.android.internal.R.array.networkAttributes
79 int resId = getContext().getResources().getIdentifier("networkAttributes", "array", "android");
80 String[] naStrings = getContext().getResources().getStringArray(resId);
Liangcai Li9f5e3f42014-01-10 16:01:46 +080081 //TODO: What is the "correct" way to determine if this is a wifi only device?
82 boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
Robert Greenwalt26a17a52013-03-11 14:32:33 -070083 for (String naString : naStrings) {
84 try {
85 NetworkConfig n = new NetworkConfig(naString);
Liangcai Li9f5e3f42014-01-10 16:01:46 +080086 if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
87 continue;
88 }
Robert Greenwalt26a17a52013-03-11 14:32:33 -070089 mNetworks.put(n.type, n);
90 } catch (Exception e) {}
Xia Wangf93284c2011-03-04 22:11:29 -080091 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -070092 }
93
The Android Open Source Projectf8057102009-03-15 16:47:16 -070094 public void testIsNetworkTypeValid() {
Robert Greenwalt26a17a52013-03-11 14:32:33 -070095 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE));
96 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI));
97 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_MMS));
98 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_SUPL));
99 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_DUN));
100 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_HIPRI));
101 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIMAX));
102 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_BLUETOOTH));
103 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_DUMMY));
104 assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_ETHERNET));
105 assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_FOTA));
106 assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IMS));
107 assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_CBS));
108 assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI_P2P));
Wink Savilleaa9579a2013-08-17 16:47:29 -0700109 assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IA));
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700110 assertFalse(mCm.isNetworkTypeValid(-1));
111 assertTrue(mCm.isNetworkTypeValid(0));
112 assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE));
113 assertFalse(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE+1));
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700114
115 NetworkInfo[] ni = mCm.getAllNetworkInfo();
116
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700117 for (NetworkInfo n: ni) {
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700118 assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType()));
119 }
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700120
121 }
122
123 public void testSetNetworkPreference() {
Paul Jensen67ab58d2014-09-25 10:07:21 -0400124 // getNetworkPreference() and setNetworkPreference() are both deprecated so they do
125 // not preform any action. Verify they are at least still callable.
126 mCm.setNetworkPreference(mCm.getNetworkPreference());
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700127 }
128
129 public void testGetActiveNetworkInfo() {
130 NetworkInfo ni = mCm.getActiveNetworkInfo();
131
Jim Guggemos63073b92015-07-21 20:08:24 -0600132 assertNotNull("You must have an active network connection to complete CTS", ni);
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700133 assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
134 assertTrue(ni.getState() == State.CONNECTED);
135 }
136
Jim Guggemosb30c71f2015-07-14 15:15:04 -0600137 public void testGetActiveNetwork() {
138 Network network = mCm.getActiveNetwork();
Jim Guggemos63073b92015-07-21 20:08:24 -0600139 assertNotNull("You must have an active network connection to complete CTS", network);
Jim Guggemosb30c71f2015-07-14 15:15:04 -0600140
141 NetworkInfo ni = mCm.getNetworkInfo(network);
Jim Guggemos63073b92015-07-21 20:08:24 -0600142 assertNotNull("Network returned from getActiveNetwork was invalid", ni);
143
Jim Guggemosb30c71f2015-07-14 15:15:04 -0600144 // Similar to testGetActiveNetworkInfo above.
145 assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
146 assertTrue(ni.getState() == State.CONNECTED);
147 }
148
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700149 public void testGetNetworkInfo() {
150 for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) {
151 if (isSupported(type)) {
152 NetworkInfo ni = mCm.getNetworkInfo(type);
153 assertTrue("Info shouldn't be null for " + type, ni != null);
154 State state = ni.getState();
155 assertTrue("Bad state for " + type, State.UNKNOWN.ordinal() >= state.ordinal()
156 && state.ordinal() >= State.CONNECTING.ordinal());
157 DetailedState ds = ni.getDetailedState();
158 assertTrue("Bad detailed state for " + type,
159 DetailedState.FAILED.ordinal() >= ds.ordinal()
160 && ds.ordinal() >= DetailedState.IDLE.ordinal());
161 } else {
162 assertNull("Info should be null for " + type, mCm.getNetworkInfo(type));
163 }
164 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700165 }
166
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700167 public void testGetAllNetworkInfo() {
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700168 NetworkInfo[] ni = mCm.getAllNetworkInfo();
Brett Chabotfe5dc4a2009-12-08 19:52:35 -0800169 assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES);
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700170 for (int type = 0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
171 int desiredFoundCount = (isSupported(type) ? 1 : 0);
172 int foundCount = 0;
173 for (NetworkInfo i : ni) {
174 if (i.getType() == type) foundCount++;
175 }
Robert Greenwalt7eda9b72013-04-25 17:08:18 -0700176 if (foundCount != desiredFoundCount) {
177 Log.e(TAG, "failure in testGetAllNetworkInfo. Dump of returned NetworkInfos:");
178 for (NetworkInfo networkInfo : ni) Log.e(TAG, " " + networkInfo);
179 }
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700180 assertTrue("Unexpected foundCount of " + foundCount + " for type " + type,
181 foundCount == desiredFoundCount);
182 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700183 }
184
Lorenzo Colitti86b43e52015-08-06 16:09:55 +0900185 private void assertStartUsingNetworkFeatureUnsupported(int networkType, String feature) {
186 try {
187 mCm.startUsingNetworkFeature(networkType, feature);
188 fail("startUsingNetworkFeature is no longer supported in the current API version");
189 } catch (UnsupportedOperationException expected) {}
190 }
191
192 private void assertStopUsingNetworkFeatureUnsupported(int networkType, String feature) {
193 try {
194 mCm.startUsingNetworkFeature(networkType, feature);
195 fail("stopUsingNetworkFeature is no longer supported in the current API version");
196 } catch (UnsupportedOperationException expected) {}
197 }
198
199 private void assertRequestRouteToHostUnsupported(int networkType, int hostAddress) {
200 try {
201 mCm.requestRouteToHost(networkType, hostAddress);
202 fail("requestRouteToHost is no longer supported in the current API version");
203 } catch (UnsupportedOperationException expected) {}
204 }
205
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700206 public void testStartUsingNetworkFeature() {
207
208 final String invalidateFeature = "invalidateFeature";
The Android Open Source Project7ca56df2009-03-18 17:39:42 -0700209 final String mmsFeature = "enableMMS";
210 final int failureCode = -1;
Paul Jensen67ab58d2014-09-25 10:07:21 -0400211 final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED;
212 final int wifiOnlyStopFailureCode = -1;
The Android Open Source Project7ca56df2009-03-18 17:39:42 -0700213
Lorenzo Colitti86b43e52015-08-06 16:09:55 +0900214 assertStartUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
215 assertStopUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
216 assertStartUsingNetworkFeatureUnsupported(TYPE_WIFI, mmsFeature);
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700217 }
218
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700219 private boolean isSupported(int networkType) {
Erik Klined6d87c72014-12-10 20:22:47 +0900220 // Change-Id I02eb5f22737720095f646f8db5c87fd66da129d6 added VPN support
221 // to all devices directly in software, independent of any external
222 // configuration.
223 return mNetworks.containsKey(networkType) ||
224 (networkType == ConnectivityManager.TYPE_VPN);
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700225 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700226
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700227 public void testIsNetworkSupported() {
228 for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
229 boolean supported = mCm.isNetworkSupported(type);
230 if (isSupported(type)) {
231 assertTrue(supported);
232 } else {
233 assertFalse(supported);
Brett Chabotfe5dc4a2009-12-08 19:52:35 -0800234 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700235 }
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700236 }
237
238 public void testRequestRouteToHost() {
239 for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
Lorenzo Colitti86b43e52015-08-06 16:09:55 +0900240 assertRequestRouteToHostUnsupported(type, HOST_ADDRESS);
Robert Greenwalt26a17a52013-03-11 14:32:33 -0700241 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700242 }
243
Phil Dubach158aa4a2009-06-11 14:02:10 -0700244 public void testTest() {
245 mCm.getBackgroundDataSetting();
246 }
Brian Muramatsuce420462011-01-14 17:38:16 -0800247
Jim Guggemosfe560eb2015-07-14 12:03:12 -0600248 /**
249 * Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to
250 * see if we get a callback for the TRANSPORT_WIFI transport type being available.
251 *
252 * <p>In order to test that a NetworkCallback occurs, we need some change in the network
253 * state (either a transport or capability is now available). The most straightforward is
254 * WiFi. We could add a version that uses the telephony data connection but it's not clear
255 * that it would increase test coverage by much (how many devices have 3G radio but not Wifi?).
256 */
257 public void testRegisterNetworkCallback() {
258 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
Jim Guggemos63073b92015-07-21 20:08:24 -0600259 Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
Jim Guggemosfe560eb2015-07-14 12:03:12 -0600260 return;
261 }
262
263 // We will register for a WIFI network being available or lost.
264 NetworkRequest request = new NetworkRequest.Builder()
265 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
266 .build();
267 TestNetworkCallback callback = new TestNetworkCallback();
268 mCm.registerNetworkCallback(request, callback);
269
270 boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
271
272 try {
273 // Make sure WiFi is connected to an access point to start with.
274 if (!previousWifiEnabledState) {
275 connectToWifi();
276 }
277
278 // Now we should expect to get a network callback about availability of the wifi
279 // network even if it was already connected as a state-based action when the callback
280 // is registered.
281 assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
282 callback.waitForAvailable());
283 } catch (InterruptedException e) {
284 fail("Broadcast receiver or NetworkCallback wait was interrupted.");
285 } finally {
286 mCm.unregisterNetworkCallback(callback);
287
288 // Return WiFI to its original enabled/disabled state.
Jim Guggemos63073b92015-07-21 20:08:24 -0600289 if (!previousWifiEnabledState) {
290 disconnectFromWifi();
291 }
Jim Guggemosfe560eb2015-07-14 12:03:12 -0600292 }
293 }
294
Jim Guggemos63073b92015-07-21 20:08:24 -0600295 /**
296 * Tests both registerNetworkCallback and unregisterNetworkCallback similarly to
297 * {@link #testRegisterNetworkCallback} except that a {@code PendingIntent} is used instead
298 * of a {@code NetworkCallback}.
299 */
300 public void testRegisterNetworkCallback_withPendingIntent() {
301 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
302 Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
303 return;
304 }
305
306 // Create a ConnectivityActionReceiver that has an IntentFilter for our locally defined
307 // action, NETWORK_CALLBACK_ACTION.
308 IntentFilter filter = new IntentFilter();
309 filter.addAction(NETWORK_CALLBACK_ACTION);
310
311 ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
312 ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
313 mContext.registerReceiver(receiver, filter);
314
315 // Create a broadcast PendingIntent for NETWORK_CALLBACK_ACTION.
316 Intent intent = new Intent(NETWORK_CALLBACK_ACTION);
317 PendingIntent pendingIntent = PendingIntent.getBroadcast(
318 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
319
320 // We will register for a WIFI network being available or lost.
321 NetworkRequest request = new NetworkRequest.Builder()
322 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
323 .build();
324 mCm.registerNetworkCallback(request, pendingIntent);
325
326 boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
327
328 try {
329 // Make sure WiFi is connected to an access point to start with.
330 if (!previousWifiEnabledState) {
331 connectToWifi();
332 }
333
334 // Now we expect to get the Intent delivered notifying of the availability of the wifi
335 // network even if it was already connected as a state-based action when the callback
336 // is registered.
337 assertTrue("Did not receive expected Intent " + intent + " for TRANSPORT_WIFI",
338 receiver.waitForState());
339 } catch (InterruptedException e) {
340 fail("Broadcast receiver or NetworkCallback wait was interrupted.");
341 } finally {
342 mCm.unregisterNetworkCallback(pendingIntent);
343 pendingIntent.cancel();
344 mContext.unregisterReceiver(receiver);
345
346 // Return WiFI to its original enabled/disabled state.
347 if (!previousWifiEnabledState) {
348 disconnectFromWifi();
349 }
350 }
351 }
352
353 /** Enable WiFi and wait for it to become connected to a network. */
354 private void connectToWifi() {
355 ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
356 ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
Brian Muramatsuce420462011-01-14 17:38:16 -0800357 IntentFilter filter = new IntentFilter();
358 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
359 mContext.registerReceiver(receiver, filter);
360
Jim Guggemos63073b92015-07-21 20:08:24 -0600361 boolean connected = false;
362 try {
363 assertTrue(mWifiManager.setWifiEnabled(true));
364 connected = receiver.waitForState();
365 } catch (InterruptedException ex) {
366 fail("connectToWifi was interrupted");
367 } finally {
368 mContext.unregisterReceiver(receiver);
369 }
Brian Muramatsuce420462011-01-14 17:38:16 -0800370
Jim Guggemos63073b92015-07-21 20:08:24 -0600371 assertTrue("Wifi must be configured to connect to an access point for this test.",
372 connected);
Brian Muramatsuce420462011-01-14 17:38:16 -0800373 }
374
Jim Guggemos63073b92015-07-21 20:08:24 -0600375 /** Disable WiFi and wait for it to become disconnected from the network. */
376 private void disconnectFromWifi() {
377 ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
378 ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
379 IntentFilter filter = new IntentFilter();
380 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
381 mContext.registerReceiver(receiver, filter);
382
383 boolean disconnected = false;
384 try {
385 assertTrue(mWifiManager.setWifiEnabled(false));
386 disconnected = receiver.waitForState();
387 } catch (InterruptedException ex) {
388 fail("disconnectFromWifi was interrupted");
389 } finally {
390 mContext.unregisterReceiver(receiver);
391 }
392
393 assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected);
394 }
395
396 /**
397 * Receiver that captures the last connectivity change's network type and state. Recognizes
398 * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents.
399 */
Brian Muramatsuce420462011-01-14 17:38:16 -0800400 private class ConnectivityActionReceiver extends BroadcastReceiver {
401
402 private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
403
404 private final int mNetworkType;
Jim Guggemos63073b92015-07-21 20:08:24 -0600405 private final NetworkInfo.State mNetState;
Brian Muramatsuce420462011-01-14 17:38:16 -0800406
Jim Guggemos63073b92015-07-21 20:08:24 -0600407 ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) {
Brian Muramatsuce420462011-01-14 17:38:16 -0800408 mNetworkType = networkType;
Jim Guggemos63073b92015-07-21 20:08:24 -0600409 mNetState = netState;
Brian Muramatsuce420462011-01-14 17:38:16 -0800410 }
411
412 public void onReceive(Context context, Intent intent) {
Jim Guggemos63073b92015-07-21 20:08:24 -0600413 String action = intent.getAction();
414 NetworkInfo networkInfo = null;
415
416 // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable
417 // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is
418 // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo.
419 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
420 networkInfo = intent.getExtras()
421 .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO);
422 assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", networkInfo);
423 } else if (NETWORK_CALLBACK_ACTION.equals(action)) {
424 Network network = intent.getExtras()
425 .getParcelable(ConnectivityManager.EXTRA_NETWORK);
426 assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network);
427 networkInfo = mCm.getNetworkInfo(network);
428 if (networkInfo == null) {
429 // When disconnecting, it seems like we get an intent sent with an invalid
430 // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(),
431 // it is invalid. Ignore these.
432 Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring "
433 + "invalid network");
434 return;
435 }
436 } else {
437 fail("ConnectivityActionReceiver received unxpected intent action: " + action);
438 }
439
440 assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo);
Brian Muramatsuce420462011-01-14 17:38:16 -0800441 int networkType = networkInfo.getType();
442 State networkState = networkInfo.getState();
443 Log.i(TAG, "Network type: " + networkType + " state: " + networkState);
Jim Guggemos63073b92015-07-21 20:08:24 -0600444 if (networkType == mNetworkType && networkInfo.getState() == mNetState) {
Brian Muramatsuce420462011-01-14 17:38:16 -0800445 mReceiveLatch.countDown();
446 }
447 }
448
Jim Guggemos63073b92015-07-21 20:08:24 -0600449 public boolean waitForState() throws InterruptedException {
android-htc-contribute8f2e48a2011-10-05 11:09:36 +0800450 return mReceiveLatch.await(30, TimeUnit.SECONDS);
Brian Muramatsuce420462011-01-14 17:38:16 -0800451 }
452 }
Jim Guggemosfe560eb2015-07-14 12:03:12 -0600453
454 /**
455 * Callback used in testRegisterNetworkCallback that allows caller to block on
456 * {@code onAvailable}.
457 */
Jim Guggemos63073b92015-07-21 20:08:24 -0600458 private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
Jim Guggemosfe560eb2015-07-14 12:03:12 -0600459 private final CountDownLatch mAvailableLatch = new CountDownLatch(1);
460
461 public boolean waitForAvailable() throws InterruptedException {
462 return mAvailableLatch.await(30, TimeUnit.SECONDS);
463 }
464
465 @Override
466 public void onAvailable(Network network) {
467 mAvailableLatch.countDown();
468 }
469 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700470}