Home | History | Annotate | Download | only in connectivitymanagertest
      1 /*
      2  * Copyright (C) 2010, 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 com.android.connectivitymanagertest;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.content.BroadcastReceiver;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.os.Bundle;
     25 import android.provider.Settings;
     26 import android.util.Log;
     27 import java.util.List;
     28 import android.widget.LinearLayout;
     29 import android.net.ConnectivityManager;
     30 import android.net.NetworkInfo;
     31 import android.net.NetworkInfo.State;
     32 
     33 import android.net.wifi.WifiConfiguration;
     34 import android.net.wifi.WifiManager;
     35 import android.net.wifi.WifiInfo;
     36 import android.net.wifi.ScanResult;
     37 import android.net.wifi.WifiConfiguration.KeyMgmt;
     38 
     39 
     40 /**
     41  * An activity registered with connectivity manager broadcast
     42  * provides network connectivity information and
     43  * can be used to set device states: Cellular, Wifi, Airplane mode.
     44  */
     45 public class ConnectivityManagerTestActivity extends Activity {
     46 
     47     public static final String LOG_TAG = "ConnectivityManagerTestActivity";
     48     public static final int WAIT_FOR_SCAN_RESULT = 5 * 1000; //5 seconds
     49     public static final int WIFI_SCAN_TIMEOUT = 20 * 1000;
     50     public ConnectivityReceiver mConnectivityReceiver = null;
     51     public WifiReceiver mWifiReceiver = null;
     52     /*
     53      * Track network connectivity information
     54      */
     55     public State mState;
     56     public NetworkInfo mNetworkInfo;
     57     public NetworkInfo mOtherNetworkInfo;
     58     public boolean mIsFailOver;
     59     public String mReason;
     60     public boolean mScanResultIsAvailable = false;
     61     public ConnectivityManager mCM;
     62     public Object wifiObject = new Object();
     63     public Object connectivityObject = new Object();
     64     public int mWifiState;
     65     public NetworkInfo mWifiNetworkInfo;
     66     public String mBssid;
     67 
     68     /*
     69      * Control Wifi States
     70      */
     71     public WifiManager mWifiManager;
     72 
     73     /*
     74      * Verify connectivity state
     75      */
     76     public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
     77     NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES];
     78 
     79     /**
     80      * A wrapper of a broadcast receiver which provides network connectivity information
     81      * for all kinds of network: wifi, mobile, etc.
     82      */
     83     private class ConnectivityReceiver extends BroadcastReceiver {
     84         @Override
     85         public void onReceive(Context context, Intent intent) {
     86             Log.v(LOG_TAG, "ConnectivityReceiver: onReceive() is called with " + intent);
     87             String action = intent.getAction();
     88             if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
     89                 Log.v("ConnectivityReceiver", "onReceive() called with " + intent);
     90                 return;
     91             }
     92 
     93             boolean noConnectivity =
     94                 intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
     95 
     96             if (noConnectivity) {
     97                 mState = State.DISCONNECTED;
     98             } else {
     99                 mState = State.CONNECTED;
    100             }
    101 
    102             mNetworkInfo = (NetworkInfo)
    103                 intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
    104 
    105             mOtherNetworkInfo = (NetworkInfo)
    106                 intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
    107 
    108             mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
    109             mIsFailOver = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
    110 
    111             Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString());
    112             if (mOtherNetworkInfo != null) {
    113                 Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString());
    114             }
    115             recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
    116             if (mOtherNetworkInfo != null) {
    117                 recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
    118             }
    119             notifyNetworkConnectivityChange();
    120         }
    121     }
    122 
    123     private class WifiReceiver extends BroadcastReceiver {
    124         @Override
    125         public void onReceive(Context context, Intent intent) {
    126             String action = intent.getAction();
    127             Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
    128             if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
    129                 notifyScanResult();
    130             } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    131                 mWifiNetworkInfo =
    132                     (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
    133                 Log.v(LOG_TAG, "mWifiNetworkInfo: " + mWifiNetworkInfo.toString());
    134                 if (mWifiNetworkInfo.getState() == State.CONNECTED) {
    135                     mBssid = intent.getStringExtra(WifiManager.EXTRA_BSSID);
    136                 }
    137                 notifyWifiState();
    138             } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
    139                 mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
    140                                                 WifiManager.WIFI_STATE_UNKNOWN);
    141                 notifyWifiState();
    142             }
    143             else {
    144                 return;
    145             }
    146         }
    147     }
    148 
    149     public ConnectivityManagerTestActivity() {
    150         mState = State.UNKNOWN;
    151     }
    152 
    153     @Override
    154     protected void onCreate(Bundle savedInstanceState) {
    155         super.onCreate(savedInstanceState);
    156         Log.v(LOG_TAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
    157 
    158         // Create a simple layout
    159         LinearLayout contentView = new LinearLayout(this);
    160         contentView.setOrientation(LinearLayout.VERTICAL);
    161         setContentView(contentView);
    162         setTitle("ConnectivityManagerTestActivity");
    163 
    164 
    165         // register a connectivity receiver for CONNECTIVITY_ACTION;
    166         mConnectivityReceiver = new ConnectivityReceiver();
    167         registerReceiver(mConnectivityReceiver,
    168                 new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    169 
    170         mWifiReceiver = new WifiReceiver();
    171         IntentFilter mIntentFilter = new IntentFilter();
    172         mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    173         mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    174         mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    175         registerReceiver(mWifiReceiver, mIntentFilter);
    176 
    177         // Get an instance of ConnectivityManager
    178         mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    179         // Get an instance of WifiManager
    180         mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
    181         initializeNetworkStates();
    182 
    183         if (mWifiManager.isWifiEnabled()) {
    184             Log.v(LOG_TAG, "Clear Wifi before we start the test.");
    185             clearWifi();
    186         }
    187      }
    188 
    189     // for each network type, initialize network states to UNKNOWN, and no verification flag is set
    190     public void initializeNetworkStates() {
    191         for (int networkType = NUM_NETWORK_TYPES - 1; networkType >=0; networkType--) {
    192             connectivityState[networkType] =  new NetworkState();
    193             Log.v(LOG_TAG, "Initialize network state for " + networkType + ": " +
    194                     connectivityState[networkType].toString());
    195         }
    196     }
    197 
    198     // deposit a network state
    199     public void recordNetworkState(int networkType, State networkState) {
    200         Log.v(LOG_TAG, "record network state for network " +  networkType +
    201                 ", state is " + networkState);
    202         connectivityState[networkType].recordState(networkState);
    203     }
    204 
    205     // set the state transition criteria
    206     public void setStateTransitionCriteria(int networkType, State initState,
    207             int transitionDir, State targetState) {
    208         connectivityState[networkType].setStateTransitionCriteria(
    209                 initState, transitionDir, targetState);
    210     }
    211 
    212     // Validate the states recorded
    213     public boolean validateNetworkStates(int networkType) {
    214         Log.v(LOG_TAG, "validate network state for " + networkType + ": ");
    215         return connectivityState[networkType].validateStateTransition();
    216     }
    217 
    218     // return result from network state validation
    219     public String getTransitionFailureReason(int networkType) {
    220         Log.v(LOG_TAG, "get network state transition failure reason for " + networkType + ": " +
    221                 connectivityState[networkType].toString());
    222         return connectivityState[networkType].getReason();
    223     }
    224 
    225     private void notifyNetworkConnectivityChange() {
    226         synchronized(connectivityObject) {
    227             Log.v(LOG_TAG, "notify network connectivity changed");
    228             connectivityObject.notifyAll();
    229         }
    230     }
    231     private void notifyScanResult() {
    232         synchronized (this) {
    233             Log.v(LOG_TAG, "notify that scan results are available");
    234             this.notify();
    235         }
    236     }
    237 
    238     public void notifyWifiState() {
    239         synchronized (wifiObject) {
    240             Log.v(LOG_TAG, "notify wifi state changed");
    241             wifiObject.notify();
    242         }
    243     }
    244 
    245     // Return true if device is currently connected to mobile network
    246     public boolean isConnectedToMobile() {
    247         return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
    248     }
    249 
    250     // Return true if device is currently connected to Wifi
    251     public boolean isConnectedToWifi() {
    252         return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
    253     }
    254 
    255     public boolean enableWifi() {
    256         return mWifiManager.setWifiEnabled(true);
    257     }
    258 
    259     /**
    260      * Associate the device to given SSID
    261      * If the device is already associated with a WiFi, disconnect and forget it,
    262      * We don't verify whether the connection is successful or not, leave this to the test
    263      */
    264     public boolean connectToWifi(String knownSSID) {
    265         //If Wifi is not enabled, enable it
    266         if (!mWifiManager.isWifiEnabled()) {
    267             Log.v(LOG_TAG, "Wifi is not enabled, enable it");
    268             mWifiManager.setWifiEnabled(true);
    269         }
    270 
    271         List<ScanResult> netList = mWifiManager.getScanResults();
    272         if (netList == null) {
    273             // if no scan results are available, start active scan
    274             mWifiManager.startScanActive();
    275             mScanResultIsAvailable = false;
    276             long startTime = System.currentTimeMillis();
    277             while (!mScanResultIsAvailable) {
    278                 if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
    279                     return false;
    280                 }
    281                 // wait for the scan results to be available
    282                 synchronized (this) {
    283                     // wait for the scan result to be available
    284                     try {
    285                         this.wait(WAIT_FOR_SCAN_RESULT);
    286                     } catch (InterruptedException e) {
    287                         e.printStackTrace();
    288                     }
    289                     if ((mWifiManager.getScanResults() == null) ||
    290                             (mWifiManager.getScanResults().size() <= 0)) {
    291                         continue;
    292                     }
    293                     mScanResultIsAvailable = true;
    294                 }
    295             }
    296         }
    297 
    298         netList = mWifiManager.getScanResults();
    299         for (int i = 0; i < netList.size(); i++) {
    300             ScanResult sr= netList.get(i);
    301             if (sr.SSID.equals(knownSSID)) {
    302                 Log.v(LOG_TAG, "found " + knownSSID + " in the scan result list");
    303                 WifiConfiguration config = new WifiConfiguration();
    304                 config.SSID = convertToQuotedString(sr.SSID);
    305                 config.allowedKeyManagement.set(KeyMgmt.NONE);
    306                 int networkId = mWifiManager.addNetwork(config);
    307                 // Connect to network by disabling others.
    308                 mWifiManager.enableNetwork(networkId, true);
    309                 mWifiManager.saveConfiguration();
    310                 mWifiManager.reconnect();
    311                 break;
    312            }
    313         }
    314 
    315         List<WifiConfiguration> netConfList = mWifiManager.getConfiguredNetworks();
    316         if (netConfList.size() <= 0) {
    317             Log.v(LOG_TAG, knownSSID + " is not available");
    318             return false;
    319         }
    320         return true;
    321     }
    322 
    323     /*
    324      * Disconnect from the current AP
    325      */
    326     public boolean disconnectAP() {
    327         if (mWifiManager.isWifiEnabled()) {
    328             //remove the current network Id
    329             WifiInfo curWifi = mWifiManager.getConnectionInfo();
    330             if (curWifi == null) {
    331                 return false;
    332             }
    333             int curNetworkId = curWifi.getNetworkId();
    334             mWifiManager.removeNetwork(curNetworkId);
    335             mWifiManager.saveConfiguration();
    336 
    337             // remove other saved networks
    338             List<WifiConfiguration> netConfList = mWifiManager.getConfiguredNetworks();
    339             if (netConfList != null) {
    340                 Log.v(LOG_TAG, "remove configured network ids");
    341                 for (int i = 0; i < netConfList.size(); i++) {
    342                     WifiConfiguration conf = new WifiConfiguration();
    343                     conf = netConfList.get(i);
    344                     mWifiManager.removeNetwork(conf.networkId);
    345                 }
    346             }
    347         }
    348         mWifiManager.saveConfiguration();
    349         return true;
    350     }
    351     /**
    352      * Disable Wifi
    353      * @return true if Wifi is disabled successfully
    354      */
    355     public boolean disableWifi() {
    356         return mWifiManager.setWifiEnabled(false);
    357     }
    358 
    359     /**
    360      * Disconnect from the current Wifi and clear the configuration list
    361      */
    362     public boolean clearWifi() {
    363             if (!disconnectAP()) {
    364                 return false;
    365             }
    366             // Disable Wifi
    367             if (!mWifiManager.setWifiEnabled(false)) {
    368                 return false;
    369             }
    370             // Wait for the actions to be completed
    371             try {
    372                 Thread.sleep(5*1000);
    373             } catch (InterruptedException e) {}
    374         return true;
    375     }
    376 
    377     /**
    378      * Set airplane mode
    379      */
    380     public void setAirplaneMode(Context context, boolean enableAM) {
    381         //set the airplane mode
    382         Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
    383                 enableAM ? 1 : 0);
    384         // Post the intent
    385         Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
    386         intent.putExtra("state", enableAM);
    387         context.sendBroadcast(intent);
    388     }
    389 
    390     protected static String convertToQuotedString(String string) {
    391         return "\"" + string + "\"";
    392     }
    393 
    394     @Override
    395     protected void onDestroy() {
    396         super.onDestroy();
    397 
    398         //Unregister receiver
    399         if (mConnectivityReceiver != null) {
    400             unregisterReceiver(mConnectivityReceiver);
    401         }
    402         if (mWifiReceiver != null) {
    403             unregisterReceiver(mWifiReceiver);
    404         }
    405         Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
    406     }
    407 }
    408