summaryrefslogtreecommitdiffstats
path: root/core/tests/bandwidthtests/src
diff options
context:
space:
mode:
authorTsu Chiang Chuang <tsu@google.com>2011-07-27 15:51:49 -0700
committerTsu Chiang Chuang <tsu@google.com>2011-08-02 19:11:41 -0700
commit33f869951fde247927e66c3aa4ab86fc61f783ad (patch)
tree1345bb58f469061dfb9e676a0972aa9e21388bd9 /core/tests/bandwidthtests/src
parent5465e054d33436fa446465ebcff871f6b7e1e3cc (diff)
downloadframeworks_base-33f869951fde247927e66c3aa4ab86fc61f783ad.zip
frameworks_base-33f869951fde247927e66c3aa4ab86fc61f783ad.tar.gz
frameworks_base-33f869951fde247927e66c3aa4ab86fc61f783ad.tar.bz2
Bandwidth microbenchmark test app for ICS.
Change-Id: I6fed5c47818f0fe08b9f2c18f1070d3238a469b6
Diffstat (limited to 'core/tests/bandwidthtests/src')
-rw-r--r--core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java217
-rw-r--r--core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTestRunner.java38
-rw-r--r--core/tests/bandwidthtests/src/com/android/bandwidthtest/NetworkState.java257
-rw-r--r--core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java109
-rw-r--r--core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java684
5 files changed, 1305 insertions, 0 deletions
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
new file mode 100644
index 0000000..73c92b0
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2011, 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.bandwidthtest;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo.State;
+import android.net.NetworkStats;
+import android.net.TrafficStats;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Process;
+import android.os.SystemClock;
+import android.telephony.TelephonyManager;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import com.android.bandwidthtest.util.BandwidthTestUtil;
+import com.android.bandwidthtest.util.ConnectionUtil;
+
+import java.io.File;
+
+/**
+ * Test that downloads files from a test server and reports the bandwidth metrics collected.
+ */
+public class BandwidthTest extends InstrumentationTestCase {
+
+ private static final String LOG_TAG = "BandwidthTest";
+ private final static String PROF_LABEL = "PROF_";
+ private final static String PROC_LABEL = "PROC_";
+ private final static int INSTRUMENTATION_IN_PROGRESS = 2;
+
+ private final static String BASE_DIR =
+ Environment.getExternalStorageDirectory().getAbsolutePath();
+ private final static String TMP_FILENAME = "tmp.dat";
+ // Download 10.486 * 106 bytes (+ headers) from app engine test server.
+ private final int FILE_SIZE = 10485613;
+ private Context mContext;
+ private ConnectionUtil mConnectionUtil;
+ private TelephonyManager mTManager;
+ private int mUid;
+ private String mSsid;
+ private String mTestServer;
+ private String mDeviceId;
+ private BandwidthTestRunner mRunner;
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mRunner = (BandwidthTestRunner) getInstrumentation();
+ mSsid = mRunner.mSsid;
+ mTestServer = mRunner.mTestServer;
+ mContext = mRunner.getTargetContext();
+ mConnectionUtil = new ConnectionUtil(mContext);
+ mConnectionUtil.initialize();
+ Log.v(LOG_TAG, "Initialized mConnectionUtil");
+ mUid = Process.myUid();
+ mTManager = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ mDeviceId = mTManager.getDeviceId();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mConnectionUtil.cleanUp();
+ super.tearDown();
+ }
+
+ /**
+ * Ensure that downloading on wifi reports reasonable stats.
+ */
+ @LargeTest
+ public void testWifiDownload() {
+ assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+ NetworkStats pre_test_stats = fetchDataFromProc(mUid);
+ String ts = Long.toString(System.currentTimeMillis());
+
+ String targetUrl = BandwidthTestUtil.buildDownloadUrl(
+ mTestServer, FILE_SIZE, mDeviceId, ts);
+ TrafficStats.startDataProfiling(mContext);
+ File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
+ assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
+ NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
+
+ NetworkStats post_test_stats = fetchDataFromProc(mUid);
+ NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
+
+ // Output measurements to instrumentation out, so that it can be compared to that of
+ // the server.
+ Bundle results = new Bundle();
+ results.putString("device_id", mDeviceId);
+ results.putString("timestamp", ts);
+ results.putInt("size", FILE_SIZE);
+ AddStatsToResults(PROF_LABEL, prof_stats, results);
+ AddStatsToResults(PROC_LABEL, proc_stats, results);
+ getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
+
+ // Clean up.
+ assertTrue(cleanUpFile(tmpSaveFile));
+ }
+
+ /**
+ * We want to make sure that if we use the Download Manager to download stuff,
+ * accounting still goes to the app making the call and that the numbers still make sense.
+ */
+ @LargeTest
+ public void testWifiDownloadWithDownloadManager() {
+ assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+ // If we are using the download manager, then the data that is written to /proc/uid_stat/
+ // is accounted against download manager's uid, since it uses pre-ICS API.
+ int downloadManagerUid = mConnectionUtil.downloadManagerUid();
+ assertTrue(downloadManagerUid >= 0);
+ NetworkStats pre_test_stats = fetchDataFromProc(downloadManagerUid);
+ // start profiling
+ TrafficStats.startDataProfiling(mContext);
+ String ts = Long.toString(System.currentTimeMillis());
+ String targetUrl = BandwidthTestUtil.buildDownloadUrl(
+ mTestServer, FILE_SIZE, mDeviceId, ts);
+ Log.v(LOG_TAG, "Download url: " + targetUrl);
+ File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
+ assertTrue(mConnectionUtil.startDownloadAndWait(targetUrl, 500000));
+ NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
+ NetworkStats post_test_stats = fetchDataFromProc(downloadManagerUid);
+ NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
+
+ // Output measurements to instrumentation out, so that it can be compared to that of
+ // the server.
+ Bundle results = new Bundle();
+ results.putString("device_id", mDeviceId);
+ results.putString("timestamp", ts);
+ results.putInt("size", FILE_SIZE);
+ AddStatsToResults(PROF_LABEL, prof_stats, results);
+ AddStatsToResults(PROC_LABEL, proc_stats, results);
+ getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
+
+ // Clean up.
+ assertTrue(cleanUpFile(tmpSaveFile));
+ }
+
+ /**
+ * Fetch network data from /proc/uid_stat/uid
+ * @return populated {@link NetworkStats}
+ */
+ public NetworkStats fetchDataFromProc(int uid) {
+ String root_filepath = "/proc/uid_stat/" + uid + "/";
+ File rcv_stat = new File (root_filepath + "tcp_rcv");
+ int rx = BandwidthTestUtil.parseIntValueFromFile(rcv_stat);
+ File snd_stat = new File (root_filepath + "tcp_snd");
+ int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
+ NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
+ stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.TAG_NONE, rx, 0, tx, 0);
+ return stats;
+ }
+
+ /**
+ * Turn on Airplane mode and connect to the wifi
+ * @param ssid of the wifi to connect to
+ * @return true if we successfully connected to a given network.
+ */
+ public boolean setDeviceWifiAndAirplaneMode(String ssid) {
+ mConnectionUtil.setAirplaneMode(mContext, true);
+ assertTrue(mConnectionUtil.connectToWifi(ssid));
+ assertTrue(mConnectionUtil.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+ ConnectionUtil.LONG_TIMEOUT));
+ return mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ ConnectionUtil.LONG_TIMEOUT);
+ }
+
+ /**
+ * Output the {@link NetworkStats} to Instrumentation out.
+ * @param label to attach to this given stats.
+ * @param stats {@link NetworkStats} to add.
+ * @param results {@link Bundle} to be added to.
+ */
+ public void AddStatsToResults(String label, NetworkStats stats, Bundle results){
+ if (results == null || results.isEmpty()) {
+ Log.e(LOG_TAG, "Empty bundle provided.");
+ return;
+ }
+ for (int i = 0; i < stats.size(); ++i) {
+ android.net.NetworkStats.Entry entry = stats.getValues(i, null);
+ results.putInt(label + "uid", entry.uid);
+ results.putString(label + "iface", entry.iface);
+ results.putInt(label + "tag", entry.tag);
+ results.putLong(label + "tx", entry.txBytes);
+ results.putLong(label + "rx", entry.rxBytes);
+ }
+ }
+
+ /**
+ * Remove file if it exists.
+ * @param file {@link File} to delete.
+ * @return true if successfully deleted the file.
+ */
+ private boolean cleanUpFile(File file) {
+ if (file.exists()) {
+ return file.delete();
+ }
+ return true;
+ }
+} \ No newline at end of file
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTestRunner.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTestRunner.java
new file mode 100644
index 0000000..290ccee
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTestRunner.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011, 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.bandwidthtest;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+
+public class BandwidthTestRunner extends InstrumentationTestRunner {
+ public String mSsid = "wifi-ssid";
+ public String mTestServer = "http://www.sometestserver.com";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ String ssidStr= (String) icicle.get("ssid");
+ if (ssidStr != null) {
+ mSsid = ssidStr;
+ }
+ String serverStr = (String) icicle.get("server");
+ if (serverStr != null) {
+ mTestServer = serverStr;
+ }
+ }
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/NetworkState.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/NetworkState.java
new file mode 100644
index 0000000..fae0e76
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/NetworkState.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2011 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.bandwidthtest;
+
+import android.net.NetworkInfo.State;
+import android.util.Log;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Data structure to keep track of the network state transitions.
+ */
+public class NetworkState {
+ /**
+ * Desired direction of state transition.
+ */
+ public enum StateTransitionDirection {
+ TO_DISCONNECTION, TO_CONNECTION, DO_NOTHING
+ }
+ private final String LOG_TAG = "NetworkState";
+ private List<State> mStateDepository;
+ private State mTransitionTarget;
+ private StateTransitionDirection mTransitionDirection;
+ private String mReason = null; // record mReason of state transition failure
+
+ public NetworkState() {
+ mStateDepository = new ArrayList<State>();
+ mTransitionDirection = StateTransitionDirection.DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ public NetworkState(State currentState) {
+ mStateDepository = new ArrayList<State>();
+ mStateDepository.add(currentState);
+ mTransitionDirection = StateTransitionDirection.DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ /**
+ * Reinitialize the network state
+ */
+ public void resetNetworkState() {
+ mStateDepository.clear();
+ mTransitionDirection = StateTransitionDirection.DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ /**
+ * Set the transition criteria
+ * @param initState initial {@link State}
+ * @param transitionDir explicit {@link StateTransitionDirection}
+ * @param targetState desired {@link State}
+ */
+ public void setStateTransitionCriteria(State initState, StateTransitionDirection transitionDir,
+ State targetState) {
+ if (!mStateDepository.isEmpty()) {
+ mStateDepository.clear();
+ }
+ mStateDepository.add(initState);
+ mTransitionDirection = transitionDir;
+ mTransitionTarget = targetState;
+ Log.v(LOG_TAG, "setStateTransitionCriteria: " + printStates());
+ }
+
+ /**
+ * Record the current state of the network
+ * @param currentState the current {@link State}
+ */
+ public void recordState(State currentState) {
+ mStateDepository.add(currentState);
+ }
+
+ /**
+ * Verify the state transition
+ * @return true if the requested transition completed successfully.
+ */
+ public boolean validateStateTransition() {
+ Log.v(LOG_TAG, String.format("Print state depository: %s", printStates()));
+ switch (mTransitionDirection) {
+ case DO_NOTHING:
+ Log.v(LOG_TAG, "No direction requested, verifying network states");
+ return validateNetworkStates();
+ case TO_CONNECTION:
+ Log.v(LOG_TAG, "Transition to CONNECTED");
+ return validateNetworkConnection();
+ case TO_DISCONNECTION:
+ Log.v(LOG_TAG, "Transition to DISCONNECTED");
+ return validateNetworkDisconnection();
+ default:
+ Log.e(LOG_TAG, "Invalid transition direction.");
+ return false;
+ }
+ }
+
+ /**
+ * Verify that network states are valid
+ * @return false if any of the states are invalid
+ */
+ private boolean validateNetworkStates() {
+ 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, String.format("%s is expected, but it is %s",
+ mTransitionTarget.toString(),
+ mStateDepository.get(0).toString()));
+ mReason = String.format("%s is expected, but it is %s",
+ mTransitionTarget.toString(),
+ mStateDepository.get(0).toString());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Verify the network state to disconnection
+ * @return false if any of the state transitions were not valid
+ */
+ private boolean validateNetworkDisconnection() {
+ // Transition from CONNECTED -> DISCONNECTED: CONNECTED->DISCONNECTING->DISCONNECTED
+ StringBuffer str = new StringBuffer ("States: ");
+ str.append(printStates());
+ if (mStateDepository.get(0) != State.CONNECTED) {
+ str.append(String.format(" Initial state should be CONNECTED, but it is %s.",
+ mStateDepository.get(0)));
+ mReason = str.toString();
+ return false;
+ }
+ State lastState = mStateDepository.get(mStateDepository.size() - 1);
+ if ( lastState != mTransitionTarget) {
+ str.append(String.format(" Last state should be DISCONNECTED, but it is %s",
+ lastState));
+ mReason = str.toString();
+ 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 {
+ str.append(String.format(" Transition state from %s to %s is not valid",
+ preState.toString(), curState.toString()));
+ mReason = str.toString();
+ return false;
+ }
+ }
+ mReason = str.toString();
+ return true;
+ }
+
+ /**
+ * Verify the network state to connection
+ * @return false if any of the state transitions were not valid
+ */
+ private boolean validateNetworkConnection() {
+ StringBuffer str = new StringBuffer("States ");
+ str.append(printStates());
+ if (mStateDepository.get(0) != State.DISCONNECTED) {
+ str.append(String.format(" Initial state should be DISCONNECTED, but it is %s.",
+ mStateDepository.get(0)));
+ mReason = str.toString();
+ return false;
+ }
+ State lastState = mStateDepository.get(mStateDepository.size() - 1);
+ if ( lastState != mTransitionTarget) {
+ str.append(String.format(" Last state should be %s, but it is %s", mTransitionTarget,
+ lastState));
+ mReason = str.toString();
+ 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) || (curState == State.DISCONNECTED))) {
+ continue;
+ } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
+ continue;
+ } else if ((preState == State.CONNECTED) && (curState == State.CONNECTED)) {
+ continue;
+ } else {
+ str.append(String.format(" Transition state from %s to %s is not valid.",
+ preState.toString(), curState.toString()));
+ mReason = str.toString();
+ return false;
+ }
+ }
+ mReason = str.toString();
+ return true;
+ }
+
+ /**
+ * Fetch the different network state transitions
+ * @return {@link List} of {@link State}
+ */
+ public List<State> getTransitionStates() {
+ return mStateDepository;
+ }
+
+ /**
+ * Fetch the reason for network state transition failure
+ * @return the {@link String} for the failure
+ */
+ public String getFailureReason() {
+ return mReason;
+ }
+
+ /**
+ * Print the network state
+ * @return {@link String} representation of the network state
+ */
+ 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();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("mTransitionDirection: ").append(mTransitionDirection.toString()).
+ append("; ").append("states:").
+ append(printStates()).append("; ");
+ return builder.toString();
+ }
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java
new file mode 100644
index 0000000..d850169
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011, 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.bandwidthtest.util;
+
+import android.util.Log;
+
+import org.apache.http.util.ByteArrayBuffer;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+
+public class BandwidthTestUtil {
+ private static final String LOG_TAG = "BandwidthTestUtil";
+ /**
+ * Parses the first line in a file if exists.
+ *
+ * @param file {@link File} the input
+ * @return the integer value of the first line of the file.
+ */
+ public static int parseIntValueFromFile(File file) {
+ int value = 0;
+ if (file.exists()) {
+ try {
+ FileInputStream fstream = new FileInputStream(file);
+ DataInputStream in = new DataInputStream(fstream);
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String strLine = br.readLine();
+ if (strLine != null) {
+ value = Integer.parseInt(strLine);
+ }
+ // Close the input stream
+ in.close();
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Creates the Download string for the test server.
+ *
+ * @param server url of the test server
+ * @param size in bytes of the file to download
+ * @param deviceId the device id that is downloading
+ * @param timestamp
+ * @return download url
+ */
+ public static String buildDownloadUrl(String server, int size, String deviceId,
+ String timestamp) {
+ String downloadUrl = server + "/download?size=" + size + "&device_id=" + deviceId +
+ "&timestamp=" + timestamp;
+ return downloadUrl;
+ }
+
+ /**
+ * Download a given file from a target url to a given destination file.
+ * @param targetUrl the url to download
+ * @param file the {@link File} location where to save to
+ * @return true if it succeeded.
+ */
+ public static boolean DownloadFromUrl(String targetUrl, File file) {
+ try {
+ URL url = new URL(targetUrl);
+ Log.d(LOG_TAG, "Download begining");
+ Log.d(LOG_TAG, "Download url:" + url);
+ Log.d(LOG_TAG, "Downloaded file name:" + file.getAbsolutePath());
+ URLConnection ucon = url.openConnection();
+ InputStream is = ucon.getInputStream();
+ BufferedInputStream bis = new BufferedInputStream(is);
+ ByteArrayBuffer baf = new ByteArrayBuffer(50);
+ int current = 0;
+ while ((current = bis.read()) != -1) {
+ baf.append((byte) current);
+ }
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(baf.toByteArray());
+ fos.close();
+ } catch (IOException e) {
+ Log.d(LOG_TAG, "Failed to download file with error: " + e);
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
new file mode 100644
index 0000000..d663aad
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2011, 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.bandwidthtest.util;
+
+import android.app.DownloadManager;
+import android.app.DownloadManager.Query;
+import android.app.DownloadManager.Request;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.net.Uri;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.bandwidthtest.NetworkState;
+import com.android.bandwidthtest.NetworkState.StateTransitionDirection;
+import com.android.internal.util.AsyncChannel;
+
+import java.util.List;
+
+/*
+ * Utility class used to set the connectivity of the device and to download files.
+ */
+public class ConnectionUtil {
+ private static final String LOG_TAG = "ConnectionUtil";
+ private static final String DOWNLOAD_MANAGER_PKG_NAME = "com.android.providers.downloads";
+ private static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; // 10 seconds
+ private static final int WIFI_SCAN_TIMEOUT = 50 * 1000;
+ public static final int SHORT_TIMEOUT = 5 * 1000;
+ public static final int LONG_TIMEOUT = 10 * 1000;
+ private ConnectivityReceiver mConnectivityReceiver = null;
+ private WifiReceiver mWifiReceiver = null;
+ private DownloadReceiver mDownloadReceiver = null;
+ private DownloadManager mDownloadManager;
+ private NetworkInfo mNetworkInfo;
+ private NetworkInfo mOtherNetworkInfo;
+ private boolean mScanResultIsAvailable = false;
+ private ConnectivityManager mCM;
+ private Object mWifiMonitor = new Object();
+ private Object mConnectivityMonitor = new Object();
+ private Object mDownloadMonitor = new Object();
+ private int mWifiState;
+ private NetworkInfo mWifiNetworkInfo;
+ private WifiManager mWifiManager;
+ private Context mContext;
+ // Verify connectivity state
+ private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
+ private NetworkState[] mConnectivityState = new NetworkState[NUM_NETWORK_TYPES];
+
+ public ConnectionUtil(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Initialize the class. Needs to be called before any other methods in {@link ConnectionUtil}
+ *
+ * @throws Exception
+ */
+ public void initialize() throws Exception {
+ // Register a connectivity receiver for CONNECTIVITY_ACTION
+ mConnectivityReceiver = new ConnectivityReceiver();
+ mContext.registerReceiver(mConnectivityReceiver,
+ new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+
+ // Register a download receiver for ACTION_DOWNLOAD_COMPLETE
+ mDownloadReceiver = new DownloadReceiver();
+ mContext.registerReceiver(mDownloadReceiver,
+ new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
+
+ // Register a wifi receiver
+ 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);
+ mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
+ mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+ mContext.registerReceiver(mWifiReceiver, mIntentFilter);
+
+ // Get an instance of ConnectivityManager
+ mCM = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ // Get an instance of WifiManager
+ mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
+ mWifiManager.asyncConnect(mContext, new WifiServiceHandler());
+
+ mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
+
+ initializeNetworkStates();
+
+ mWifiManager.setWifiEnabled(true);
+
+ Log.v(LOG_TAG, "Clear Wifi before we start the test.");
+ sleep(SHORT_TIMEOUT);
+ removeConfiguredNetworksAndDisableWifi();
+ }
+
+
+ /**
+ * A wrapper of a broadcast receiver which provides network connectivity information
+ * for all kinds of network: wifi, mobile, etc.
+ */
+ private class ConnectivityReceiver extends BroadcastReceiver {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (isInitialStickyBroadcast()) {
+ Log.d(LOG_TAG, "This is a sticky broadcast don't do anything.");
+ return;
+ }
+ 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;
+ }
+ if (intent.hasExtra(ConnectivityManager.EXTRA_NETWORK_INFO)) {
+ mNetworkInfo = (NetworkInfo)
+ intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
+ }
+
+ if (intent.hasExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO)) {
+ mOtherNetworkInfo = (NetworkInfo)
+ intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
+ }
+
+ Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString());
+ recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
+ if (mOtherNetworkInfo != null) {
+ Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString());
+ recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
+ }
+ notifyNetworkConnectivityChange();
+ }
+ }
+
+ /**
+ * A wrapper of a broadcast receiver which provides wifi information.
+ */
+ private class WifiReceiver extends BroadcastReceiver {
+ /**
+ * {@inheritDoc}
+ */
+ @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)) {
+ Log.v(LOG_TAG, "Scan results are available");
+ 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) {
+ 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 if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
+ notifyWifiAPState();
+ } else {
+ return;
+ }
+ }
+ }
+
+ /**
+ * A wrapper of a broadcast receiver which provides download manager information.
+ */
+ private class DownloadReceiver extends BroadcastReceiver {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ Log.v("DownloadReceiver", "onReceive() is called with " + intent);
+ // Download complete
+ if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
+ notifiyDownloadState();
+ }
+ }
+ }
+
+ private class WifiServiceHandler extends Handler {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ // AsyncChannel in msg.obj
+ } else {
+ Log.v(LOG_TAG, "Failed to establish AsyncChannel connection");
+ }
+ break;
+ default:
+ // Ignore
+ break;
+ }
+ }
+ }
+
+ /**
+ * Initialize all the network states.
+ */
+ public void initializeNetworkStates() {
+ // For each network type, initialize network states to UNKNOWN, and no verification
+ // flag is set.
+ for (int networkType = NUM_NETWORK_TYPES - 1; networkType >= 0; networkType--) {
+ mConnectivityState[networkType] = new NetworkState();
+ Log.v(LOG_TAG, "Initialize network state for " + networkType + ": " +
+ mConnectivityState[networkType].toString());
+ }
+ }
+
+ public void recordNetworkState(int networkType, State networkState) {
+ // deposit a network state
+ Log.v(LOG_TAG, "record network state for network " + networkType +
+ ", state is " + networkState);
+ mConnectivityState[networkType].recordState(networkState);
+ }
+
+ /**
+ * Set the state transition criteria
+ *
+ * @param networkType
+ * @param initState
+ * @param transitionDir
+ * @param targetState
+ */
+ public void setStateTransitionCriteria(int networkType, State initState,
+ StateTransitionDirection transitionDir, State targetState) {
+ mConnectivityState[networkType].setStateTransitionCriteria(
+ initState, transitionDir, targetState);
+ }
+
+ /**
+ * Validate the states recorded.
+ * @param networkType
+ * @return
+ */
+ public boolean validateNetworkStates(int networkType) {
+ Log.v(LOG_TAG, "validate network state for " + networkType + ": ");
+ return mConnectivityState[networkType].validateStateTransition();
+ }
+
+ /**
+ * Fetch the failure reason for the transition.
+ * @param networkType
+ * @return result from network state validation
+ */
+ public String getTransitionFailureReason(int networkType) {
+ Log.v(LOG_TAG, "get network state transition failure reason for " + networkType + ": " +
+ mConnectivityState[networkType].toString());
+ return mConnectivityState[networkType].getFailureReason();
+ }
+
+ /**
+ * Send a notification via the mConnectivityMonitor when the network connectivity changes.
+ */
+ private void notifyNetworkConnectivityChange() {
+ synchronized(mConnectivityMonitor) {
+ Log.v(LOG_TAG, "notify network connectivity changed");
+ mConnectivityMonitor.notifyAll();
+ }
+ }
+
+ /**
+ * Send a notification when a scan for the wifi network is done.
+ */
+ private void notifyScanResult() {
+ synchronized (this) {
+ Log.v(LOG_TAG, "notify that scan results are available");
+ this.notify();
+ }
+ }
+
+ /**
+ * Send a notification via the mWifiMonitor when the wifi state changes.
+ */
+ private void notifyWifiState() {
+ synchronized (mWifiMonitor) {
+ Log.v(LOG_TAG, "notify wifi state changed.");
+ mWifiMonitor.notify();
+ }
+ }
+
+ /**
+ * Send a notification via the mDownloadMonitor when a download is complete.
+ */
+ private void notifiyDownloadState() {
+ synchronized (mDownloadMonitor) {
+ Log.v(LOG_TAG, "notifiy download manager state changed.");
+ mDownloadMonitor.notify();
+ }
+ }
+
+ /**
+ * Send a notification when the wifi ap state changes.
+ */
+ private void notifyWifiAPState() {
+ synchronized (this) {
+ Log.v(LOG_TAG, "notify wifi AP state changed.");
+ this.notify();
+ }
+ }
+
+ /**
+ * Start a download on a given url and wait for completion.
+ *
+ * @param targetUrl the target to download.x
+ * @param timeout to wait for download to finish
+ * @return true if we successfully downloaded the requestedUrl, false otherwise.
+ */
+ public boolean startDownloadAndWait(String targetUrl, long timeout) {
+ if (targetUrl.length() == 0 || targetUrl == null) {
+ Log.v(LOG_TAG, "Empty or Null target url requested to DownloadManager");
+ return true;
+ }
+ Request request = new Request(Uri.parse(targetUrl));
+ long enqueue = mDownloadManager.enqueue(request);
+ Log.v(LOG_TAG, "Sending download request of " + targetUrl + " to DownloadManager");
+ long startTime = System.currentTimeMillis();
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ Log.v(LOG_TAG, "startDownloadAndWait timed out, failed to fetch " + targetUrl +
+ " within " + timeout);
+ return downloadSuccessful(enqueue);
+ }
+ Log.v(LOG_TAG, "Waiting for the download to finish " + targetUrl);
+ synchronized (mDownloadMonitor) {
+ try {
+ mDownloadMonitor.wait(SHORT_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (!downloadSuccessful(enqueue)) {
+ continue;
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Fetch the Download Manager's UID.
+ * @return the Download Manager's UID
+ */
+ public int downloadManagerUid() {
+ try {
+ PackageManager pm = mContext.getPackageManager();
+ ApplicationInfo appInfo = pm.getApplicationInfo(DOWNLOAD_MANAGER_PKG_NAME,
+ PackageManager.GET_META_DATA);
+ return appInfo.uid;
+ } catch (NameNotFoundException e) {
+ Log.d(LOG_TAG, "Did not find the package for the download service.");
+ return -1;
+ }
+ }
+
+ /**
+ * Determines if a given download was successful by querying the DownloadManager.
+ *
+ * @param enqueue the id used to identify/query the DownloadManager with.
+ * @return true if download was successful, false otherwise.
+ */
+ private boolean downloadSuccessful(long enqueue) {
+ Query query = new Query();
+ query.setFilterById(enqueue);
+ Cursor c = mDownloadManager.query(query);
+ if (c.moveToFirst()) {
+ int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
+ if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
+ Log.v(LOG_TAG, "Successfully downloaded file!");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Wait for network connectivity state.
+ * @param networkType the network to check for
+ * @param expectedState the desired state
+ * @param timeout in milliseconds
+ * @return true if the network connectivity state matched what was expected
+ */
+ public boolean waitForNetworkState(int networkType, State expectedState, long timeout) {
+ long startTime = System.currentTimeMillis();
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ Log.v(LOG_TAG, "waitForNetworkState time out, the state of network type " + networkType +
+ " is: " + mCM.getNetworkInfo(networkType).getState());
+ 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 (mConnectivityMonitor) {
+ try {
+ mConnectivityMonitor.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 a given wifi state to occur within a given timeout.
+ * @param expectedState the expected wifi state.
+ * @param timeout for the state to be set in milliseconds.
+ * @return true if the state was achieved within the timeout, false otherwise.
+ */
+ public boolean waitForWifiState(int expectedState, long timeout) {
+ // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
+ // WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
+ 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 (mWifiMonitor) {
+ try {
+ mWifiMonitor.wait(SHORT_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (mWifiState != expectedState) {
+ Log.v(LOG_TAG, "Wifi state is: " + mWifiState);
+ continue;
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Convenience method to determine if we are connected to a mobile network.
+ * @return true if connected to a mobile network, false otherwise.
+ */
+ public boolean isConnectedToMobile() {
+ return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
+ }
+
+ /**
+ * Convenience method to determine if we are connected to wifi.
+ * @return true if connected to wifi, false otherwise.
+ */
+ public boolean isConnectedToWifi() {
+ return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
+ }
+
+
+ /**
+ * 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) {
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = knownSSID;
+ config.allowedKeyManagement.set(KeyMgmt.NONE);
+ return connectToWifiWithConfiguration(config);
+ }
+
+ /**
+ * Connect to Wi-Fi with the given configuration.
+ * @param config
+ * @return true if we ar connected to a given
+ */
+ public boolean connectToWifiWithConfiguration(WifiConfiguration config) {
+ // The SSID in the configuration is a pure string, need to convert it to a quoted string.
+ 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");
+ mWifiManager.setWifiEnabled(true);
+ // wait for the wifi state change before start scanning.
+ if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2 * SHORT_TIMEOUT)) {
+ Log.v(LOG_TAG, "Wait for WIFI_STATE_ENABLED failed");
+ return false;
+ }
+ }
+
+ boolean foundApInScanResults = false;
+ for (int retry = 0; retry < 5; retry++) {
+ List<ScanResult> netList = mWifiManager.getScanResults();
+ if (netList != null) {
+ Log.v(LOG_TAG, "size of scan result list: " + netList.size());
+ for (int i = 0; i < netList.size(); i++) {
+ ScanResult sr= netList.get(i);
+ if (sr.SSID.equals(ssid)) {
+ Log.v(LOG_TAG, "Found " + ssid + " in the scan result list.");
+ Log.v(LOG_TAG, "Retry: " + retry);
+ foundApInScanResults = true;
+ mWifiManager.connectNetwork(config);
+ break;
+ }
+ }
+ }
+ if (foundApInScanResults) {
+ return true;
+ } else {
+ // Start an active scan
+ mWifiManager.startScanActive();
+ mScanResultIsAvailable = false;
+ long startTime = System.currentTimeMillis();
+ while (!mScanResultIsAvailable) {
+ if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
+ Log.v(LOG_TAG, "wait for scan results 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;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Disconnect from the current AP and remove configured networks.
+ */
+ public boolean disconnectAP() {
+ // remove saved networks
+ List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
+ Log.v(LOG_TAG, "size of wifiConfigList: " + wifiConfigList.size());
+ for (WifiConfiguration wifiConfig: wifiConfigList) {
+ Log.v(LOG_TAG, "Remove wifi configuration: " + wifiConfig.networkId);
+ int netId = wifiConfig.networkId;
+ mWifiManager.forgetNetwork(netId);
+ }
+ return true;
+ }
+
+ /**
+ * Enable Wifi
+ * @return true if Wifi is enabled successfully
+ */
+ public boolean enableWifi() {
+ return mWifiManager.setWifiEnabled(true);
+ }
+
+ /**
+ * Disable Wifi
+ * @return true if Wifi is disabled successfully
+ */
+ public boolean disableWifi() {
+ return mWifiManager.setWifiEnabled(false);
+ }
+
+ /**
+ * Remove configured networks and disable wifi
+ */
+ public boolean removeConfiguredNetworksAndDisableWifi() {
+ if (!disconnectAP()) {
+ return false;
+ }
+ sleep(SHORT_TIMEOUT);
+ if (!mWifiManager.setWifiEnabled(false)) {
+ return false;
+ }
+ sleep(SHORT_TIMEOUT);
+ return true;
+ }
+
+ /**
+ * Make the current thread sleep.
+ * @param sleeptime the time to sleep in milliseconds
+ */
+ private void sleep(long sleeptime) {
+ try {
+ Thread.sleep(sleeptime);
+ } catch (InterruptedException e) {}
+ }
+
+ /**
+ * Set airplane mode on device, caller is responsible to ensuring correct state.
+ * @param context {@link Context}
+ * @param enableAM to enable or disable 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);
+ }
+
+ /**
+ * Add quotes around the string.
+ * @param string to convert
+ * @return string with quotes around it
+ */
+ protected static String convertToQuotedString(String string) {
+ return "\"" + string + "\"";
+ }
+
+ public void cleanUp() {
+ // Unregister receivers if defined.
+ if (mConnectivityReceiver != null) {
+ mContext.unregisterReceiver(mConnectivityReceiver);
+ }
+ if (mWifiReceiver != null) {
+ mContext.unregisterReceiver(mWifiReceiver);
+ }
+ if (mDownloadReceiver != null) {
+ mContext.unregisterReceiver(mDownloadReceiver);
+ }
+ Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
+ }
+} \ No newline at end of file