Home | History | Annotate | Download | only in cts
      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