/* * 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 android.app.Activity; import android.content.Context; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.provider.Settings; import android.util.Log; 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.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 * can be used to set device states: Cellular, Wifi, Airplane mode. */ 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 WIFI_SCAN_TIMEOUT = 20 * 1000; public ConnectivityReceiver mConnectivityReceiver = null; public WifiReceiver mWifiReceiver = null; /* * Track network connectivity information */ public State mState; public NetworkInfo mNetworkInfo; public NetworkInfo mOtherNetworkInfo; public boolean mIsFailOver; public String mReason; public boolean mScanResultIsAvailable = false; public ConnectivityManager mCM; public Object wifiObject = new Object(); public Object connectivityObject = new Object(); public int mWifiState; public NetworkInfo mWifiNetworkInfo; public String mBssid; /* * Control Wifi States */ public WifiManager mWifiManager; /* * Verify connectivity state */ public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1; NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES]; /** * A wrapper of a broadcast receiver which provides network connectivity information * for all kinds of network: wifi, mobile, etc. */ private class ConnectivityReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.v(LOG_TAG, "ConnectivityReceiver: onReceive() is called with " + intent); String action = intent.getAction(); if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { Log.v("ConnectivityReceiver", "onReceive() called with " + intent); return; } boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); if (noConnectivity) { mState = State.DISCONNECTED; } else { mState = State.CONNECTED; } mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); mOtherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO); mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON); mIsFailOver = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false); Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString()); if (mOtherNetworkInfo != null) { Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString()); } recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState()); if (mOtherNetworkInfo != null) { recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState()); } notifyNetworkConnectivityChange(); } } private class WifiReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.v("WifiReceiver", "onReceive() is calleld with " + intent); if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { notifyScanResult(); } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { mWifiNetworkInfo = (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); Log.v(LOG_TAG, "mWifiNetworkInfo: " + mWifiNetworkInfo.toString()); if (mWifiNetworkInfo.getState() == State.CONNECTED) { mBssid = intent.getStringExtra(WifiManager.EXTRA_BSSID); } notifyWifiState(); } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN); notifyWifiState(); } else { return; } } } public ConnectivityManagerTestActivity() { mState = State.UNKNOWN; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.v(LOG_TAG, "onCreate, inst=" + Integer.toHexString(hashCode())); // Create a simple layout LinearLayout contentView = new LinearLayout(this); contentView.setOrientation(LinearLayout.VERTICAL); setContentView(contentView); setTitle("ConnectivityManagerTestActivity"); // register a connectivity receiver for CONNECTIVITY_ACTION; mConnectivityReceiver = new ConnectivityReceiver(); registerReceiver(mConnectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); mWifiReceiver = new WifiReceiver(); IntentFilter mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); registerReceiver(mWifiReceiver, mIntentFilter); // Get an instance of ConnectivityManager mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); // Get an instance of WifiManager mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE); initializeNetworkStates(); if (mWifiManager.isWifiEnabled()) { Log.v(LOG_TAG, "Clear Wifi before we start the test."); clearWifi(); } } // for each network type, initialize network states to UNKNOWN, and no verification flag is set public void initializeNetworkStates() { for (int networkType = NUM_NETWORK_TYPES - 1; networkType >=0; networkType--) { connectivityState[networkType] = new NetworkState(); Log.v(LOG_TAG, "Initialize network state for " + networkType + ": " + connectivityState[networkType].toString()); } } // deposit a network state public void recordNetworkState(int networkType, State networkState) { Log.v(LOG_TAG, "record network state for network " + networkType + ", state is " + networkState); connectivityState[networkType].recordState(networkState); } // set the state transition criteria public void setStateTransitionCriteria(int networkType, State initState, int transitionDir, State targetState) { connectivityState[networkType].setStateTransitionCriteria( initState, transitionDir, targetState); } // Validate the states recorded public boolean validateNetworkStates(int networkType) { Log.v(LOG_TAG, "validate network state for " + networkType + ": "); return connectivityState[networkType].validateStateTransition(); } // return result from network state validation public String getTransitionFailureReason(int networkType) { Log.v(LOG_TAG, "get network state transition failure reason for " + networkType + ": " + connectivityState[networkType].toString()); return connectivityState[networkType].getReason(); } private void notifyNetworkConnectivityChange() { synchronized(connectivityObject) { Log.v(LOG_TAG, "notify network connectivity changed"); connectivityObject.notifyAll(); } } private void notifyScanResult() { synchronized (this) { Log.v(LOG_TAG, "notify that scan results are available"); this.notify(); } } public void notifyWifiState() { synchronized (wifiObject) { Log.v(LOG_TAG, "notify wifi state changed"); wifiObject.notify(); } } // Return true if device is currently connected to mobile network public boolean isConnectedToMobile() { return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE); } // Return true if device is currently connected to Wifi public boolean isConnectedToWifi() { return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI); } public boolean enableWifi() { return mWifiManager.setWifiEnabled(true); } /** * Associate the device to given SSID * If the device is already associated with a WiFi, disconnect and forget it, * We don't verify whether the connection is successful or not, leave this to the test */ public boolean connectToWifi(String knownSSID) { //If Wifi is not enabled, enable it if (!mWifiManager.isWifiEnabled()) { Log.v(LOG_TAG, "Wifi is not enabled, enable it"); mWifiManager.setWifiEnabled(true); } List<ScanResult> netList = mWifiManager.getScanResults(); if (netList == null) { // if no scan results are available, start active scan mWifiManager.startScanActive(); mScanResultIsAvailable = false; long startTime = System.currentTimeMillis(); while (!mScanResultIsAvailable) { if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) { return false; } // wait for the scan results to be available synchronized (this) { // wait for the scan result to be available try { this.wait(WAIT_FOR_SCAN_RESULT); } catch (InterruptedException e) { e.printStackTrace(); } if ((mWifiManager.getScanResults() == null) || (mWifiManager.getScanResults().size() <= 0)) { continue; } mScanResultIsAvailable = true; } } } 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); int networkId = mWifiManager.addNetwork(config); // Connect to network by disabling others. mWifiManager.enableNetwork(networkId, true); mWifiManager.saveConfiguration(); mWifiManager.reconnect(); break; } } List<WifiConfiguration> netConfList = mWifiManager.getConfiguredNetworks(); if (netConfList.size() <= 0) { Log.v(LOG_TAG, knownSSID + " is not available"); return false; } return true; } /* * Disconnect from the current AP */ public boolean disconnectAP() { if (mWifiManager.isWifiEnabled()) { //remove the current network Id WifiInfo curWifi = mWifiManager.getConnectionInfo(); if (curWifi == null) { return false; } int curNetworkId = curWifi.getNetworkId(); mWifiManager.removeNetwork(curNetworkId); mWifiManager.saveConfiguration(); // remove other saved networks List<WifiConfiguration> netConfList = mWifiManager.getConfiguredNetworks(); if (netConfList != null) { Log.v(LOG_TAG, "remove configured network ids"); for (int i = 0; i < netConfList.size(); i++) { WifiConfiguration conf = new WifiConfiguration(); conf = netConfList.get(i); mWifiManager.removeNetwork(conf.networkId); } } } mWifiManager.saveConfiguration(); return true; } /** * Disable Wifi * @return true if Wifi is disabled successfully */ public boolean disableWifi() { return mWifiManager.setWifiEnabled(false); } /** * Disconnect from the current Wifi and clear the configuration list */ public boolean clearWifi() { if (!disconnectAP()) { return false; } // Disable Wifi if (!mWifiManager.setWifiEnabled(false)) { return false; } // Wait for the actions to be completed try { Thread.sleep(5*1000); } catch (InterruptedException e) {} return true; } /** * Set airplane mode */ public void setAirplaneMode(Context context, boolean enableAM) { //set the airplane mode Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, enableAM ? 1 : 0); // Post the intent Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); intent.putExtra("state", enableAM); context.sendBroadcast(intent); } protected static String convertToQuotedString(String string) { return "\"" + string + "\""; } @Override protected void onDestroy() { super.onDestroy(); //Unregister receiver if (mConnectivityReceiver != null) { unregisterReceiver(mConnectivityReceiver); } if (mWifiReceiver != null) { unregisterReceiver(mWifiReceiver); } Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode())); } }