ConnectivityManagerTestActivity.java revision 27284da88c4552c5be4c8eff8acd36b518da47da
1/*
2 * Copyright (C) 2010, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.connectivitymanagertest;
18
19import android.app.Activity;
20import android.content.Context;
21import android.content.BroadcastReceiver;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.net.ConnectivityManager;
25import android.net.NetworkInfo;
26import android.net.NetworkInfo.State;
27import android.net.wifi.WifiConfiguration;
28import android.net.wifi.WifiManager;
29import android.net.wifi.WifiInfo;
30import android.net.wifi.ScanResult;
31import android.net.wifi.WifiConfiguration.KeyMgmt;
32import android.os.Bundle;
33import android.os.Handler;
34import android.os.IPowerManager;
35import android.os.Message;
36import android.os.PowerManager;
37import android.os.ServiceManager;
38import android.os.SystemClock;
39import android.provider.Settings;
40import android.util.Log;
41import android.view.KeyEvent;
42import android.widget.LinearLayout;
43
44import com.android.internal.util.AsyncChannel;
45
46import java.io.IOException;
47import java.io.InputStream;
48import java.net.UnknownHostException;
49import java.util.ArrayList;
50import java.util.List;
51
52
53/**
54 * An activity registered with connectivity manager broadcast
55 * provides network connectivity information and
56 * can be used to set device states: Cellular, Wifi, Airplane mode.
57 */
58public class ConnectivityManagerTestActivity extends Activity {
59
60    public static final String LOG_TAG = "ConnectivityManagerTestActivity";
61    public static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds
62    public static final int WIFI_SCAN_TIMEOUT = 50 * 1000;
63    public static final int SHORT_TIMEOUT = 5 * 1000;
64    public static final long LONG_TIMEOUT = 50 * 1000;
65    // 2 minutes timer between wifi stop and start
66    public static final long  WIFI_STOP_START_INTERVAL = 2 * 60 * 1000;
67    public static final int SUCCESS = 0;  // for Wifi tethering state change
68    public static final int FAILURE = 1;
69    public static final int INIT = -1;
70    private static final String ACCESS_POINT_FILE = "accesspoints.xml";
71    public ConnectivityReceiver mConnectivityReceiver = null;
72    public WifiReceiver mWifiReceiver = null;
73    private AccessPointParserHelper mParseHelper = null;
74    /*
75     * Track network connectivity information
76     */
77    public State mState;
78    public NetworkInfo mNetworkInfo;
79    public NetworkInfo mOtherNetworkInfo;
80    public boolean mIsFailOver;
81    public String mReason;
82    public boolean mScanResultIsAvailable = false;
83    public ConnectivityManager mCM;
84    public Object wifiObject = new Object();
85    public Object connectivityObject = new Object();
86    public int mWifiState;
87    public NetworkInfo mWifiNetworkInfo;
88    public String mBssid;
89    public String mPowerSsid = "opennet"; //Default power SSID
90    private Context mContext;
91    public boolean scanResultAvailable = false;
92
93    /*
94     * Control Wifi States
95     */
96    public WifiManager mWifiManager;
97    public WifiManager.Channel mChannel;
98
99    /*
100     * Verify connectivity state
101     */
102    public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
103    NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES];
104
105    // For wifi tethering tests
106    private String[] mWifiRegexs;
107    public int mWifiTetherResult = INIT;    // -1 is initialization state
108
109    /**
110     * A wrapper of a broadcast receiver which provides network connectivity information
111     * for all kinds of network: wifi, mobile, etc.
112     */
113    private class ConnectivityReceiver extends BroadcastReceiver {
114        @Override
115        public void onReceive(Context context, Intent intent) {
116            log("ConnectivityReceiver: onReceive() is called with " + intent);
117            String action = intent.getAction();
118            if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
119                Log.v("ConnectivityReceiver", "onReceive() called with " + intent);
120                return;
121            }
122
123            boolean noConnectivity =
124                intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
125
126            if (noConnectivity) {
127                mState = State.DISCONNECTED;
128            } else {
129                mState = State.CONNECTED;
130            }
131
132            mNetworkInfo = (NetworkInfo)
133                intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
134
135            mOtherNetworkInfo = (NetworkInfo)
136                intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
137
138            mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
139            mIsFailOver = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
140
141            log("mNetworkInfo: " + mNetworkInfo.toString());
142            if (mOtherNetworkInfo != null) {
143                log("mOtherNetworkInfo: " + mOtherNetworkInfo.toString());
144            }
145            recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
146            if (mOtherNetworkInfo != null) {
147                recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
148            }
149            notifyNetworkConnectivityChange();
150        }
151    }
152
153    private class WifiReceiver extends BroadcastReceiver {
154        @Override
155        public void onReceive(Context context, Intent intent) {
156            String action = intent.getAction();
157            Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
158            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
159                log("scan results are available");
160                notifyScanResult();
161            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
162                mWifiNetworkInfo =
163                    (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
164                log("mWifiNetworkInfo: " + mWifiNetworkInfo.toString());
165                if (mWifiNetworkInfo.getState() == State.CONNECTED) {
166                    mBssid = intent.getStringExtra(WifiManager.EXTRA_BSSID);
167                }
168                notifyWifiState();
169            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
170                mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
171                                                WifiManager.WIFI_STATE_UNKNOWN);
172                notifyWifiState();
173            } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
174                notifyWifiAPState();
175            } else if (action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
176                ArrayList<String> available = intent.getStringArrayListExtra(
177                        ConnectivityManager.EXTRA_AVAILABLE_TETHER);
178                ArrayList<String> active = intent.getStringArrayListExtra(
179                        ConnectivityManager.EXTRA_ACTIVE_TETHER);
180                ArrayList<String> errored = intent.getStringArrayListExtra(
181                        ConnectivityManager.EXTRA_ERRORED_TETHER);
182                updateTetherState(available.toArray(), active.toArray(), errored.toArray());
183            }
184            else {
185                return;
186            }
187        }
188    }
189
190    private class WifiServiceHandler extends Handler {
191        @Override
192        public void handleMessage(Message msg) {
193            switch (msg.what) {
194                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
195                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
196                        //AsyncChannel in msg.obj
197                    } else {
198                        log("Failed to establish AsyncChannel connection");
199                    }
200                    break;
201                default:
202                    //Ignore
203                    break;
204            }
205        }
206    }
207
208    public ConnectivityManagerTestActivity() {
209        mState = State.UNKNOWN;
210        scanResultAvailable = false;
211    }
212
213    @Override
214    protected void onCreate(Bundle savedInstanceState) {
215        super.onCreate(savedInstanceState);
216        log("onCreate, inst=" + Integer.toHexString(hashCode()));
217
218        // Create a simple layout
219        LinearLayout contentView = new LinearLayout(this);
220        contentView.setOrientation(LinearLayout.VERTICAL);
221        setContentView(contentView);
222        setTitle("ConnectivityManagerTestActivity");
223
224
225        // register a connectivity receiver for CONNECTIVITY_ACTION;
226        mConnectivityReceiver = new ConnectivityReceiver();
227        registerReceiver(mConnectivityReceiver,
228                new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
229
230        mWifiReceiver = new WifiReceiver();
231        IntentFilter mIntentFilter = new IntentFilter();
232        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
233        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
234        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
235        mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
236        mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
237        mIntentFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
238        registerReceiver(mWifiReceiver, mIntentFilter);
239
240        // Get an instance of ConnectivityManager
241        mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
242        // Get an instance of WifiManager
243        mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
244        mContext = this;
245        mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null);
246
247        initializeNetworkStates();
248
249        mWifiManager.setWifiEnabled(true);
250        log("Clear Wifi before we start the test.");
251        sleep(SHORT_TIMEOUT);
252        removeConfiguredNetworksAndDisableWifi();
253        mWifiRegexs = mCM.getTetherableWifiRegexs();
254     }
255
256    public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
257        InputStream in = getAssets().open(ACCESS_POINT_FILE);
258        mParseHelper = new AccessPointParserHelper(in);
259        return mParseHelper.getNetworkConfigurations();
260    }
261
262    // for each network type, initialize network states to UNKNOWN, and no verification flag is set
263    public void initializeNetworkStates() {
264        for (int networkType = NUM_NETWORK_TYPES - 1; networkType >=0; networkType--) {
265            connectivityState[networkType] =  new NetworkState();
266            log("Initialize network state for " + networkType + ": " +
267                    connectivityState[networkType].toString());
268        }
269    }
270
271    // deposit a network state
272    public void recordNetworkState(int networkType, State networkState) {
273        log("record network state for network " +  networkType +
274                ", state is " + networkState);
275        connectivityState[networkType].recordState(networkState);
276    }
277
278    // set the state transition criteria
279    public void setStateTransitionCriteria(int networkType, State initState,
280            int transitionDir, State targetState) {
281        connectivityState[networkType].setStateTransitionCriteria(
282                initState, transitionDir, targetState);
283    }
284
285    // Validate the states recorded
286    public boolean validateNetworkStates(int networkType) {
287        log("validate network state for " + networkType + ": ");
288        return connectivityState[networkType].validateStateTransition();
289    }
290
291    // return result from network state validation
292    public String getTransitionFailureReason(int networkType) {
293        log("get network state transition failure reason for " + networkType + ": " +
294                connectivityState[networkType].toString());
295        return connectivityState[networkType].getReason();
296    }
297
298    private void notifyNetworkConnectivityChange() {
299        synchronized(connectivityObject) {
300            log("notify network connectivity changed");
301            connectivityObject.notifyAll();
302        }
303    }
304    private void notifyScanResult() {
305        synchronized (this) {
306            log("notify that scan results are available");
307            scanResultAvailable = true;
308            this.notify();
309        }
310    }
311
312    private void notifyWifiState() {
313        synchronized (wifiObject) {
314            log("notify wifi state changed");
315            wifiObject.notify();
316        }
317    }
318
319    private void notifyWifiAPState() {
320        synchronized (this) {
321            log("notify wifi AP state changed");
322            this.notify();
323        }
324    }
325
326    // Update wifi tethering state
327    private void updateTetherState(Object[] available, Object[] tethered, Object[] errored) {
328        boolean wifiTethered = false;
329        boolean wifiErrored = false;
330
331        synchronized (this) {
332            for (Object obj: tethered) {
333                String str = (String)obj;
334                for (String tethRex: mWifiRegexs) {
335                    log("str: " + str +"tethRex: " + tethRex);
336                    if (str.matches(tethRex)) {
337                        wifiTethered = true;
338                    }
339                }
340            }
341
342            for (Object obj: errored) {
343                String str = (String)obj;
344                for (String tethRex: mWifiRegexs) {
345                    log("error: str: " + str +"tethRex: " + tethRex);
346                    if (str.matches(tethRex)) {
347                        wifiErrored = true;
348                    }
349                }
350            }
351
352            if (wifiTethered) {
353                mWifiTetherResult = SUCCESS;   // wifi tethering is successful
354            } else if (wifiErrored) {
355                mWifiTetherResult = FAILURE;   // wifi tethering failed
356            }
357            log("mWifiTetherResult: " + mWifiTetherResult);
358            this.notify();
359        }
360    }
361
362
363    // Wait for network connectivity state: CONNECTING, CONNECTED, SUSPENDED,
364    //                                      DISCONNECTING, DISCONNECTED, UNKNOWN
365    public boolean waitForNetworkState(int networkType, State expectedState, long timeout) {
366        long startTime = System.currentTimeMillis();
367        while (true) {
368            if ((System.currentTimeMillis() - startTime) > timeout) {
369                log("waitForNetworkState time out, the state of network type " + networkType +
370                        " is: " + mCM.getNetworkInfo(networkType).getState());
371                if (mCM.getNetworkInfo(networkType).getState() != expectedState) {
372                    return false;
373                } else {
374                    // the broadcast has been sent out. the state has been changed.
375                    log("networktype: " + networkType + " state: " +
376                            mCM.getNetworkInfo(networkType));
377                    return true;
378                }
379            }
380            log("Wait for the connectivity state for network: " + networkType +
381                    " to be " + expectedState.toString());
382            synchronized (connectivityObject) {
383                try {
384                    connectivityObject.wait(SHORT_TIMEOUT);
385                } catch (InterruptedException e) {
386                    e.printStackTrace();
387                }
388                if ((mNetworkInfo.getType() != networkType) ||
389                    (mNetworkInfo.getState() != expectedState)) {
390                    log("network state for " + mNetworkInfo.getType() +
391                            "is: " + mNetworkInfo.getState());
392                    continue;
393                }
394                return true;
395            }
396        }
397    }
398
399    // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
400    //                      WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
401    public boolean waitForWifiState(int expectedState, long timeout) {
402        long startTime = System.currentTimeMillis();
403        while (true) {
404            if ((System.currentTimeMillis() - startTime) > timeout) {
405                if (mWifiState != expectedState) {
406                    return false;
407                } else {
408                    return true;
409                }
410            }
411            log("Wait for wifi state to be: " + expectedState);
412            synchronized (wifiObject) {
413                try {
414                    wifiObject.wait(SHORT_TIMEOUT);
415                } catch (InterruptedException e) {
416                    e.printStackTrace();
417                }
418                if (mWifiState != expectedState) {
419                    log("Wifi state is: " + mWifiState);
420                    continue;
421                }
422                return true;
423            }
424        }
425    }
426
427    // Wait for Wifi AP state: WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING,
428    //                         WIFI_AP_STATE_ENABLED, WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
429    public boolean waitForWifiAPState(int expectedState, long timeout) {
430        long startTime = System.currentTimeMillis();
431        while (true) {
432            if ((System.currentTimeMillis() - startTime) > timeout) {
433                if (mWifiManager.getWifiApState() != expectedState) {
434                    return false;
435                } else {
436                    return true;
437                }
438            }
439            log("Wait for wifi AP state to be: " + expectedState);
440            synchronized (wifiObject) {
441                try {
442                    wifiObject.wait(SHORT_TIMEOUT);
443                } catch (InterruptedException e) {
444                    e.printStackTrace();
445                }
446                if (mWifiManager.getWifiApState() != expectedState) {
447                    log("Wifi state is: " + mWifiManager.getWifiApState());
448                    continue;
449                }
450                return true;
451            }
452        }
453    }
454
455    /**
456     * Wait for the wifi tethering result:
457     * @param timeout is the maximum waiting time
458     * @return SUCCESS if tethering result is successful
459     *         FAILURE if tethering result returns error.
460     */
461    public int waitForTetherStateChange(long timeout) {
462        long startTime = System.currentTimeMillis();
463        while (true) {
464            if ((System.currentTimeMillis() - startTime) > timeout) {
465                return mWifiTetherResult;
466            }
467            log("Wait for wifi tethering result.");
468            synchronized (this) {
469                try {
470                    this.wait(SHORT_TIMEOUT);
471                } catch (InterruptedException e) {
472                    e.printStackTrace();
473                }
474                if (mWifiTetherResult == INIT ) {
475                    continue;
476                } else {
477                    return mWifiTetherResult;
478                }
479            }
480        }
481    }
482
483    // Return true if device is currently connected to mobile network
484    public boolean isConnectedToMobile() {
485        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
486    }
487
488    // Return true if device is currently connected to Wifi
489    public boolean isConnectedToWifi() {
490        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
491    }
492
493    public boolean enableWifi() {
494        return mWifiManager.setWifiEnabled(true);
495    }
496
497    // Turn screen off
498    public void turnScreenOff() {
499        log("Turn screen off");
500        PowerManager pm =
501            (PowerManager) getSystemService(Context.POWER_SERVICE);
502        pm.goToSleep(SystemClock.uptimeMillis() + 100);
503    }
504
505    // Turn screen on
506    public void turnScreenOn() {
507        log("Turn screen on");
508        IPowerManager mPowerManagerService = IPowerManager.Stub.asInterface(
509                ServiceManager.getService("power"));;
510        try {
511            mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
512        } catch (Exception e) {
513            log(e.toString());
514        }
515    }
516
517    /**
518     * @param pingServerList a list of servers that can be used for ping test, can be null
519     * @return true if the ping test is successful, false otherwise.
520     */
521    public boolean pingTest(String[] pingServerList) {
522        boolean result = false;
523        String[] hostList = {"www.google.com", "www.yahoo.com",
524                "www.bing.com", "www.facebook.com", "www.ask.com"};
525        if (pingServerList != null) {
526            hostList = pingServerList;
527        }
528        try {
529            // assume the chance that all servers are down is very small
530            for (int i = 0; i < hostList.length; i++ ) {
531                String host = hostList[i];
532                log("Start ping test, ping " + host);
533                Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
534                int status = p.waitFor();
535                if (status == 0) {
536                    // if any of the ping test is successful, return true
537                    result = true;
538                    break;
539                } else {
540                    result = false;
541                    log("ping " + host + " failed.");
542                }
543            }
544        } catch (UnknownHostException e) {
545            log("Ping test Fail: Unknown Host");
546        } catch (IOException e) {
547            log("Ping test Fail:  IOException");
548        } catch (InterruptedException e) {
549            log("Ping test Fail: InterruptedException");
550        }
551        log("return");
552        return result;
553    }
554
555    /**
556     * Associate the device to given SSID
557     * If the device is already associated with a WiFi, disconnect and forget it,
558     * We don't verify whether the connection is successful or not, leave this to the test
559     */
560    public boolean connectToWifi(String knownSSID) {
561        WifiConfiguration config = new WifiConfiguration();
562        config.SSID = knownSSID;
563        config.allowedKeyManagement.set(KeyMgmt.NONE);
564        return connectToWifiWithConfiguration(config);
565    }
566
567    /**
568     * Connect to Wi-Fi with the given configuration. Note the SSID in the configuration
569     * is pure string, we need to convert it to quoted string.
570     * @param config
571     * @return
572     */
573    public boolean connectToWifiWithConfiguration(WifiConfiguration config) {
574        String ssid = config.SSID;
575        config.SSID = convertToQuotedString(ssid);
576
577        //If Wifi is not enabled, enable it
578        if (!mWifiManager.isWifiEnabled()) {
579            log("Wifi is not enabled, enable it");
580            mWifiManager.setWifiEnabled(true);
581            // wait for the wifi state change before start scanning.
582            if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2*SHORT_TIMEOUT)) {
583                log("wait for WIFI_STATE_ENABLED failed");
584                return false;
585            }
586        }
587
588        boolean foundApInScanResults = false;
589        for (int retry = 0; retry < 5; retry++) {
590            List<ScanResult> netList = mWifiManager.getScanResults();
591            if (netList != null) {
592                log("size of scan result list: " + netList.size());
593                for (int i = 0; i < netList.size(); i++) {
594                    ScanResult sr= netList.get(i);
595                    if (sr.SSID.equals(ssid)) {
596                        log("found " + ssid + " in the scan result list");
597                        log("retry: " + retry);
598                        foundApInScanResults = true;
599                        mWifiManager.connect(mChannel, config,
600                                new WifiManager.ActionListener() {
601                                    public void onSuccess() {
602                                    }
603                                    public void onFailure(int reason) {
604                                        log("connect failure " + reason);
605                                    }
606                                });
607                        break;
608                   }
609                }
610            }
611            if (foundApInScanResults) {
612                return true;
613            } else {
614                // Start an active scan
615                mWifiManager.startScanActive();
616                mScanResultIsAvailable = false;
617                long startTime = System.currentTimeMillis();
618                while (!mScanResultIsAvailable) {
619                    if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
620                        log("wait for scan results timeout");
621                        return false;
622                    }
623                    // wait for the scan results to be available
624                    synchronized (this) {
625                        // wait for the scan result to be available
626                        try {
627                            this.wait(WAIT_FOR_SCAN_RESULT);
628                        } catch (InterruptedException e) {
629                            e.printStackTrace();
630                        }
631                        if ((mWifiManager.getScanResults() == null) ||
632                                (mWifiManager.getScanResults().size() <= 0)) {
633                            continue;
634                        }
635                        mScanResultIsAvailable = true;
636                    }
637                }
638            }
639        }
640        return false;
641    }
642
643    /*
644     * Disconnect from the current AP and remove configured networks.
645     */
646    public boolean disconnectAP() {
647        // remove saved networks
648        List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
649        log("size of wifiConfigList: " + wifiConfigList.size());
650        for (WifiConfiguration wifiConfig: wifiConfigList) {
651            log("remove wifi configuration: " + wifiConfig.networkId);
652            int netId = wifiConfig.networkId;
653            mWifiManager.forget(mChannel, netId, new WifiManager.ActionListener() {
654                    public void onSuccess() {
655                    }
656                    public void onFailure(int reason) {
657                        log("Failed to forget " + reason);
658                    }
659                });
660        }
661        return true;
662    }
663    /**
664     * Disable Wifi
665     * @return true if Wifi is disabled successfully
666     */
667    public boolean disableWifi() {
668        return mWifiManager.setWifiEnabled(false);
669    }
670
671    /**
672     * Remove configured networks and disable wifi
673     */
674    public boolean removeConfiguredNetworksAndDisableWifi() {
675        if (!disconnectAP()) {
676           return false;
677        }
678        sleep(SHORT_TIMEOUT);
679        if (!mWifiManager.setWifiEnabled(false)) {
680            return false;
681        }
682        sleep(SHORT_TIMEOUT);
683        return true;
684    }
685
686    private void sleep(long sleeptime) {
687        try {
688            Thread.sleep(sleeptime);
689        } catch (InterruptedException e) {}
690    }
691
692    /**
693     * Set airplane mode
694     */
695    public void setAirplaneMode(Context context, boolean enableAM) {
696        //set the airplane mode
697        Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
698                enableAM ? 1 : 0);
699        // Post the intent
700        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
701        intent.putExtra("state", enableAM);
702        context.sendBroadcast(intent);
703    }
704
705    protected static String convertToQuotedString(String string) {
706        return "\"" + string + "\"";
707    }
708
709    @Override
710    protected void onDestroy() {
711        super.onDestroy();
712
713        //Unregister receiver
714        if (mConnectivityReceiver != null) {
715            unregisterReceiver(mConnectivityReceiver);
716        }
717        if (mWifiReceiver != null) {
718            unregisterReceiver(mWifiReceiver);
719        }
720        log("onDestroy, inst=" + Integer.toHexString(hashCode()));
721    }
722
723    @Override
724    public void onStart() {
725        super.onStart();
726        mContext = this;
727        Bundle bundle = this.getIntent().getExtras();
728        if (bundle != null){
729            mPowerSsid = bundle.getString("power_ssid");
730        }
731    }
732    //A thread to set the device into airplane mode then turn on wifi.
733    Thread setDeviceWifiAndAirplaneThread = new Thread(new Runnable() {
734        public void run() {
735            setAirplaneMode(mContext, true);
736            connectToWifi(mPowerSsid);
737        }
738    });
739
740    //A thread to set the device into wifi
741    Thread setDeviceInWifiOnlyThread = new Thread(new Runnable() {
742        public void run() {
743            connectToWifi(mPowerSsid);
744        }
745    });
746
747    @Override
748    public boolean onKeyDown(int keyCode, KeyEvent event) {
749        switch (keyCode) {
750            //This is a tricky way for the scripted monkey to
751            //set the device in wifi and wifi in airplane mode.
752            case KeyEvent.KEYCODE_1:
753                setDeviceWifiAndAirplaneThread.start();
754                break;
755
756            case KeyEvent.KEYCODE_2:
757                setDeviceInWifiOnlyThread.start();
758                break;
759        }
760        return super.onKeyDown(keyCode, event);
761    }
762
763    private void log(String message) {
764        Log.v(LOG_TAG, message);
765    }
766}
767