The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 1 | /* |
Scott Su | b45eaae | 2009-04-30 16:53:23 -0700 | [diff] [blame] | 2 | * Copyright (C) 2009 The Android Open Source Project |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 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 | |
| 17 | package android.net.cts; |
| 18 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 19 | import android.app.PendingIntent; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 20 | import android.content.BroadcastReceiver; |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 21 | import android.content.Context; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 22 | import android.content.Intent; |
| 23 | import android.content.IntentFilter; |
| 24 | import android.content.pm.PackageManager; |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 25 | import android.net.ConnectivityManager; |
Jim Guggemos | b30c71f | 2015-07-14 15:15:04 -0600 | [diff] [blame] | 26 | import android.net.Network; |
Jim Guggemos | fe560eb | 2015-07-14 12:03:12 -0600 | [diff] [blame] | 27 | import android.net.NetworkCapabilities; |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 28 | import android.net.NetworkConfig; |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 29 | import android.net.NetworkInfo; |
| 30 | import android.net.NetworkInfo.DetailedState; |
| 31 | import android.net.NetworkInfo.State; |
Jim Guggemos | fe560eb | 2015-07-14 12:03:12 -0600 | [diff] [blame] | 32 | import android.net.NetworkRequest; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 33 | import android.net.wifi.WifiManager; |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 34 | import android.test.AndroidTestCase; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 35 | import android.util.Log; |
Liangcai Li | 9f5e3f4 | 2014-01-10 16:01:46 +0800 | [diff] [blame] | 36 | import android.os.SystemProperties; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 37 | |
Paul Jensen | 67ab58d | 2014-09-25 10:07:21 -0400 | [diff] [blame] | 38 | import com.android.internal.telephony.PhoneConstants; |
| 39 | |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 40 | import java.util.ArrayList; |
| 41 | import java.util.HashMap; |
Brian Muramatsu | 9fc7097 | 2011-08-17 14:16:48 -0700 | [diff] [blame] | 42 | import java.util.HashSet; |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 43 | import java.util.List; |
Brian Muramatsu | 9fc7097 | 2011-08-17 14:16:48 -0700 | [diff] [blame] | 44 | import java.util.Set; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 45 | import java.util.concurrent.CountDownLatch; |
| 46 | import java.util.concurrent.TimeUnit; |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 47 | |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 48 | public class ConnectivityManagerTest extends AndroidTestCase { |
| 49 | |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 50 | private static final String TAG = ConnectivityManagerTest.class.getSimpleName(); |
| 51 | |
| 52 | private static final String FEATURE_ENABLE_HIPRI = "enableHIPRI"; |
| 53 | |
Scott Su | b45eaae | 2009-04-30 16:53:23 -0700 | [diff] [blame] | 54 | public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; |
| 55 | public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 56 | private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 |
Brian Muramatsu | a3712c0 | 2011-03-31 14:18:43 -0700 | [diff] [blame] | 57 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 58 | // 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 Wang | f93284c | 2011-03-04 22:11:29 -0800 | [diff] [blame] | 62 | // device could have only one interface: data, wifi. |
| 63 | private static final int MIN_NUM_NETWORK_TYPES = 1; |
Scott Su | b45eaae | 2009-04-30 16:53:23 -0700 | [diff] [blame] | 64 | |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 65 | private ConnectivityManager mCm; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 66 | private WifiManager mWifiManager; |
| 67 | private PackageManager mPackageManager; |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 68 | private final HashMap<Integer, NetworkConfig> mNetworks = |
| 69 | new HashMap<Integer, NetworkConfig>(); |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 70 | |
| 71 | @Override |
| 72 | protected void setUp() throws Exception { |
| 73 | super.setUp(); |
Scott Su | b45eaae | 2009-04-30 16:53:23 -0700 | [diff] [blame] | 74 | mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 75 | mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); |
| 76 | mPackageManager = getContext().getPackageManager(); |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 77 | |
Johan Redestig | bcb89bc | 2013-10-30 14:14:58 +0100 | [diff] [blame] | 78 | // Get com.android.internal.R.array.networkAttributes |
| 79 | int resId = getContext().getResources().getIdentifier("networkAttributes", "array", "android"); |
| 80 | String[] naStrings = getContext().getResources().getStringArray(resId); |
Liangcai Li | 9f5e3f4 | 2014-01-10 16:01:46 +0800 | [diff] [blame] | 81 | //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 Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 83 | for (String naString : naStrings) { |
| 84 | try { |
| 85 | NetworkConfig n = new NetworkConfig(naString); |
Liangcai Li | 9f5e3f4 | 2014-01-10 16:01:46 +0800 | [diff] [blame] | 86 | if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) { |
| 87 | continue; |
| 88 | } |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 89 | mNetworks.put(n.type, n); |
| 90 | } catch (Exception e) {} |
Xia Wang | f93284c | 2011-03-04 22:11:29 -0800 | [diff] [blame] | 91 | } |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 92 | } |
| 93 | |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 94 | public void testIsNetworkTypeValid() { |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 95 | 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 Saville | aa9579a | 2013-08-17 16:47:29 -0700 | [diff] [blame] | 109 | assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IA)); |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 110 | 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 Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 114 | |
| 115 | NetworkInfo[] ni = mCm.getAllNetworkInfo(); |
| 116 | |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 117 | for (NetworkInfo n: ni) { |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 118 | assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType())); |
| 119 | } |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 120 | |
| 121 | } |
| 122 | |
| 123 | public void testSetNetworkPreference() { |
Paul Jensen | 67ab58d | 2014-09-25 10:07:21 -0400 | [diff] [blame] | 124 | // 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 Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 127 | } |
| 128 | |
| 129 | public void testGetActiveNetworkInfo() { |
| 130 | NetworkInfo ni = mCm.getActiveNetworkInfo(); |
| 131 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 132 | assertNotNull("You must have an active network connection to complete CTS", ni); |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 133 | assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType())); |
| 134 | assertTrue(ni.getState() == State.CONNECTED); |
| 135 | } |
| 136 | |
Jim Guggemos | b30c71f | 2015-07-14 15:15:04 -0600 | [diff] [blame] | 137 | public void testGetActiveNetwork() { |
| 138 | Network network = mCm.getActiveNetwork(); |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 139 | assertNotNull("You must have an active network connection to complete CTS", network); |
Jim Guggemos | b30c71f | 2015-07-14 15:15:04 -0600 | [diff] [blame] | 140 | |
| 141 | NetworkInfo ni = mCm.getNetworkInfo(network); |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 142 | assertNotNull("Network returned from getActiveNetwork was invalid", ni); |
| 143 | |
Jim Guggemos | b30c71f | 2015-07-14 15:15:04 -0600 | [diff] [blame] | 144 | // Similar to testGetActiveNetworkInfo above. |
| 145 | assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType())); |
| 146 | assertTrue(ni.getState() == State.CONNECTED); |
| 147 | } |
| 148 | |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 149 | 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 Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 165 | } |
| 166 | |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 167 | public void testGetAllNetworkInfo() { |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 168 | NetworkInfo[] ni = mCm.getAllNetworkInfo(); |
Brett Chabot | fe5dc4a | 2009-12-08 19:52:35 -0800 | [diff] [blame] | 169 | assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES); |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 170 | 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 Greenwalt | 7eda9b7 | 2013-04-25 17:08:18 -0700 | [diff] [blame] | 176 | 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 Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 180 | assertTrue("Unexpected foundCount of " + foundCount + " for type " + type, |
| 181 | foundCount == desiredFoundCount); |
| 182 | } |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 183 | } |
| 184 | |
Lorenzo Colitti | 86b43e5 | 2015-08-06 16:09:55 +0900 | [diff] [blame] | 185 | 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 Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 206 | public void testStartUsingNetworkFeature() { |
| 207 | |
| 208 | final String invalidateFeature = "invalidateFeature"; |
The Android Open Source Project | 7ca56df | 2009-03-18 17:39:42 -0700 | [diff] [blame] | 209 | final String mmsFeature = "enableMMS"; |
| 210 | final int failureCode = -1; |
Paul Jensen | 67ab58d | 2014-09-25 10:07:21 -0400 | [diff] [blame] | 211 | final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED; |
| 212 | final int wifiOnlyStopFailureCode = -1; |
The Android Open Source Project | 7ca56df | 2009-03-18 17:39:42 -0700 | [diff] [blame] | 213 | |
Lorenzo Colitti | 86b43e5 | 2015-08-06 16:09:55 +0900 | [diff] [blame] | 214 | assertStartUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature); |
| 215 | assertStopUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature); |
| 216 | assertStartUsingNetworkFeatureUnsupported(TYPE_WIFI, mmsFeature); |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 217 | } |
| 218 | |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 219 | private boolean isSupported(int networkType) { |
Erik Kline | d6d87c7 | 2014-12-10 20:22:47 +0900 | [diff] [blame] | 220 | // 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 Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 225 | } |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 226 | |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 227 | 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 Chabot | fe5dc4a | 2009-12-08 19:52:35 -0800 | [diff] [blame] | 234 | } |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 235 | } |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | public void testRequestRouteToHost() { |
| 239 | for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) { |
Lorenzo Colitti | 86b43e5 | 2015-08-06 16:09:55 +0900 | [diff] [blame] | 240 | assertRequestRouteToHostUnsupported(type, HOST_ADDRESS); |
Robert Greenwalt | 26a17a5 | 2013-03-11 14:32:33 -0700 | [diff] [blame] | 241 | } |
The Android Open Source Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 242 | } |
| 243 | |
Phil Dubach | 158aa4a | 2009-06-11 14:02:10 -0700 | [diff] [blame] | 244 | public void testTest() { |
| 245 | mCm.getBackgroundDataSetting(); |
| 246 | } |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 247 | |
Jim Guggemos | fe560eb | 2015-07-14 12:03:12 -0600 | [diff] [blame] | 248 | /** |
| 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 Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 259 | Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi"); |
Jim Guggemos | fe560eb | 2015-07-14 12:03:12 -0600 | [diff] [blame] | 260 | 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 Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 289 | if (!previousWifiEnabledState) { |
| 290 | disconnectFromWifi(); |
| 291 | } |
Jim Guggemos | fe560eb | 2015-07-14 12:03:12 -0600 | [diff] [blame] | 292 | } |
| 293 | } |
| 294 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 295 | /** |
| 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 Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 357 | IntentFilter filter = new IntentFilter(); |
| 358 | filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); |
| 359 | mContext.registerReceiver(receiver, filter); |
| 360 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 361 | 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 Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 370 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 371 | assertTrue("Wifi must be configured to connect to an access point for this test.", |
| 372 | connected); |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 373 | } |
| 374 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 375 | /** 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 Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 400 | private class ConnectivityActionReceiver extends BroadcastReceiver { |
| 401 | |
| 402 | private final CountDownLatch mReceiveLatch = new CountDownLatch(1); |
| 403 | |
| 404 | private final int mNetworkType; |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 405 | private final NetworkInfo.State mNetState; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 406 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 407 | ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) { |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 408 | mNetworkType = networkType; |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 409 | mNetState = netState; |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 410 | } |
| 411 | |
| 412 | public void onReceive(Context context, Intent intent) { |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 413 | 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 Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 441 | int networkType = networkInfo.getType(); |
| 442 | State networkState = networkInfo.getState(); |
| 443 | Log.i(TAG, "Network type: " + networkType + " state: " + networkState); |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 444 | if (networkType == mNetworkType && networkInfo.getState() == mNetState) { |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 445 | mReceiveLatch.countDown(); |
| 446 | } |
| 447 | } |
| 448 | |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 449 | public boolean waitForState() throws InterruptedException { |
android-htc-contribute | 8f2e48a | 2011-10-05 11:09:36 +0800 | [diff] [blame] | 450 | return mReceiveLatch.await(30, TimeUnit.SECONDS); |
Brian Muramatsu | ce42046 | 2011-01-14 17:38:16 -0800 | [diff] [blame] | 451 | } |
| 452 | } |
Jim Guggemos | fe560eb | 2015-07-14 12:03:12 -0600 | [diff] [blame] | 453 | |
| 454 | /** |
| 455 | * Callback used in testRegisterNetworkCallback that allows caller to block on |
| 456 | * {@code onAvailable}. |
| 457 | */ |
Jim Guggemos | 63073b9 | 2015-07-21 20:08:24 -0600 | [diff] [blame] | 458 | private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { |
Jim Guggemos | fe560eb | 2015-07-14 12:03:12 -0600 | [diff] [blame] | 459 | 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 Project | f805710 | 2009-03-15 16:47:16 -0700 | [diff] [blame] | 470 | } |