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