- Create a dummy activity - ConnectivityManagerTestActivity - to listen to broadcast from connectivity manager, to control wifi, and to verify that connectivity information for different network types. This framework will be used for funcitonal tests and stress tests.
- Add two functional test cases:
. test3GToWifiNotification: test enabling Wifi without associating with any access point, Wifi stays disconnected, device should still connect to cellular.
. testConnectToWifi: when switching from cellular to Wfi and associated with a given AP, connectivity manager broadcast the right informtion for mobile and Wifi.
Change-Id: Ib6fcf0ff6dd9725076836032e567c0a6a52f622f
--- /dev/null
+# Copyright 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+
+#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+
+include $(BUILD_PACKAGE)
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.connectivitymanagertest">
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="ConnectivityManagerTestActivity"
+ android:label="CMTest">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.TEST" />
+ </intent-filter>
+ </activity>
+ </application>
+ <!--
+ This declares that this app uses the instrumentation test runner targeting
+ the package of browserpowertest. To run the tests use the command:
+ "adb shell am instrument -w com.android.connectivitymanagertest/.ConnectivityManagerTestRunner"
+ -->
+ <instrumentation android:name=".ConnectivityManagerTestRunner"
+ android:targetPackage="com.android.connectivitymanagertest"
+ android:label="Test runner for Connectivity Manager Tests"
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+
+</manifest>
--- /dev/null
+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.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;
+
+ /*
+ * Control Wifi States
+ */
+ public WifiManager mWifiManager;
+
+ /*
+ * Verify connectivity state
+ */
+ public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE;
+ 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) {
+ 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);
+ recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
+ if (mOtherNetworkInfo != null) {
+ recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
+ }
+ }
+ }
+
+ private class WifiReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (!action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+ Log.v(LOG_TAG, "onReceive() is calleld with " + intent);
+ return;
+ }
+ notifyScanResult();
+ }
+ }
+
+ 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");
+
+ mConnectivityReceiver = new ConnectivityReceiver();
+ // register a connectivity receiver for CONNECTIVITY_ACTION;
+ registerReceiver(mConnectivityReceiver,
+ new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+
+ mWifiReceiver = new WifiReceiver();
+ registerReceiver(mWifiReceiver,
+ new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
+ // 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 notifyScanResult() {
+ synchronized (this) {
+ Log.v(LOG_TAG, "notify that scan results are available");
+ this.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 = sr.SSID;
+ config.allowedKeyManagement.set(KeyMgmt.NONE);
+ int networkId = mWifiManager.addNetwork(config);
+ mWifiManager.saveConfiguration();
+ // Connect to network by disabling others.
+ mWifiManager.enableNetwork(networkId, true);
+ mWifiManager.reconnect();
+ break;
+ }
+ }
+
+ List<WifiConfiguration> netConfList = mWifiManager.getConfiguredNetworks();
+ if (netConfList.size() <= 0) {
+ Log.v(LOG_TAG, knownSSID + " is not available");
+ return false;
+ }
+ 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 (mWifiManager.isWifiEnabled()) {
+ //remove the current network Id
+ int curNetworkId = mWifiManager.getConnectionInfo().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();
+ // 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);
+ }
+
+ @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()));
+ }
+}
--- /dev/null
+package com.android.connectivitymanagertest;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import android.util.Log;
+import com.android.connectivitymanagertest.functional.ConnectivityManagerMobileTest;
+
+import junit.framework.TestSuite;
+
+/**
+ * Instrumentation Test Runner for all connectivity manager tests.
+ *
+ * To run the connectivity manager tests:
+ *
+ * adb shell am instrument \
+ * -w com.android.connectivitymanagertest/.ConnectivityManagerTestRunner
+ */
+
+public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(ConnectivityManagerMobileTest.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return ConnectivityManagerTestRunner.class.getClassLoader();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ String testSSID = (String) icicle.get("ssid");
+ if (testSSID != null) {
+ TEST_SSID = testSSID;
+ }
+ }
+
+ public String TEST_SSID = "GoogleGuest";
+}
--- /dev/null
+package com.android.connectivitymanagertest;
+
+import android.net.NetworkInfo.State;
+import android.util.Log;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class NetworkState {
+ public static final int TO_DISCONNECTION = 0; // transition to disconnection
+ public static final int TO_CONNECTION = 1; // transition to connection
+ public static final int DO_NOTHING = -1; // no state change
+ private final String LOG_TAG = "NetworkState";
+ private List<State> mStateDepository;
+ private State mTransitionTarget;
+ private int mTransitionDirection;
+ private String mReason = null; // record mReason of state transition failure
+
+ public NetworkState() {
+ mStateDepository = new ArrayList<State>();
+ mTransitionDirection = DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ public NetworkState(State currentState) {
+ mStateDepository = new ArrayList<State>();
+ mStateDepository.add(currentState);
+ mTransitionDirection = DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ // Reinitialize the network state
+ public void resetNetworkState() {
+ mStateDepository.clear();
+ mTransitionDirection = DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ // set the transition criteria, transitionDir could be:
+ // DO_NOTHING, TO_CONNECTION, TO_DISCONNECTION
+ public void setStateTransitionCriteria(State initState, int transitionDir, State targetState) {
+ if (!mStateDepository.isEmpty()) {
+ mStateDepository.clear();
+ }
+ mStateDepository.add(initState);
+ mTransitionDirection = transitionDir;
+ mTransitionTarget = targetState;
+ Log.v(LOG_TAG, "setStateTransitionCriteria: " + printStates());
+ }
+
+ public void recordState(State currentState) {
+ mStateDepository.add(currentState);
+ }
+
+ // Verify state transition
+ public boolean validateStateTransition() {
+ Log.v(LOG_TAG, "print state depository: " + printStates());
+ if (mTransitionDirection == DO_NOTHING) {
+ if (mStateDepository.isEmpty()) {
+ Log.v(LOG_TAG, "no state is recorded");
+ mReason = "no state is recorded.";
+ return false;
+ } else if (mStateDepository.size() > 1) {
+ Log.v(LOG_TAG, "no broadcast is expected, " +
+ "instead broadcast is probably received");
+ mReason = "no broadcast is expected, instead broadcast is probably received";
+ return false;
+ } else if (mStateDepository.get(0) != mTransitionTarget) {
+ Log.v(LOG_TAG, mTransitionTarget + " is expected, but it is " +
+ mStateDepository.get(0));
+ mReason = mTransitionTarget + " is expected, but it is " + mStateDepository.get(0);
+ return false;
+ }
+ return true;
+ } else if (mTransitionDirection == TO_CONNECTION) {
+ Log.v(LOG_TAG, "transition to CONNECTED");
+ return transitToConnection();
+ } else {
+ Log.v(LOG_TAG, "transition to DISCONNECTED");
+ return transitToDisconnection();
+ }
+ }
+
+ /*
+ * Transition from CONNECTED -> DISCONNECTED:
+ * CONNECTED->DISCONNECTING->DISCONNECTED
+ * return false if any state transition is not valid and save a message in mReason
+ */
+ public boolean transitToDisconnection () {
+ mReason = "states: " + printStates();
+ if (mStateDepository.get(0) != State.CONNECTED) {
+ mReason += " initial state should be CONNECTED, but it is " +
+ mStateDepository.get(0) + ".";
+ return false;
+ }
+ State lastState = mStateDepository.get(mStateDepository.size() - 1);
+ if ( lastState != mTransitionTarget) {
+ mReason += " the last state should be DISCONNECTED, but it is " + lastState;
+ return false;
+ }
+ for (int i = 1; i < mStateDepository.size() - 1; i++) {
+ State preState = mStateDepository.get(i-1);
+ State curState = mStateDepository.get(i);
+ if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) ||
+ (curState == State.DISCONNECTED))) {
+ continue;
+ } else if ((preState == State.DISCONNECTING) && (curState == State.DISCONNECTED)) {
+ continue;
+ } else if ((preState == State.DISCONNECTED) && (curState == State.DISCONNECTED)) {
+ continue;
+ } else {
+ mReason += " Transition state from " + preState.toString() + " to " +
+ curState.toString() + " is not valid.";
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // DISCONNECTED->CONNECTING->CONNECTED
+ public boolean transitToConnection() {
+ mReason = "states: " + printStates();
+ if (mStateDepository.get(0) != State.DISCONNECTED) {
+ mReason += " initial state should be DISCONNECTED, but it is " +
+ mStateDepository.get(0) + ".";
+ return false;
+ }
+ State lastState = mStateDepository.get(mStateDepository.size() - 1);
+ if ( lastState != mTransitionTarget) {
+ mReason += " the last state should be CONNECTED, but it is " + lastState;
+ return false;
+ }
+ for (int i = 1; i < mStateDepository.size(); i++) {
+ State preState = mStateDepository.get(i-1);
+ State curState = mStateDepository.get(i);
+ if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) ||
+ (curState == State.CONNECTED))) {
+ continue;
+ } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
+ continue;
+ } else if ((preState == State.CONNECTED) && (curState == State.CONNECTED)) {
+ continue;
+ } else {
+ mReason += " Transition state from " + preState.toString() + " to " +
+ curState.toString() + " is not valid.";
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public List<State> getTransitionStates() {
+ return mStateDepository;
+ }
+
+ // return state failure mReason
+ public String getReason() {
+ return mReason;
+ }
+
+ public String printStates() {
+ StringBuilder stateBuilder = new StringBuilder("");
+ for (int i = 0; i < mStateDepository.size(); i++) {
+ stateBuilder.append(" ").append(mStateDepository.get(i).toString()).append("->");
+ }
+ return stateBuilder.toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(" ");
+ builder.append("mTransitionDirection: ").append(Integer.toString(mTransitionDirection)).
+ append("; ").append("states:").
+ append(printStates()).append("; ");
+ return builder.toString();
+ }
+}
--- /dev/null
+package com.android.connectivitymanagertest.functional;
+
+import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+
+import android.content.Intent;
+import android.content.Context;
+import android.app.Instrumentation;
+import android.os.Handler;
+import android.os.Message;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.net.NetworkInfo.DetailedState;
+
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.ActivityInstrumentationTestCase2;
+import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
+import com.android.connectivitymanagertest.NetworkState;
+import android.util.Log;
+import junit.framework.*;
+
+public class ConnectivityManagerMobileTest
+ extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+
+ private static final String LOG_TAG = "ConnectivityManagerMobileTest";
+ private static final String PKG_NAME = "com.android.connectivitymanagertest";
+ private static final long WIFI_CONNECTION_TIMEOUT = 30 * 1000;
+ private static final long WIFI_NOTIFICATION_TIMEOUT = 10 * 1000;
+ private String TEST_ACCESS_POINT;
+ private ConnectivityManagerTestActivity cmActivity;
+
+ public ConnectivityManagerMobileTest() {
+ super(PKG_NAME, ConnectivityManagerTestActivity.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ cmActivity = getActivity();
+ ConnectivityManagerTestRunner mRunner =
+ (ConnectivityManagerTestRunner)getInstrumentation();
+ TEST_ACCESS_POINT = mRunner.TEST_SSID;
+ // Each test case will start with cellular connection
+ verifyCellularConnection();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ // clear Wifi after each test case
+ cmActivity.clearWifi();
+ cmActivity.finish();
+ Log.v(LOG_TAG, "tear down ConnectivityManager test activity");
+ super.tearDown();
+ }
+
+ // help function to verify 3G connection
+ public void verifyCellularConnection() {
+ NetworkInfo extraNetInfo = cmActivity.mNetworkInfo;
+ assertEquals("network type is not MOBILE", ConnectivityManager.TYPE_MOBILE,
+ extraNetInfo.getType());
+ assertTrue("not connected to cellular network", extraNetInfo.isConnected());
+ assertTrue("no data connection", cmActivity.mState.equals(State.CONNECTED));
+ }
+
+ // Test case 1: Test enabling Wifi without associating with any AP
+ @LargeTest
+ public void test3GToWifiNotification() {
+ // As Wifi stays in DISCONNECTED, the connectivity manager will not broadcast
+ // any network connectivity event for Wifi
+ NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE, networkInfo.getState(),
+ NetworkState.DO_NOTHING, State.CONNECTED);
+ networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ NetworkState.DO_NOTHING, State.DISCONNECTED);
+ // Eanble Wifi
+ cmActivity.enableWifi();
+ try {
+ Thread.sleep(WIFI_NOTIFICATION_TIMEOUT);
+ } catch (Exception e) {
+ Log.v(LOG_TAG, "exception: " + e.toString());
+ }
+
+ // validate state and broadcast
+ if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ Log.v(LOG_TAG, "the state for WIFI is changed");
+ Log.v(LOG_TAG, "reason: " +
+ cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ assertTrue(false);
+ }
+ if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ Log.v(LOG_TAG, "the state for MOBILE is changed");
+ Log.v(LOG_TAG, "reason: " +
+ cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ assertTrue(false);
+ }
+ // Verify that the device is still connected to MOBILE
+ verifyCellularConnection();
+ }
+
+ // Test case 2: test connection to a given AP
+ @LargeTest
+ public void testConnectToWifi() {
+ //Prepare for connectivity verification
+ NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE, networkInfo.getState(),
+ NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
+ networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ NetworkState.TO_CONNECTION, State.CONNECTED);
+
+ // Enable Wifi and connect to a test access point
+ assertTrue("failed to connect to " + TEST_ACCESS_POINT,
+ cmActivity.connectToWifi(TEST_ACCESS_POINT));
+ try {
+ Thread.sleep(WIFI_CONNECTION_TIMEOUT);
+ } catch (Exception e) {
+ Log.v(LOG_TAG, "exception: " + e.toString());
+ }
+
+ // validate states
+ if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ Log.v(LOG_TAG, "Wifi state transition validation failed.");
+ Log.v(LOG_TAG, "reason: " +
+ cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ assertTrue(false);
+ }
+ if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ Log.v(LOG_TAG, "Mobile state transition validation failed.");
+ Log.v(LOG_TAG, "reason: " +
+ cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ assertTrue(false);
+ }
+ }
+}