ConnectivityManagerTestActivity.java revision 27284da88c4552c5be4c8eff8acd36b518da47da
1fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang/*
2fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * Copyright (C) 2010, The Android Open Source Project
3fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang *
4fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * Licensed under the Apache License, Version 2.0 (the "License");
5fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * you may not use this file except in compliance with the License.
6fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * You may obtain a copy of the License at
7fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang *
8fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang *      http://www.apache.org/licenses/LICENSE-2.0
9fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang *
10fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * Unless required by applicable law or agreed to in writing, software
11fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * distributed under the License is distributed on an "AS IS" BASIS,
12fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * See the License for the specific language governing permissions and
14fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang * limitations under the License.
15fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang */
16fc2dbd04005c32360eead803e29df3cc62209cd8Xia Wang
177fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangpackage com.android.connectivitymanagertest;
187fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
197fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.app.Activity;
207fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.content.Context;
217fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.content.BroadcastReceiver;
227fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.content.Intent;
237fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.content.IntentFilter;
24ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.ConnectivityManager;
25ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.NetworkInfo;
26ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.NetworkInfo.State;
27ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.wifi.WifiConfiguration;
28ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.wifi.WifiManager;
29ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.wifi.WifiInfo;
30ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.wifi.ScanResult;
31ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.net.wifi.WifiConfiguration.KeyMgmt;
327fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.os.Bundle;
33ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.os.Handler;
3473055f12d7764e322f3f83717525a2dba01f9ef9Xia Wangimport android.os.IPowerManager;
35ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.os.Message;
3673055f12d7764e322f3f83717525a2dba01f9ef9Xia Wangimport android.os.PowerManager;
3773055f12d7764e322f3f83717525a2dba01f9ef9Xia Wangimport android.os.ServiceManager;
3873055f12d7764e322f3f83717525a2dba01f9ef9Xia Wangimport android.os.SystemClock;
397fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.provider.Settings;
407fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport android.util.Log;
41ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lauimport android.view.KeyEvent;
42ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.widget.LinearLayout;
43ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff
44ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport com.android.internal.util.AsyncChannel;
45ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang
466bffe14c78efa0b56327262543ce2e0dfc024219Xia Wangimport java.io.IOException;
47ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wangimport java.io.InputStream;
486bffe14c78efa0b56327262543ce2e0dfc024219Xia Wangimport java.net.UnknownHostException;
49ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wangimport java.util.ArrayList;
507fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangimport java.util.List;
517fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
527fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
537fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang/**
547fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang * An activity registered with connectivity manager broadcast
557fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang * provides network connectivity information and
567fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang * can be used to set device states: Cellular, Wifi, Airplane mode.
577fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang */
587fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wangpublic class ConnectivityManagerTestActivity extends Activity {
597fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
607fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public static final String LOG_TAG = "ConnectivityManagerTestActivity";
61ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds
62a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang    public static final int WIFI_SCAN_TIMEOUT = 50 * 1000;
63ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public static final int SHORT_TIMEOUT = 5 * 1000;
64ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public static final long LONG_TIMEOUT = 50 * 1000;
65a4c2caac05009512213454d329579a79dde11e5fXia Wang    // 2 minutes timer between wifi stop and start
66a4c2caac05009512213454d329579a79dde11e5fXia Wang    public static final long  WIFI_STOP_START_INTERVAL = 2 * 60 * 1000;
676026d52710d7a6195a33885020d29aa1330fa855Xia Wang    public static final int SUCCESS = 0;  // for Wifi tethering state change
686026d52710d7a6195a33885020d29aa1330fa855Xia Wang    public static final int FAILURE = 1;
696026d52710d7a6195a33885020d29aa1330fa855Xia Wang    public static final int INIT = -1;
70ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    private static final String ACCESS_POINT_FILE = "accesspoints.xml";
717fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public ConnectivityReceiver mConnectivityReceiver = null;
727fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public WifiReceiver mWifiReceiver = null;
73a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang    private AccessPointParserHelper mParseHelper = null;
747fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    /*
757fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * Track network connectivity information
767fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     */
777fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public State mState;
787fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public NetworkInfo mNetworkInfo;
797fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public NetworkInfo mOtherNetworkInfo;
807fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public boolean mIsFailOver;
817fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public String mReason;
827fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public boolean mScanResultIsAvailable = false;
837fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public ConnectivityManager mCM;
842c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public Object wifiObject = new Object();
852c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public Object connectivityObject = new Object();
862c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public int mWifiState;
872c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public NetworkInfo mWifiNetworkInfo;
882c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public String mBssid;
893d273da8fa08ddcb16b8fefa35aff10b45778ddcYu Shan Emily Lau    public String mPowerSsid = "opennet"; //Default power SSID
90ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    private Context mContext;
9190e1c782a63475cd9b3973936decf6a4f6c6148fXia Wang    public boolean scanResultAvailable = false;
927fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
937fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    /*
947fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * Control Wifi States
957fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     */
967fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public WifiManager mWifiManager;
97d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public WifiManager.Channel mChannel;
987fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
997fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    /*
1007fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * Verify connectivity state
1017fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     */
1022c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
1037fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES];
1047fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
1056026d52710d7a6195a33885020d29aa1330fa855Xia Wang    // For wifi tethering tests
1066026d52710d7a6195a33885020d29aa1330fa855Xia Wang    private String[] mWifiRegexs;
1076026d52710d7a6195a33885020d29aa1330fa855Xia Wang    public int mWifiTetherResult = INIT;    // -1 is initialization state
1086026d52710d7a6195a33885020d29aa1330fa855Xia Wang
1097fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    /**
1107fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * A wrapper of a broadcast receiver which provides network connectivity information
1117fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * for all kinds of network: wifi, mobile, etc.
1127fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     */
1137fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    private class ConnectivityReceiver extends BroadcastReceiver {
1147fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        @Override
1157fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        public void onReceive(Context context, Intent intent) {
116a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("ConnectivityReceiver: onReceive() is called with " + intent);
1177fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            String action = intent.getAction();
1187fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
1197fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                Log.v("ConnectivityReceiver", "onReceive() called with " + intent);
1207fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                return;
1217fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            }
1227fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
1237fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            boolean noConnectivity =
1247fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
1257fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
1267fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            if (noConnectivity) {
1277fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                mState = State.DISCONNECTED;
1287fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            } else {
1297fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                mState = State.CONNECTED;
1307fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            }
1317fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
1327fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            mNetworkInfo = (NetworkInfo)
1337fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
1347fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
1357fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            mOtherNetworkInfo = (NetworkInfo)
1367fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
1377fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
1387fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
1397fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            mIsFailOver = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
1402c15966f8cf6160ad5dcbbde372508de89985829Xia Wang
141a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("mNetworkInfo: " + mNetworkInfo.toString());
1422c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            if (mOtherNetworkInfo != null) {
143a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                log("mOtherNetworkInfo: " + mOtherNetworkInfo.toString());
1442c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            }
1457fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
1467fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            if (mOtherNetworkInfo != null) {
1477fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
1487fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            }
1492c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            notifyNetworkConnectivityChange();
1507fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
1517fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
1527fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
1537fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    private class WifiReceiver extends BroadcastReceiver {
1547fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        @Override
1557fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        public void onReceive(Context context, Intent intent) {
1567fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            String action = intent.getAction();
1572c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
1582c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
15990e1c782a63475cd9b3973936decf6a4f6c6148fXia Wang                log("scan results are available");
1602c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                notifyScanResult();
1612c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
1622c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                mWifiNetworkInfo =
1632c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                    (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
164a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                log("mWifiNetworkInfo: " + mWifiNetworkInfo.toString());
1652c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                if (mWifiNetworkInfo.getState() == State.CONNECTED) {
1662c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                    mBssid = intent.getStringExtra(WifiManager.EXTRA_BSSID);
1672c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                }
1682c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                notifyWifiState();
1692c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
1702c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
1712c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                                                WifiManager.WIFI_STATE_UNKNOWN);
1722c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                notifyWifiState();
1736026d52710d7a6195a33885020d29aa1330fa855Xia Wang            } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
1746026d52710d7a6195a33885020d29aa1330fa855Xia Wang                notifyWifiAPState();
1756026d52710d7a6195a33885020d29aa1330fa855Xia Wang            } else if (action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
1766026d52710d7a6195a33885020d29aa1330fa855Xia Wang                ArrayList<String> available = intent.getStringArrayListExtra(
1776026d52710d7a6195a33885020d29aa1330fa855Xia Wang                        ConnectivityManager.EXTRA_AVAILABLE_TETHER);
1786026d52710d7a6195a33885020d29aa1330fa855Xia Wang                ArrayList<String> active = intent.getStringArrayListExtra(
1796026d52710d7a6195a33885020d29aa1330fa855Xia Wang                        ConnectivityManager.EXTRA_ACTIVE_TETHER);
1806026d52710d7a6195a33885020d29aa1330fa855Xia Wang                ArrayList<String> errored = intent.getStringArrayListExtra(
1816026d52710d7a6195a33885020d29aa1330fa855Xia Wang                        ConnectivityManager.EXTRA_ERRORED_TETHER);
1826026d52710d7a6195a33885020d29aa1330fa855Xia Wang                updateTetherState(available.toArray(), active.toArray(), errored.toArray());
1832c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            }
1842c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            else {
1857fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                return;
1867fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            }
1877fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
1887fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
1897fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
190ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff    private class WifiServiceHandler extends Handler {
191ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff        @Override
192ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff        public void handleMessage(Message msg) {
193ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff            switch (msg.what) {
194ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
195ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
196ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                        //AsyncChannel in msg.obj
197ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                    } else {
198ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                        log("Failed to establish AsyncChannel connection");
199ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                    }
200ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                    break;
201ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                default:
202ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                    //Ignore
203ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                    break;
204ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff            }
205ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff        }
206ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff    }
207ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff
2087fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public ConnectivityManagerTestActivity() {
2097fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        mState = State.UNKNOWN;
21090e1c782a63475cd9b3973936decf6a4f6c6148fXia Wang        scanResultAvailable = false;
2117fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
2127fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2137fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    @Override
2147fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    protected void onCreate(Bundle savedInstanceState) {
2157fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        super.onCreate(savedInstanceState);
216a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        log("onCreate, inst=" + Integer.toHexString(hashCode()));
2177fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2187fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        // Create a simple layout
2197fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        LinearLayout contentView = new LinearLayout(this);
2207fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        contentView.setOrientation(LinearLayout.VERTICAL);
2217fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        setContentView(contentView);
2227fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        setTitle("ConnectivityManagerTestActivity");
2237fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2242c15966f8cf6160ad5dcbbde372508de89985829Xia Wang
2257fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        // register a connectivity receiver for CONNECTIVITY_ACTION;
2262c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        mConnectivityReceiver = new ConnectivityReceiver();
2277fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        registerReceiver(mConnectivityReceiver,
2287fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
2297fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2307fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        mWifiReceiver = new WifiReceiver();
2312c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        IntentFilter mIntentFilter = new IntentFilter();
2322c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
2332c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
2342c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
235ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
2366026d52710d7a6195a33885020d29aa1330fa855Xia Wang        mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
2376026d52710d7a6195a33885020d29aa1330fa855Xia Wang        mIntentFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
2382c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        registerReceiver(mWifiReceiver, mIntentFilter);
2392c15966f8cf6160ad5dcbbde372508de89985829Xia Wang
2407fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        // Get an instance of ConnectivityManager
2417fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
2427fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        // Get an instance of WifiManager
2437fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
24427284da88c4552c5be4c8eff8acd36b518da47daXia Wang        mContext = this;
245d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null);
246ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff
2477fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        initializeNetworkStates();
2487fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
249dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        mWifiManager.setWifiEnabled(true);
250dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        log("Clear Wifi before we start the test.");
251dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        sleep(SHORT_TIMEOUT);
252dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        removeConfiguredNetworksAndDisableWifi();
2536026d52710d7a6195a33885020d29aa1330fa855Xia Wang        mWifiRegexs = mCM.getTetherableWifiRegexs();
2547fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     }
2557fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
256ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
257ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        InputStream in = getAssets().open(ACCESS_POINT_FILE);
258a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        mParseHelper = new AccessPointParserHelper(in);
259a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        return mParseHelper.getNetworkConfigurations();
260ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    }
261ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang
2627fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    // for each network type, initialize network states to UNKNOWN, and no verification flag is set
2637fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public void initializeNetworkStates() {
2647fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        for (int networkType = NUM_NETWORK_TYPES - 1; networkType >=0; networkType--) {
2657fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            connectivityState[networkType] =  new NetworkState();
266a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("Initialize network state for " + networkType + ": " +
2677fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                    connectivityState[networkType].toString());
2687fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
2697fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
2707fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2717fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    // deposit a network state
2727fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public void recordNetworkState(int networkType, State networkState) {
273a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        log("record network state for network " +  networkType +
2742c15966f8cf6160ad5dcbbde372508de89985829Xia Wang                ", state is " + networkState);
2757fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        connectivityState[networkType].recordState(networkState);
2767fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
2777fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2787fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    // set the state transition criteria
2797fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public void setStateTransitionCriteria(int networkType, State initState,
2807fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            int transitionDir, State targetState) {
2817fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        connectivityState[networkType].setStateTransitionCriteria(
2827fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                initState, transitionDir, targetState);
2837fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
2847fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2857fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    // Validate the states recorded
2867fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public boolean validateNetworkStates(int networkType) {
287a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        log("validate network state for " + networkType + ": ");
2887fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        return connectivityState[networkType].validateStateTransition();
2897fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
2907fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2917fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    // return result from network state validation
2927fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public String getTransitionFailureReason(int networkType) {
293a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        log("get network state transition failure reason for " + networkType + ": " +
2947fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                connectivityState[networkType].toString());
2957fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        return connectivityState[networkType].getReason();
2967fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
2977fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
2982c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    private void notifyNetworkConnectivityChange() {
2992c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        synchronized(connectivityObject) {
300a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("notify network connectivity changed");
3012c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            connectivityObject.notifyAll();
3022c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        }
3032c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    }
3047fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    private void notifyScanResult() {
3057fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        synchronized (this) {
306a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("notify that scan results are available");
30790e1c782a63475cd9b3973936decf6a4f6c6148fXia Wang            scanResultAvailable = true;
3087fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            this.notify();
3097fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
3107fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
3117fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
3126026d52710d7a6195a33885020d29aa1330fa855Xia Wang    private void notifyWifiState() {
3132c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        synchronized (wifiObject) {
314a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("notify wifi state changed");
3152c15966f8cf6160ad5dcbbde372508de89985829Xia Wang            wifiObject.notify();
3162c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        }
3172c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    }
3182c15966f8cf6160ad5dcbbde372508de89985829Xia Wang
3196026d52710d7a6195a33885020d29aa1330fa855Xia Wang    private void notifyWifiAPState() {
3206026d52710d7a6195a33885020d29aa1330fa855Xia Wang        synchronized (this) {
321a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("notify wifi AP state changed");
3226026d52710d7a6195a33885020d29aa1330fa855Xia Wang            this.notify();
3236026d52710d7a6195a33885020d29aa1330fa855Xia Wang        }
3246026d52710d7a6195a33885020d29aa1330fa855Xia Wang    }
3256026d52710d7a6195a33885020d29aa1330fa855Xia Wang
3266026d52710d7a6195a33885020d29aa1330fa855Xia Wang    // Update wifi tethering state
3276026d52710d7a6195a33885020d29aa1330fa855Xia Wang    private void updateTetherState(Object[] available, Object[] tethered, Object[] errored) {
3286026d52710d7a6195a33885020d29aa1330fa855Xia Wang        boolean wifiTethered = false;
3296026d52710d7a6195a33885020d29aa1330fa855Xia Wang        boolean wifiErrored = false;
3306026d52710d7a6195a33885020d29aa1330fa855Xia Wang
3316026d52710d7a6195a33885020d29aa1330fa855Xia Wang        synchronized (this) {
3326026d52710d7a6195a33885020d29aa1330fa855Xia Wang            for (Object obj: tethered) {
3336026d52710d7a6195a33885020d29aa1330fa855Xia Wang                String str = (String)obj;
3346026d52710d7a6195a33885020d29aa1330fa855Xia Wang                for (String tethRex: mWifiRegexs) {
335a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    log("str: " + str +"tethRex: " + tethRex);
3366026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    if (str.matches(tethRex)) {
3376026d52710d7a6195a33885020d29aa1330fa855Xia Wang                        wifiTethered = true;
3386026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    }
3396026d52710d7a6195a33885020d29aa1330fa855Xia Wang                }
3406026d52710d7a6195a33885020d29aa1330fa855Xia Wang            }
3416026d52710d7a6195a33885020d29aa1330fa855Xia Wang
3426026d52710d7a6195a33885020d29aa1330fa855Xia Wang            for (Object obj: errored) {
3436026d52710d7a6195a33885020d29aa1330fa855Xia Wang                String str = (String)obj;
3446026d52710d7a6195a33885020d29aa1330fa855Xia Wang                for (String tethRex: mWifiRegexs) {
345a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    log("error: str: " + str +"tethRex: " + tethRex);
3466026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    if (str.matches(tethRex)) {
3476026d52710d7a6195a33885020d29aa1330fa855Xia Wang                        wifiErrored = true;
3486026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    }
3496026d52710d7a6195a33885020d29aa1330fa855Xia Wang                }
3506026d52710d7a6195a33885020d29aa1330fa855Xia Wang            }
3516026d52710d7a6195a33885020d29aa1330fa855Xia Wang
3526026d52710d7a6195a33885020d29aa1330fa855Xia Wang            if (wifiTethered) {
3536026d52710d7a6195a33885020d29aa1330fa855Xia Wang                mWifiTetherResult = SUCCESS;   // wifi tethering is successful
3546026d52710d7a6195a33885020d29aa1330fa855Xia Wang            } else if (wifiErrored) {
3556026d52710d7a6195a33885020d29aa1330fa855Xia Wang                mWifiTetherResult = FAILURE;   // wifi tethering failed
3566026d52710d7a6195a33885020d29aa1330fa855Xia Wang            }
357a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("mWifiTetherResult: " + mWifiTetherResult);
3586026d52710d7a6195a33885020d29aa1330fa855Xia Wang            this.notify();
3596026d52710d7a6195a33885020d29aa1330fa855Xia Wang        }
3606026d52710d7a6195a33885020d29aa1330fa855Xia Wang    }
3616026d52710d7a6195a33885020d29aa1330fa855Xia Wang
3626026d52710d7a6195a33885020d29aa1330fa855Xia Wang
363ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    // Wait for network connectivity state: CONNECTING, CONNECTED, SUSPENDED,
364ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    //                                      DISCONNECTING, DISCONNECTED, UNKNOWN
365ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public boolean waitForNetworkState(int networkType, State expectedState, long timeout) {
366ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        long startTime = System.currentTimeMillis();
367ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        while (true) {
368ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            if ((System.currentTimeMillis() - startTime) > timeout) {
36990e1c782a63475cd9b3973936decf6a4f6c6148fXia Wang                log("waitForNetworkState time out, the state of network type " + networkType +
37090e1c782a63475cd9b3973936decf6a4f6c6148fXia Wang                        " is: " + mCM.getNetworkInfo(networkType).getState());
371ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                if (mCM.getNetworkInfo(networkType).getState() != expectedState) {
372ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    return false;
373ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                } else {
374ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    // the broadcast has been sent out. the state has been changed.
375a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    log("networktype: " + networkType + " state: " +
376ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                            mCM.getNetworkInfo(networkType));
377ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    return true;
378ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                }
379ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            }
380a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("Wait for the connectivity state for network: " + networkType +
381ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    " to be " + expectedState.toString());
382ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            synchronized (connectivityObject) {
383ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                try {
384ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    connectivityObject.wait(SHORT_TIMEOUT);
385ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                } catch (InterruptedException e) {
386ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    e.printStackTrace();
387ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                }
388ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                if ((mNetworkInfo.getType() != networkType) ||
389ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    (mNetworkInfo.getState() != expectedState)) {
390a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    log("network state for " + mNetworkInfo.getType() +
391ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                            "is: " + mNetworkInfo.getState());
392ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    continue;
393ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                }
394ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                return true;
395ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            }
396ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        }
397ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    }
398ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang
399ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
400ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    //                      WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
401ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public boolean waitForWifiState(int expectedState, long timeout) {
402ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        long startTime = System.currentTimeMillis();
403ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        while (true) {
404ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            if ((System.currentTimeMillis() - startTime) > timeout) {
405ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                if (mWifiState != expectedState) {
406ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    return false;
407ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                } else {
408ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    return true;
409ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                }
410ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            }
411a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("Wait for wifi state to be: " + expectedState);
412ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            synchronized (wifiObject) {
413ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                try {
414ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    wifiObject.wait(SHORT_TIMEOUT);
415ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                } catch (InterruptedException e) {
416ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    e.printStackTrace();
417ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                }
418ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                if (mWifiState != expectedState) {
419a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    log("Wifi state is: " + mWifiState);
420ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                    continue;
421ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                }
422ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang                return true;
423ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang            }
424ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        }
425ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    }
426ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang
4276026d52710d7a6195a33885020d29aa1330fa855Xia Wang    // Wait for Wifi AP state: WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING,
4286026d52710d7a6195a33885020d29aa1330fa855Xia Wang    //                         WIFI_AP_STATE_ENABLED, WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
4296026d52710d7a6195a33885020d29aa1330fa855Xia Wang    public boolean waitForWifiAPState(int expectedState, long timeout) {
4306026d52710d7a6195a33885020d29aa1330fa855Xia Wang        long startTime = System.currentTimeMillis();
4316026d52710d7a6195a33885020d29aa1330fa855Xia Wang        while (true) {
4326026d52710d7a6195a33885020d29aa1330fa855Xia Wang            if ((System.currentTimeMillis() - startTime) > timeout) {
4336026d52710d7a6195a33885020d29aa1330fa855Xia Wang                if (mWifiManager.getWifiApState() != expectedState) {
4346026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    return false;
4356026d52710d7a6195a33885020d29aa1330fa855Xia Wang                } else {
4366026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    return true;
4376026d52710d7a6195a33885020d29aa1330fa855Xia Wang                }
4386026d52710d7a6195a33885020d29aa1330fa855Xia Wang            }
439a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("Wait for wifi AP state to be: " + expectedState);
4406026d52710d7a6195a33885020d29aa1330fa855Xia Wang            synchronized (wifiObject) {
4416026d52710d7a6195a33885020d29aa1330fa855Xia Wang                try {
4426026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    wifiObject.wait(SHORT_TIMEOUT);
4436026d52710d7a6195a33885020d29aa1330fa855Xia Wang                } catch (InterruptedException e) {
4446026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    e.printStackTrace();
4456026d52710d7a6195a33885020d29aa1330fa855Xia Wang                }
4466026d52710d7a6195a33885020d29aa1330fa855Xia Wang                if (mWifiManager.getWifiApState() != expectedState) {
447a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    log("Wifi state is: " + mWifiManager.getWifiApState());
4486026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    continue;
4496026d52710d7a6195a33885020d29aa1330fa855Xia Wang                }
4506026d52710d7a6195a33885020d29aa1330fa855Xia Wang                return true;
4516026d52710d7a6195a33885020d29aa1330fa855Xia Wang            }
4526026d52710d7a6195a33885020d29aa1330fa855Xia Wang        }
4536026d52710d7a6195a33885020d29aa1330fa855Xia Wang    }
4546026d52710d7a6195a33885020d29aa1330fa855Xia Wang
4556026d52710d7a6195a33885020d29aa1330fa855Xia Wang    /**
4566026d52710d7a6195a33885020d29aa1330fa855Xia Wang     * Wait for the wifi tethering result:
4576026d52710d7a6195a33885020d29aa1330fa855Xia Wang     * @param timeout is the maximum waiting time
4586026d52710d7a6195a33885020d29aa1330fa855Xia Wang     * @return SUCCESS if tethering result is successful
4596026d52710d7a6195a33885020d29aa1330fa855Xia Wang     *         FAILURE if tethering result returns error.
4606026d52710d7a6195a33885020d29aa1330fa855Xia Wang     */
4616026d52710d7a6195a33885020d29aa1330fa855Xia Wang    public int waitForTetherStateChange(long timeout) {
4626026d52710d7a6195a33885020d29aa1330fa855Xia Wang        long startTime = System.currentTimeMillis();
4636026d52710d7a6195a33885020d29aa1330fa855Xia Wang        while (true) {
4646026d52710d7a6195a33885020d29aa1330fa855Xia Wang            if ((System.currentTimeMillis() - startTime) > timeout) {
4656026d52710d7a6195a33885020d29aa1330fa855Xia Wang                return mWifiTetherResult;
4666026d52710d7a6195a33885020d29aa1330fa855Xia Wang            }
467a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("Wait for wifi tethering result.");
4686026d52710d7a6195a33885020d29aa1330fa855Xia Wang            synchronized (this) {
4696026d52710d7a6195a33885020d29aa1330fa855Xia Wang                try {
4706026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    this.wait(SHORT_TIMEOUT);
4716026d52710d7a6195a33885020d29aa1330fa855Xia Wang                } catch (InterruptedException e) {
4726026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    e.printStackTrace();
4736026d52710d7a6195a33885020d29aa1330fa855Xia Wang                }
4746026d52710d7a6195a33885020d29aa1330fa855Xia Wang                if (mWifiTetherResult == INIT ) {
4756026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    continue;
4766026d52710d7a6195a33885020d29aa1330fa855Xia Wang                } else {
4776026d52710d7a6195a33885020d29aa1330fa855Xia Wang                    return mWifiTetherResult;
4786026d52710d7a6195a33885020d29aa1330fa855Xia Wang                }
4796026d52710d7a6195a33885020d29aa1330fa855Xia Wang            }
4806026d52710d7a6195a33885020d29aa1330fa855Xia Wang        }
4816026d52710d7a6195a33885020d29aa1330fa855Xia Wang    }
4826026d52710d7a6195a33885020d29aa1330fa855Xia Wang
4837fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    // Return true if device is currently connected to mobile network
4847fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public boolean isConnectedToMobile() {
4857fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
4867fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
4877fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
4887fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    // Return true if device is currently connected to Wifi
4897fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public boolean isConnectedToWifi() {
4907fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
4917fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
4927fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
4937fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public boolean enableWifi() {
4947fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        return mWifiManager.setWifiEnabled(true);
4957fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
4967fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
49773055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang    // Turn screen off
49873055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang    public void turnScreenOff() {
49973055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        log("Turn screen off");
50073055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        PowerManager pm =
50173055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang            (PowerManager) getSystemService(Context.POWER_SERVICE);
50273055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        pm.goToSleep(SystemClock.uptimeMillis() + 100);
50373055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang    }
50473055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang
50573055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang    // Turn screen on
50673055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang    public void turnScreenOn() {
50773055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        log("Turn screen on");
50873055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        IPowerManager mPowerManagerService = IPowerManager.Stub.asInterface(
50973055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang                ServiceManager.getService("power"));;
51073055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        try {
51173055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang            mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
51273055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        } catch (Exception e) {
51373055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang            log(e.toString());
51473055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang        }
51573055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang    }
51673055f12d7764e322f3f83717525a2dba01f9ef9Xia Wang
5177fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    /**
5186bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang     * @param pingServerList a list of servers that can be used for ping test, can be null
5196bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang     * @return true if the ping test is successful, false otherwise.
5206bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang     */
5216bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang    public boolean pingTest(String[] pingServerList) {
5226bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        boolean result = false;
5236bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        String[] hostList = {"www.google.com", "www.yahoo.com",
5246bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                "www.bing.com", "www.facebook.com", "www.ask.com"};
5256bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        if (pingServerList != null) {
5266bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang            hostList = pingServerList;
5276bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        }
5286bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        try {
5296bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang            // assume the chance that all servers are down is very small
5306bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang            for (int i = 0; i < hostList.length; i++ ) {
5316bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                String host = hostList[i];
5326bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                log("Start ping test, ping " + host);
5336bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
5346bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                int status = p.waitFor();
5356bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                if (status == 0) {
5366bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                    // if any of the ping test is successful, return true
5376bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                    result = true;
5386bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                    break;
5396bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                } else {
5406bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                    result = false;
5416bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                    log("ping " + host + " failed.");
5426bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang                }
5436bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang            }
5446bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        } catch (UnknownHostException e) {
5456bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang            log("Ping test Fail: Unknown Host");
5466bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        } catch (IOException e) {
5476bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang            log("Ping test Fail:  IOException");
5486bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        } catch (InterruptedException e) {
5496bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang            log("Ping test Fail: InterruptedException");
5506bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        }
5516bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        log("return");
5526bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang        return result;
5536bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang    }
5546bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang
5556bffe14c78efa0b56327262543ce2e0dfc024219Xia Wang    /**
5567fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * Associate the device to given SSID
5577fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * If the device is already associated with a WiFi, disconnect and forget it,
5587fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * We don't verify whether the connection is successful or not, leave this to the test
5597fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     */
5607fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public boolean connectToWifi(String knownSSID) {
561ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        WifiConfiguration config = new WifiConfiguration();
562ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        config.SSID = knownSSID;
563ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        config.allowedKeyManagement.set(KeyMgmt.NONE);
564ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        return connectToWifiWithConfiguration(config);
565ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    }
566ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang
567ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    /**
568ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang     * Connect to Wi-Fi with the given configuration. Note the SSID in the configuration
569ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang     * is pure string, we need to convert it to quoted string.
570ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang     * @param config
571ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang     * @return
572ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang     */
573ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public boolean connectToWifiWithConfiguration(WifiConfiguration config) {
574ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        String ssid = config.SSID;
575ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang        config.SSID = convertToQuotedString(ssid);
576ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang
5777fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        //If Wifi is not enabled, enable it
5787fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        if (!mWifiManager.isWifiEnabled()) {
579a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            log("Wifi is not enabled, enable it");
5807fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            mWifiManager.setWifiEnabled(true);
581a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            // wait for the wifi state change before start scanning.
582a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2*SHORT_TIMEOUT)) {
583a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                log("wait for WIFI_STATE_ENABLED failed");
584a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                return false;
585a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            }
5867fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
5877fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
588a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        boolean foundApInScanResults = false;
589a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        for (int retry = 0; retry < 5; retry++) {
590a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            List<ScanResult> netList = mWifiManager.getScanResults();
591a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            if (netList != null) {
592a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                log("size of scan result list: " + netList.size());
593a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                for (int i = 0; i < netList.size(); i++) {
594a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    ScanResult sr= netList.get(i);
595a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    if (sr.SSID.equals(ssid)) {
596a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        log("found " + ssid + " in the scan result list");
597a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        log("retry: " + retry);
598a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        foundApInScanResults = true;
599d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        mWifiManager.connect(mChannel, config,
600d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                new WifiManager.ActionListener() {
601d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                    public void onSuccess() {
602d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                    }
603d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                    public void onFailure(int reason) {
604d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                        log("connect failure " + reason);
605d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                    }
606d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                });
607a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        break;
608a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                   }
6097fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                }
610a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            }
611a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            if (foundApInScanResults) {
612a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                return true;
613a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang            } else {
614a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                // Start an active scan
615a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                mWifiManager.startScanActive();
616a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                mScanResultIsAvailable = false;
617a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                long startTime = System.currentTimeMillis();
618a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                while (!mScanResultIsAvailable) {
619a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
620a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        log("wait for scan results timeout");
621a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        return false;
6227fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                    }
623a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    // wait for the scan results to be available
624a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                    synchronized (this) {
625a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        // wait for the scan result to be available
626a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        try {
627a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                            this.wait(WAIT_FOR_SCAN_RESULT);
628a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        } catch (InterruptedException e) {
629a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                            e.printStackTrace();
630a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        }
631a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        if ((mWifiManager.getScanResults() == null) ||
632a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                                (mWifiManager.getScanResults().size() <= 0)) {
633a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                            continue;
634a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        }
635a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang                        mScanResultIsAvailable = true;
6367fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                    }
6377fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                }
6387fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            }
6397fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
640a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        return false;
6417fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
6427fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
6432c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    /*
644ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang     * Disconnect from the current AP and remove configured networks.
6457fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     */
6462c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public boolean disconnectAP() {
647dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        // remove saved networks
648dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
649dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        log("size of wifiConfigList: " + wifiConfigList.size());
650dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        for (WifiConfiguration wifiConfig: wifiConfigList) {
651dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang            log("remove wifi configuration: " + wifiConfig.networkId);
652dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang            int netId = wifiConfig.networkId;
653d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff            mWifiManager.forget(mChannel, netId, new WifiManager.ActionListener() {
654d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    public void onSuccess() {
655d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
656d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    public void onFailure(int reason) {
657d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        log("Failed to forget " + reason);
658d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
659d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                });
6602c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        }
6612c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        return true;
6622c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    }
6632c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    /**
6642c15966f8cf6160ad5dcbbde372508de89985829Xia Wang     * Disable Wifi
6652c15966f8cf6160ad5dcbbde372508de89985829Xia Wang     * @return true if Wifi is disabled successfully
6662c15966f8cf6160ad5dcbbde372508de89985829Xia Wang     */
6672c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    public boolean disableWifi() {
6682c15966f8cf6160ad5dcbbde372508de89985829Xia Wang        return mWifiManager.setWifiEnabled(false);
6692c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    }
6702c15966f8cf6160ad5dcbbde372508de89985829Xia Wang
6712c15966f8cf6160ad5dcbbde372508de89985829Xia Wang    /**
672ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang     * Remove configured networks and disable wifi
6732c15966f8cf6160ad5dcbbde372508de89985829Xia Wang     */
674ca1f2b1a1e8cb785be5ebbcf7ded7c921cbf80a7Xia Wang    public boolean removeConfiguredNetworksAndDisableWifi() {
675dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        if (!disconnectAP()) {
676dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang           return false;
677dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        }
678dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        sleep(SHORT_TIMEOUT);
679dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        if (!mWifiManager.setWifiEnabled(false)) {
680dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang            return false;
681dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        }
682dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        sleep(SHORT_TIMEOUT);
6837fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        return true;
6847fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
6857fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
686dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang    private void sleep(long sleeptime) {
687dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        try {
688dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang            Thread.sleep(sleeptime);
689dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang        } catch (InterruptedException e) {}
690dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang    }
691dddfaa75e77f4d02cc7b4180f5eb0679321cb628Xia Wang
6927fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    /**
6937fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     * Set airplane mode
6947fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang     */
6957fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    public void setAirplaneMode(Context context, boolean enableAM) {
6967fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        //set the airplane mode
6977fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
6987fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang                enableAM ? 1 : 0);
6997fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        // Post the intent
7007fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
7017fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        intent.putExtra("state", enableAM);
7027fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        context.sendBroadcast(intent);
7037fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
7047fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
705069067963cf0117cfb4a1aef99b550b126d9ca92Xia Wang    protected static String convertToQuotedString(String string) {
706069067963cf0117cfb4a1aef99b550b126d9ca92Xia Wang        return "\"" + string + "\"";
707069067963cf0117cfb4a1aef99b550b126d9ca92Xia Wang    }
708069067963cf0117cfb4a1aef99b550b126d9ca92Xia Wang
7097fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    @Override
7107fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    protected void onDestroy() {
7117fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        super.onDestroy();
7127fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang
7137fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        //Unregister receiver
7147fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        if (mConnectivityReceiver != null) {
7157fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            unregisterReceiver(mConnectivityReceiver);
7167fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
7177fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        if (mWifiReceiver != null) {
7187fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang            unregisterReceiver(mWifiReceiver);
7197fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang        }
720a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        log("onDestroy, inst=" + Integer.toHexString(hashCode()));
7217fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang    }
722ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau
723ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    @Override
724ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    public void onStart() {
725ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        super.onStart();
726ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        mContext = this;
727ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        Bundle bundle = this.getIntent().getExtras();
728ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        if (bundle != null){
729ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            mPowerSsid = bundle.getString("power_ssid");
730ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        }
731ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    }
732ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    //A thread to set the device into airplane mode then turn on wifi.
733ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    Thread setDeviceWifiAndAirplaneThread = new Thread(new Runnable() {
734ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        public void run() {
735ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            setAirplaneMode(mContext, true);
736ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            connectToWifi(mPowerSsid);
737ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        }
738ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    });
739ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau
740ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    //A thread to set the device into wifi
741ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    Thread setDeviceInWifiOnlyThread = new Thread(new Runnable() {
742ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        public void run() {
743ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            connectToWifi(mPowerSsid);
744ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        }
745ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    });
746ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau
747ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    @Override
748ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    public boolean onKeyDown(int keyCode, KeyEvent event) {
749ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        switch (keyCode) {
750ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            //This is a tricky way for the scripted monkey to
751ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            //set the device in wifi and wifi in airplane mode.
752ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            case KeyEvent.KEYCODE_1:
753ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau                setDeviceWifiAndAirplaneThread.start();
754ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau                break;
755ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau
756ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau            case KeyEvent.KEYCODE_2:
757ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau                setDeviceInWifiOnlyThread.start();
758ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau                break;
759ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        }
760ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau        return super.onKeyDown(keyCode, event);
761ba1348e3c21502ecde9427413703defa6d105132Yu Shan Emily Lau    }
762a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang
763a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang    private void log(String message) {
764a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang        Log.v(LOG_TAG, message);
765a42a1e6b6fb6acc9ca327523ae456e464f8aedc1Xia Wang    }
7667fb1f674c90eb8f85f1d1ad7dab29ac65c15cb6eXia Wang}
767