1 /* 2 * Copyright (C) 2009 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 17 package android.net.wifi.cts; 18 19 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.net.NetworkInfo; 25 import android.net.wifi.ScanResult; 26 import android.net.wifi.WifiConfiguration; 27 import android.net.wifi.WifiConfiguration.Status; 28 import android.net.wifi.WifiManager; 29 import android.net.wifi.WifiManager.TxPacketCountListener; 30 import android.net.wifi.WifiManager.WifiLock; 31 import android.os.SystemClock; 32 import android.test.AndroidTestCase; 33 import android.util.Log; 34 35 import java.net.HttpURLConnection; 36 import java.net.URL; 37 import java.util.HashSet; 38 import java.util.List; 39 import java.util.Set; 40 import java.util.concurrent.TimeUnit; 41 import java.util.concurrent.atomic.AtomicInteger; 42 43 public class WifiManagerTest extends AndroidTestCase { 44 private static class MySync { 45 int expectedState = STATE_NULL; 46 } 47 48 private WifiManager mWifiManager; 49 private WifiLock mWifiLock; 50 private static MySync mMySync; 51 private List<ScanResult> mScanResults = null; 52 private NetworkInfo mNetworkInfo; 53 54 // Please refer to WifiManager 55 private static final int MIN_RSSI = -100; 56 private static final int MAX_RSSI = -55; 57 58 private static final int STATE_NULL = 0; 59 private static final int STATE_WIFI_CHANGING = 1; 60 private static final int STATE_WIFI_ENABLED = 2; 61 private static final int STATE_WIFI_DISABLED = 3; 62 private static final int STATE_SCANNING = 4; 63 private static final int STATE_SCAN_RESULTS_AVAILABLE = 5; 64 65 private static final String TAG = "WifiManagerTest"; 66 private static final String SSID1 = "\"WifiManagerTest\""; 67 private static final String SSID2 = "\"WifiManagerTestModified\""; 68 private static final int TIMEOUT_MSEC = 6000; 69 private static final int WAIT_MSEC = 60; 70 private static final int DURATION = 10000; 71 private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000; 72 private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; 73 private static final int WIFI_SCAN_TEST_ITERATIONS = 5; 74 75 private IntentFilter mIntentFilter; 76 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 77 @Override 78 public void onReceive(Context context, Intent intent) { 79 final String action = intent.getAction(); 80 if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 81 synchronized (mMySync) { 82 if (mWifiManager.getScanResults() != null) { 83 mScanResults = mWifiManager.getScanResults(); 84 mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; 85 mScanResults = mWifiManager.getScanResults(); 86 mMySync.notifyAll(); 87 } 88 } 89 } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 90 int newState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 91 WifiManager.WIFI_STATE_UNKNOWN); 92 synchronized (mMySync) { 93 if (newState == WifiManager.WIFI_STATE_ENABLED) { 94 Log.d(TAG, "*** New WiFi state is ENABLED ***"); 95 mMySync.expectedState = STATE_WIFI_ENABLED; 96 mMySync.notifyAll(); 97 } else if (newState == WifiManager.WIFI_STATE_DISABLED) { 98 Log.d(TAG, "*** New WiFi state is DISABLED ***"); 99 mMySync.expectedState = STATE_WIFI_DISABLED; 100 mMySync.notifyAll(); 101 } 102 } 103 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 104 synchronized (mMySync) { 105 mNetworkInfo = 106 (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 107 if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) 108 mMySync.notifyAll(); 109 } 110 } 111 } 112 }; 113 114 @Override 115 protected void setUp() throws Exception { 116 super.setUp(); 117 if (!WifiFeature.isWifiSupported(getContext())) { 118 // skip the test if WiFi is not supported 119 return; 120 } 121 mMySync = new MySync(); 122 mIntentFilter = new IntentFilter(); 123 mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 124 mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 125 mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); 126 mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); 127 mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 128 mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); 129 mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); 130 mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); 131 132 mContext.registerReceiver(mReceiver, mIntentFilter); 133 mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); 134 assertNotNull(mWifiManager); 135 mWifiLock = mWifiManager.createWifiLock(TAG); 136 mWifiLock.acquire(); 137 if (!mWifiManager.isWifiEnabled()) 138 setWifiEnabled(true); 139 Thread.sleep(DURATION); 140 assertTrue(mWifiManager.isWifiEnabled()); 141 synchronized (mMySync) { 142 mMySync.expectedState = STATE_NULL; 143 } 144 } 145 146 @Override 147 protected void tearDown() throws Exception { 148 if (!WifiFeature.isWifiSupported(getContext())) { 149 // skip the test if WiFi is not supported 150 super.tearDown(); 151 return; 152 } 153 if (!mWifiManager.isWifiEnabled()) 154 setWifiEnabled(true); 155 mWifiLock.release(); 156 mContext.unregisterReceiver(mReceiver); 157 Thread.sleep(DURATION); 158 super.tearDown(); 159 } 160 161 private void setWifiEnabled(boolean enable) throws Exception { 162 synchronized (mMySync) { 163 assertTrue(mWifiManager.setWifiEnabled(enable)); 164 if (mWifiManager.isWifiEnabled() != enable) { 165 mMySync.expectedState = STATE_WIFI_CHANGING; 166 long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; 167 int expectedState = (enable ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED); 168 while (System.currentTimeMillis() < timeout 169 && mMySync.expectedState != expectedState) 170 mMySync.wait(WAIT_MSEC); 171 } 172 } 173 } 174 175 private void startScan() throws Exception { 176 synchronized (mMySync) { 177 mMySync.expectedState = STATE_SCANNING; 178 assertTrue(mWifiManager.startScan()); 179 long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; 180 while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANNING) 181 mMySync.wait(WAIT_MSEC); 182 } 183 } 184 185 private void connectWifi() throws Exception { 186 synchronized (mMySync) { 187 if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) return; 188 assertTrue(mWifiManager.reconnect()); 189 long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; 190 while (System.currentTimeMillis() < timeout 191 && mNetworkInfo.getState() != NetworkInfo.State.CONNECTED) 192 mMySync.wait(WAIT_MSEC); 193 assertTrue(mNetworkInfo.getState() == NetworkInfo.State.CONNECTED); 194 } 195 } 196 197 private boolean existSSID(String ssid) { 198 for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { 199 if (w.SSID.equals(ssid)) 200 return true; 201 } 202 return false; 203 } 204 205 private int findConfiguredNetworks(String SSID, List<WifiConfiguration> networks) { 206 for (final WifiConfiguration w : networks) { 207 if (w.SSID.equals(SSID)) 208 return networks.indexOf(w); 209 } 210 return -1; 211 } 212 213 private void assertDisableOthers(WifiConfiguration wifiConfiguration, boolean disableOthers) { 214 for (WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { 215 if ((!w.SSID.equals(wifiConfiguration.SSID)) && w.status != Status.CURRENT) { 216 if (disableOthers) { 217 assertEquals(Status.DISABLED, w.status); 218 } 219 } 220 } 221 } 222 223 /** 224 * test point of wifiManager actions: 225 * 1.reconnect 226 * 2.reassociate 227 * 3.disconnect 228 * 4.pingSupplicant 229 * 5.satrtScan 230 */ 231 public void testWifiManagerActions() throws Exception { 232 if (!WifiFeature.isWifiSupported(getContext())) { 233 // skip the test if WiFi is not supported 234 return; 235 } 236 assertTrue(mWifiManager.reconnect()); 237 assertTrue(mWifiManager.reassociate()); 238 assertTrue(mWifiManager.disconnect()); 239 assertTrue(mWifiManager.pingSupplicant()); 240 startScan(); 241 setWifiEnabled(false); 242 Thread.sleep(DURATION); 243 assertTrue(mWifiManager.pingSupplicant() == mWifiManager.isScanAlwaysAvailable()); 244 final String TAG = "Test"; 245 assertNotNull(mWifiManager.createWifiLock(TAG)); 246 assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); 247 } 248 249 /** 250 * test point of wifiManager properties: 251 * 1.enable properties 252 * 2.DhcpInfo properties 253 * 3.wifi state 254 * 4.ConnectionInfo 255 */ 256 public void testWifiManagerProperties() throws Exception { 257 if (!WifiFeature.isWifiSupported(getContext())) { 258 // skip the test if WiFi is not supported 259 return; 260 } 261 setWifiEnabled(true); 262 assertTrue(mWifiManager.isWifiEnabled()); 263 assertNotNull(mWifiManager.getDhcpInfo()); 264 assertEquals(WifiManager.WIFI_STATE_ENABLED, mWifiManager.getWifiState()); 265 mWifiManager.getConnectionInfo(); 266 setWifiEnabled(false); 267 assertFalse(mWifiManager.isWifiEnabled()); 268 } 269 270 /** 271 * Test WiFi scan timestamp - fails when WiFi scan timestamps are inconsistent with 272 * {@link SystemClock#elapsedRealtime()} on device.<p> 273 * To run this test in cts-tradefed: 274 * run cts --class android.net.wifi.cts.WifiManagerTest --method testWifiScanTimestamp 275 */ 276 public void testWifiScanTimestamp() throws Exception { 277 if (!WifiFeature.isWifiSupported(getContext())) { 278 Log.d(TAG, "Skipping test as WiFi is not supported"); 279 return; 280 } 281 if (!mWifiManager.isWifiEnabled()) { 282 setWifiEnabled(true); 283 } 284 // Scan multiple times to make sure scan timestamps increase with device timestamp. 285 for (int i = 0; i < WIFI_SCAN_TEST_ITERATIONS; ++i) { 286 startScan(); 287 // Make sure at least one AP is found. 288 assertFalse("empty scan results!", mScanResults.isEmpty()); 289 long nowMillis = SystemClock.elapsedRealtime(); 290 // Keep track of how many APs are fresh in one scan. 291 int numFreshAps = 0; 292 for (ScanResult result : mScanResults) { 293 long scanTimeMillis = TimeUnit.MICROSECONDS.toMillis(result.timestamp); 294 if (Math.abs(nowMillis - scanTimeMillis) < WIFI_SCAN_TEST_CACHE_DELAY_MILLIS) { 295 numFreshAps++; 296 } 297 } 298 // At least half of the APs in the scan should be fresh. 299 int numTotalAps = mScanResults.size(); 300 String msg = "Stale AP count: " + (numTotalAps - numFreshAps) + ", fresh AP count: " 301 + numFreshAps; 302 assertTrue(msg, numFreshAps * 2 >= mScanResults.size()); 303 if (i < WIFI_SCAN_TEST_ITERATIONS - 1) { 304 // Wait before running next iteration. 305 Thread.sleep(WIFI_SCAN_TEST_INTERVAL_MILLIS); 306 } 307 } 308 } 309 310 /** 311 * test point of wifiManager NetWork: 312 * 1.add NetWork 313 * 2.update NetWork 314 * 3.remove NetWork 315 * 4.enable NetWork 316 * 5.disable NetWork 317 * 6.configured Networks 318 * 7.save configure; 319 */ 320 public void testWifiManagerNetWork() throws Exception { 321 if (!WifiFeature.isWifiSupported(getContext())) { 322 // skip the test if WiFi is not supported 323 return; 324 } 325 326 // store the list of enabled networks, so they can be re-enabled after test completes 327 Set<String> enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); 328 try { 329 WifiConfiguration wifiConfiguration; 330 // add a WifiConfig 331 final int notExist = -1; 332 List<WifiConfiguration> wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); 333 int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); 334 if (notExist != pos) { 335 wifiConfiguration = wifiConfiguredNetworks.get(pos); 336 mWifiManager.removeNetwork(wifiConfiguration.networkId); 337 } 338 pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); 339 assertEquals(notExist, pos); 340 final int size = wifiConfiguredNetworks.size(); 341 342 wifiConfiguration = new WifiConfiguration(); 343 wifiConfiguration.SSID = SSID1; 344 int netId = mWifiManager.addNetwork(wifiConfiguration); 345 assertTrue(existSSID(SSID1)); 346 347 wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); 348 assertEquals(size + 1, wifiConfiguredNetworks.size()); 349 pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); 350 assertTrue(notExist != pos); 351 352 // Enable & disable network 353 boolean disableOthers = false; 354 assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); 355 wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); 356 assertDisableOthers(wifiConfiguration, disableOthers); 357 assertEquals(Status.ENABLED, wifiConfiguration.status); 358 359 assertTrue(mWifiManager.disableNetwork(netId)); 360 wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); 361 assertEquals(Status.DISABLED, wifiConfiguration.status); 362 363 // Update a WifiConfig 364 wifiConfiguration = wifiConfiguredNetworks.get(pos); 365 wifiConfiguration.SSID = SSID2; 366 netId = mWifiManager.updateNetwork(wifiConfiguration); 367 assertFalse(existSSID(SSID1)); 368 assertTrue(existSSID(SSID2)); 369 370 // Remove a WifiConfig 371 assertTrue(mWifiManager.removeNetwork(netId)); 372 assertFalse(mWifiManager.removeNetwork(notExist)); 373 assertFalse(existSSID(SSID1)); 374 assertFalse(existSSID(SSID2)); 375 376 assertTrue(mWifiManager.saveConfiguration()); 377 } finally { 378 reEnableNetworks(enabledSsids, mWifiManager.getConfiguredNetworks()); 379 mWifiManager.saveConfiguration(); 380 } 381 } 382 383 private Set<String> getEnabledNetworks(List<WifiConfiguration> configuredNetworks) { 384 Set<String> ssids = new HashSet<String>(); 385 for (WifiConfiguration wifiConfig : configuredNetworks) { 386 if (Status.ENABLED == wifiConfig.status || Status.CURRENT == wifiConfig.status) { 387 ssids.add(wifiConfig.SSID); 388 Log.i(TAG, String.format("remembering enabled network %s", wifiConfig.SSID)); 389 } 390 } 391 return ssids; 392 } 393 394 private void reEnableNetworks(Set<String> enabledSsids, 395 List<WifiConfiguration> configuredNetworks) { 396 for (WifiConfiguration wifiConfig : configuredNetworks) { 397 if (enabledSsids.contains(wifiConfig.SSID)) { 398 mWifiManager.enableNetwork(wifiConfig.networkId, false); 399 Log.i(TAG, String.format("re-enabling network %s", wifiConfig.SSID)); 400 } 401 } 402 } 403 404 public void testSignal() { 405 if (!WifiFeature.isWifiSupported(getContext())) { 406 // skip the test if WiFi is not supported 407 return; 408 } 409 final int numLevels = 9; 410 int expectLevel = 0; 411 assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels)); 412 assertEquals(numLevels - 1, WifiManager.calculateSignalLevel(MAX_RSSI, numLevels)); 413 expectLevel = 4; 414 assertEquals(expectLevel, WifiManager.calculateSignalLevel((MIN_RSSI + MAX_RSSI) / 2, 415 numLevels)); 416 int rssiA = 4; 417 int rssiB = 5; 418 assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) < 0); 419 rssiB = 4; 420 assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) == 0); 421 rssiA = 5; 422 rssiB = 4; 423 assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0); 424 } 425 426 private int getTxPacketCount() throws Exception { 427 final AtomicInteger ret = new AtomicInteger(-1); 428 429 mWifiManager.getTxPacketCount(new TxPacketCountListener() { 430 @Override 431 public void onSuccess(int count) { 432 ret.set(count); 433 } 434 @Override 435 public void onFailure(int reason) { 436 ret.set(0); 437 } 438 }); 439 440 long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; 441 while (ret.get() < 0 && System.currentTimeMillis() < timeout) 442 Thread.sleep(WAIT_MSEC); 443 assertTrue(ret.get() >= 0); 444 return ret.get(); 445 } 446 447 /** 448 * The new WiFi watchdog requires kernel/driver to export some packet loss 449 * counters. This CTS tests whether those counters are correctly exported. 450 * To pass this CTS test, a connected WiFi link is required. 451 */ 452 public void testWifiWatchdog() throws Exception { 453 if (!WifiFeature.isWifiSupported(getContext())) { 454 // skip the test if WiFi is not supported 455 return; 456 } 457 // Make sure WiFi is enabled 458 if (!mWifiManager.isWifiEnabled()) { 459 setWifiEnabled(true); 460 Thread.sleep(DURATION); 461 } 462 assertTrue(mWifiManager.isWifiEnabled()); 463 464 int i = 0; 465 for (; i < 15; i++) { 466 // Wait for a WiFi connection 467 connectWifi(); 468 469 // Read TX packet counter 470 int txcount1 = getTxPacketCount(); 471 472 // Do some network operations 473 HttpURLConnection connection = null; 474 try { 475 URL url = new URL("http://www.google.com/"); 476 connection = (HttpURLConnection) url.openConnection(); 477 connection.setInstanceFollowRedirects(false); 478 connection.setConnectTimeout(TIMEOUT_MSEC); 479 connection.setReadTimeout(TIMEOUT_MSEC); 480 connection.setUseCaches(false); 481 connection.getInputStream(); 482 } catch (Exception e) { 483 // ignore 484 } finally { 485 if (connection != null) connection.disconnect(); 486 } 487 488 // Read TX packet counter again and make sure it increases 489 int txcount2 = getTxPacketCount(); 490 491 if (txcount2 > txcount1) { 492 break; 493 } else { 494 Thread.sleep(DURATION); 495 } 496 } 497 assertTrue(i < 15); 498 } 499 } 500