Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca1f2b1a authored by Xia Wang's avatar Xia Wang
Browse files

Add Wi-Fi connection functional tests.

- Add a XML parser to parse Wi-Fi configurations
- Add Wifi connection tests
- Fix issue: failure in setup will block the next tests.
             call tearDown() if the test fails at setUp().

Change-Id: I1a380fa02ebc96b69165d1514da12df985224e8d
parent 868889fb
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <accesspoint>
    <ssid>opennet</ssid>
    <security>NONE</security>
  </accesspoint>
    <accesspoint>
    <ssid>GoogleGuest</ssid>
    <security>NONE</security>
  </accesspoint>
  <accesspoint>
    <ssid>securenetdhcp</ssid>
    <security>PSK</security>
    <password>androidwifi</password>
  </accesspoint>
  <accesspoint>
    <ssid>botnet</ssid>
    <security>EAP</security>
    <eap>PEAP</eap>
    <phase2>MSCHAPV2</phase2>
    <identity>donut</identity>
    <password>android</password>
  </accesspoint>
</resources>
+262 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.connectivitymanagertest;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;

import android.util.Log;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;


/**
 * Help class to process configurations of access points saved in an XML file.
 * The configurations of an access point is included in tag
 * <accesspoint></accesspoint>. The supported configuration includes: ssid,
 * security, eap, phase2, identity, password, anonymousidentity, cacert, usercert,
 * in which each is included in the corresponding tags. All access points have to be
 * enclosed in tags of <resources></resources>.
 *
 * The following is a sample configuration file for an access point using EAP-PEAP with MSCHAP2.
 * <resources>
 *   <accesspoint>
 *   <ssid>testnet</ssid>
 *   <security>EAP</security>
 *   <eap>PEAP</eap>
 *   <phase2>MSCHAP2</phase2>
 *   <identity>donut</identity</identity>
 *   <password>abcdefgh</password>
 *   </accesspoint>
 * </resources>
 */
public class AccessPointParserHelper {
    private static final String KEYSTORE_SPACE = "keystore://";
    private static final String TAG = "AccessPointParserHelper";
    static final int NONE = 0;
    static final int WEP = 1;
    static final int PSK = 2;
    static final int EAP = 3;

    List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();

    private int getSecurityType (String security) {
        if (security.equalsIgnoreCase("NONE")) {
            return NONE;
        } else if (security.equalsIgnoreCase("WEP")) {
            return WEP;
        } else if (security.equalsIgnoreCase("PSK")) {
            return PSK;
        } else if (security.equalsIgnoreCase("EAP")) {
            return EAP;
        } else {
            return -1;
        }
    }

    private boolean validateEapValue(String value) {
        if (value.equalsIgnoreCase("PEAP") ||
                value.equalsIgnoreCase("TLS") ||
                value.equalsIgnoreCase("TTLS")) {
            return true;
        } else {
            return false;
        }
    }

    DefaultHandler mHandler = new DefaultHandler() {

        boolean ssid = false;
        boolean security = false;
        boolean password = false;
        boolean ip = false;
        boolean subnetmask = false;
        boolean gateway = false;
        boolean dns = false;
        boolean eap = false;
        boolean phase2 = false;
        boolean identity = false;
        boolean anonymousidentity = false;
        boolean cacert = false;
        boolean usercert = false;
        WifiConfiguration config = null;
        int securityType = NONE;

        @Override
        public void startElement(String uri, String localName, String tagName,
                Attributes attributes) throws SAXException {
            if (tagName.equalsIgnoreCase("accesspoint")) {
                config = new WifiConfiguration();
            }
            if (tagName.equalsIgnoreCase("ssid")) {
                ssid = true;
            }
            if (tagName.equalsIgnoreCase("security")) {
                security = true;
            }
            if (tagName.equalsIgnoreCase("password")) {
                password = true;
            }
            if (tagName.equalsIgnoreCase("eap")) {
                eap = true;
            }
            if (tagName.equalsIgnoreCase("phase2")) {
                phase2 = true;
            }
            if (tagName.equalsIgnoreCase("identity")) {
                identity = true;
            }
            if (tagName.equalsIgnoreCase("anonymousidentity")) {
                anonymousidentity = true;
            }
            if (tagName.equalsIgnoreCase("cacert")) {
                cacert = true;
            }
            if (tagName.equalsIgnoreCase("usercert")) {
                usercert = true;
            }
        }

        @Override
        public void endElement(String uri, String localName, String tagName) throws SAXException {
            Log.v(TAG, "endElement: " + tagName);
            if (tagName.equalsIgnoreCase("accesspoint")) {
                networks.add(config);
            }
        }

        @Override
        public void characters(char ch[], int start, int length) throws SAXException {
            if (ssid) {
                config.SSID = new String(ch, start, length);
                Log.v(TAG, "ssid: " + config.SSID);
                ssid = false;
            }
            if (security) {
                String securityStr = (new String(ch, start, length)).toUpperCase();
                Log.v(TAG, "security: " + securityStr);
                securityType = getSecurityType(securityStr);
                Log.v(TAG, "securityType = " + securityType);
                switch (securityType) {
                    case NONE:
                        config.allowedKeyManagement.set(KeyMgmt.NONE);
                        break;
                    case WEP:
                        config.allowedKeyManagement.set(KeyMgmt.NONE);
                        config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
                        config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
                        break;
                    case PSK:
                        config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
                        break;
                    case EAP:
                        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
                        config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
                        break;
                    default:
                        throw new SAXException();
                }
                security = false;
            }
            if (password) {
                String passwordStr = new String(ch, start, length);
                int len = passwordStr.length();
                if (len == 0) {
                    throw new SAXException();
                }
                Log.v(TAG, "passwordStr:" + passwordStr);
                if (securityType == WEP) {
                    if ((len == 10 || len == 26 || len == 58) &&
                            passwordStr.matches("[0-9A-Fa-f]*")) {
                        config.wepKeys[0] = passwordStr;
                    } else {
                        config.wepKeys[0] = '"' + passwordStr + '"';
                    }
                } else if (securityType == PSK) {
                    if (passwordStr.matches("[0-9A-Fa-f]{64}")) {
                        config.preSharedKey = passwordStr;
                    } else {
                        config.preSharedKey = '"' + passwordStr + '"';
                    }
                } else if (securityType == EAP) {
                    config.password.setValue(passwordStr);
                } else {
                    throw new SAXException();
                }
                password = false;
            }
            if (eap) {
                String eapValue = new String(ch, start, length);
                if (!validateEapValue(eapValue)) {
                    throw new SAXException();
                }
                config.eap.setValue(eapValue);
                eap = false;
            }
            if (phase2) {
                String phase2Value = new String(ch, start, length);
                config.phase2.setValue("auth=" + phase2Value);
                phase2 = false;
            }
            if (identity) {
                String identityValue = new String(ch, start, length);
                config.identity.setValue(identityValue);
                identity = false;
            }
            if (anonymousidentity) {
                String anonyId = new String(ch, start, length);
                config.anonymous_identity.setValue(anonyId);
                anonymousidentity = false;
            }
            if (cacert) {
                String cacertValue = new String(ch, start, length);
                // need to install the credentail to "keystore://"
                config.ca_cert.setValue(KEYSTORE_SPACE);
                cacert = false;
            }
            if (usercert) {
                String usercertValue = new String(ch, start, length);
                config.client_cert.setValue(KEYSTORE_SPACE);
                usercert = false;
            }
        }
    };

    public AccessPointParserHelper() {
    }

    /**
     * Process the accesspoint.xml file
     * @return List of WifiConfiguration
     * @throws Exception when parsing the XML file
     */
    public List<WifiConfiguration> processAccessPoint(InputStream in) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        saxParser.parse(in, mHandler);
        return networks;
    }
}
+119 −12
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.connectivitymanagertest;

import com.android.connectivitymanagertest.R;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
@@ -25,19 +27,22 @@ import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.widget.LinearLayout;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;

import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration.KeyMgmt;


/**
 * An activity registered with connectivity manager broadcast
 * provides network connectivity information and
@@ -46,8 +51,11 @@ import android.net.wifi.WifiConfiguration.KeyMgmt;
public class ConnectivityManagerTestActivity extends Activity {

    public static final String LOG_TAG = "ConnectivityManagerTestActivity";
    public static final int WAIT_FOR_SCAN_RESULT = 5 * 1000; //5 seconds
    public static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds
    public static final int WIFI_SCAN_TIMEOUT = 20 * 1000;
    public static final int SHORT_TIMEOUT = 5 * 1000;
    public static final long LONG_TIMEOUT = 50 * 1000;
    private static final String ACCESS_POINT_FILE = "accesspoints.xml";
    public ConnectivityReceiver mConnectivityReceiver = null;
    public WifiReceiver mWifiReceiver = null;
    /*
@@ -175,6 +183,7 @@ public class ConnectivityManagerTestActivity extends Activity {
        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        registerReceiver(mWifiReceiver, mIntentFilter);

        // Get an instance of ConnectivityManager
@@ -185,7 +194,23 @@ public class ConnectivityManagerTestActivity extends Activity {

        if (mWifiManager.isWifiEnabled()) {
            Log.v(LOG_TAG, "Clear Wifi before we start the test.");
            clearWifi();
            removeConfiguredNetworksAndDisableWifi();
        }
     }

    public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
        InputStream in = getAssets().open(ACCESS_POINT_FILE);
        AccessPointParserHelper parseHelper = new AccessPointParserHelper();
        return parseHelper.processAccessPoint(in);
    }

    private void printNetConfig(String[] configuration) {
        for (int i = 0; i < configuration.length; i++) {
            if (i == 0) {
                Log.v(LOG_TAG, "SSID: " + configuration[0]);
            } else {
                Log.v(LOG_TAG, "      " + configuration[i]);
            }
        }
    }

@@ -245,6 +270,68 @@ public class ConnectivityManagerTestActivity extends Activity {
        }
    }

    // Wait for network connectivity state: CONNECTING, CONNECTED, SUSPENDED,
    //                                      DISCONNECTING, DISCONNECTED, UNKNOWN
    public boolean waitForNetworkState(int networkType, State expectedState, long timeout) {
        long startTime = System.currentTimeMillis();
        while (true) {
            if ((System.currentTimeMillis() - startTime) > timeout) {
                if (mCM.getNetworkInfo(networkType).getState() != expectedState) {
                    return false;
                } else {
                    // the broadcast has been sent out. the state has been changed.
                    Log.v(LOG_TAG, "networktype: " + networkType + " state: " +
                            mCM.getNetworkInfo(networkType));
                    return true;
                }
            }
            Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType +
                    " to be " + expectedState.toString());
            synchronized (connectivityObject) {
                try {
                    connectivityObject.wait(SHORT_TIMEOUT);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if ((mNetworkInfo.getType() != networkType) ||
                    (mNetworkInfo.getState() != expectedState)) {
                    Log.v(LOG_TAG, "network state for " + mNetworkInfo.getType() +
                            "is: " + mNetworkInfo.getState());
                    continue;
                }
                return true;
            }
        }
    }

    // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
    //                      WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
    public boolean waitForWifiState(int expectedState, long timeout) {
        long startTime = System.currentTimeMillis();
        while (true) {
            if ((System.currentTimeMillis() - startTime) > timeout) {
                if (mWifiState != expectedState) {
                    return false;
                } else {
                    return true;
                }
            }
            Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState);
            synchronized (wifiObject) {
                try {
                    wifiObject.wait(SHORT_TIMEOUT);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (mWifiState != expectedState) {
                    Log.v(LOG_TAG, "Wifi state is: " + mWifiNetworkInfo.getState());
                    continue;
                }
                return true;
            }
        }
    }

    // Return true if device is currently connected to mobile network
    public boolean isConnectedToMobile() {
        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
@@ -265,6 +352,22 @@ public class ConnectivityManagerTestActivity extends Activity {
     * We don't verify whether the connection is successful or not, leave this to the test
     */
    public boolean connectToWifi(String knownSSID) {
        WifiConfiguration config = new WifiConfiguration();
        config.SSID = knownSSID;
        config.allowedKeyManagement.set(KeyMgmt.NONE);
        return connectToWifiWithConfiguration(config);
    }

    /**
     * Connect to Wi-Fi with the given configuration. Note the SSID in the configuration
     * is pure string, we need to convert it to quoted string.
     * @param config
     * @return
     */
    public boolean connectToWifiWithConfiguration(WifiConfiguration config) {
        String ssid = config.SSID;
        config.SSID = convertToQuotedString(ssid);

        //If Wifi is not enabled, enable it
        if (!mWifiManager.isWifiEnabled()) {
            Log.v(LOG_TAG, "Wifi is not enabled, enable it");
@@ -273,6 +376,7 @@ public class ConnectivityManagerTestActivity extends Activity {

        List<ScanResult> netList = mWifiManager.getScanResults();
        if (netList == null) {
            Log.v(LOG_TAG, "scan results are null");
            // if no scan results are available, start active scan
            mWifiManager.startScanActive();
            mScanResultIsAvailable = false;
@@ -299,17 +403,20 @@ public class ConnectivityManagerTestActivity extends Activity {
        }

        netList = mWifiManager.getScanResults();

        for (int i = 0; i < netList.size(); i++) {
            ScanResult sr= netList.get(i);
            if (sr.SSID.equals(knownSSID)) {
                Log.v(LOG_TAG, "found " + knownSSID + " in the scan result list");
                WifiConfiguration config = new WifiConfiguration();
                config.SSID = convertToQuotedString(sr.SSID);
                config.allowedKeyManagement.set(KeyMgmt.NONE);
            if (sr.SSID.equals(ssid)) {
                Log.v(LOG_TAG, "found " + ssid + " in the scan result list");
                int networkId = mWifiManager.addNetwork(config);
                // Connect to network by disabling others.
                mWifiManager.enableNetwork(networkId, true);
                mWifiManager.saveConfiguration();
                List<WifiConfiguration> wifiNetworks = mWifiManager.getConfiguredNetworks();
                for (WifiConfiguration netConfig : wifiNetworks) {
                    Log.v(LOG_TAG, netConfig.toString());
                }

                mWifiManager.reconnect();
                break;
           }
@@ -317,14 +424,14 @@ public class ConnectivityManagerTestActivity extends Activity {

        List<WifiConfiguration> netConfList = mWifiManager.getConfiguredNetworks();
        if (netConfList.size() <= 0) {
            Log.v(LOG_TAG, knownSSID + " is not available");
            Log.v(LOG_TAG, ssid + " is not available");
            return false;
        }
        return true;
    }

    /*
     * Disconnect from the current AP
     * Disconnect from the current AP and remove configured networks.
     */
    public boolean disconnectAP() {
        if (mWifiManager.isWifiEnabled()) {
@@ -360,9 +467,9 @@ public class ConnectivityManagerTestActivity extends Activity {
    }

    /**
     * Disconnect from the current Wifi and clear the configuration list
     * Remove configured networks and disable wifi
     */
    public boolean clearWifi() {
    public boolean removeConfiguredNetworksAndDisableWifi() {
            if (!disconnectAP()) {
                return false;
            }
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import android.util.Log;
import com.android.connectivitymanagertest.functional.ConnectivityManagerMobileTest;
import com.android.connectivitymanagertest.functional.WifiConnectionTest;

import junit.framework.TestSuite;

@@ -38,6 +39,7 @@ public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
    public TestSuite getAllTests() {
        TestSuite suite = new InstrumentationTestSuite(this);
        suite.addTestSuite(ConnectivityManagerMobileTest.class);
        suite.addTestSuite(WifiConnectionTest.class);
        return suite;
    }

+68 −120

File changed.

Preview size limit exceeded, changes collapsed.

Loading