RadioInfo.java revision 9302986035f46d2868c23db6349fd04b543eb676
1/*
2 * Copyright (C) 2006 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.settings;
18
19import android.app.Activity;
20import android.content.Context;
21import android.content.Intent;
22import android.content.pm.PackageManager;
23import android.content.pm.ResolveInfo;
24import android.content.res.Resources;
25import android.net.ConnectivityManager;
26import android.net.LinkProperties;
27import android.net.TrafficStats;
28import android.net.Uri;
29import android.os.AsyncResult;
30import android.os.Bundle;
31import android.os.Handler;
32import android.os.Message;
33import android.os.RemoteException;
34import android.os.ServiceManager;
35import android.os.SystemProperties;
36import android.telephony.CellLocation;
37import android.telephony.PhoneStateListener;
38import android.telephony.ServiceState;
39import android.telephony.TelephonyManager;
40import android.telephony.NeighboringCellInfo;
41import android.telephony.cdma.CdmaCellLocation;
42import android.telephony.gsm.GsmCellLocation;
43import android.text.format.DateUtils;
44import android.util.Log;
45import android.view.Menu;
46import android.view.MenuItem;
47import android.view.View;
48import android.view.View.OnClickListener;
49import android.widget.AdapterView;
50import android.widget.ArrayAdapter;
51import android.widget.Button;
52import android.widget.Spinner;
53import android.widget.TextView;
54import android.widget.EditText;
55
56import com.android.internal.telephony.DataConnection;
57import com.android.internal.telephony.Phone;
58import com.android.internal.telephony.PhoneFactory;
59import com.android.internal.telephony.PhoneStateIntentReceiver;
60import com.android.internal.telephony.TelephonyProperties;
61import com.android.internal.telephony.gsm.GsmDataConnection;
62
63import org.apache.http.HttpResponse;
64import org.apache.http.client.HttpClient;
65import org.apache.http.client.methods.HttpGet;
66import org.apache.http.impl.client.DefaultHttpClient;
67
68import java.io.IOException;
69import java.net.InetAddress;
70import java.net.UnknownHostException;
71import java.util.ArrayList;
72import java.util.List;
73
74import android.util.Log;
75
76public class RadioInfo extends Activity {
77    private final String TAG = "phone";
78
79    private static final int EVENT_PHONE_STATE_CHANGED = 100;
80    private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
81    private static final int EVENT_SERVICE_STATE_CHANGED = 300;
82    private static final int EVENT_CFI_CHANGED = 302;
83
84    private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
85    private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
86    private static final int EVENT_QUERY_NEIGHBORING_CIDS_DONE = 1002;
87    private static final int EVENT_QUERY_SMSC_DONE = 1005;
88    private static final int EVENT_UPDATE_SMSC_DONE = 1006;
89
90    private static final int MENU_ITEM_SELECT_BAND  = 0;
91    private static final int MENU_ITEM_VIEW_ADN     = 1;
92    private static final int MENU_ITEM_VIEW_FDN     = 2;
93    private static final int MENU_ITEM_VIEW_SDN     = 3;
94    private static final int MENU_ITEM_GET_PDP_LIST = 4;
95    private static final int MENU_ITEM_TOGGLE_DATA  = 5;
96
97    static final String ENABLE_DATA_STR = "Enable data connection";
98    static final String DISABLE_DATA_STR = "Disable data connection";
99
100    private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
101    private TextView number;
102    private TextView callState;
103    private TextView operatorName;
104    private TextView roamingState;
105    private TextView gsmState;
106    private TextView gprsState;
107    private TextView network;
108    private TextView dBm;
109    private TextView mMwi;
110    private TextView mCfi;
111    private TextView mLocation;
112    private TextView mNeighboringCids;
113    private TextView resets;
114    private TextView attempts;
115    private TextView successes;
116    private TextView disconnects;
117    private TextView sentSinceReceived;
118    private TextView sent;
119    private TextView received;
120    private TextView mPingIpAddr;
121    private TextView mPingHostname;
122    private TextView mHttpClientTest;
123    private TextView dnsCheckState;
124    private EditText smsc;
125    private Button radioPowerButton;
126    private Button dnsCheckToggleButton;
127    private Button pingTestButton;
128    private Button updateSmscButton;
129    private Button refreshSmscButton;
130    private Button oemInfoButton;
131    private Spinner preferredNetworkType;
132
133    private TelephonyManager mTelephonyManager;
134    private Phone phone = null;
135    private PhoneStateIntentReceiver mPhoneStateReceiver;
136
137    private String mPingIpAddrResult;
138    private String mPingHostnameResult;
139    private String mHttpClientTestResult;
140    private boolean mMwiValue = false;
141    private boolean mCfiValue = false;
142
143    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
144        @Override
145        public void onDataConnectionStateChanged(int state) {
146            updateDataState();
147            updateDataStats();
148            updatePdpList();
149            updateNetworkType();
150        }
151
152        @Override
153        public void onDataActivity(int direction) {
154            updateDataStats2();
155        }
156
157        @Override
158        public void onCellLocationChanged(CellLocation location) {
159            updateLocation(location);
160        }
161
162        @Override
163        public void onMessageWaitingIndicatorChanged(boolean mwi) {
164            mMwiValue = mwi;
165            updateMessageWaiting();
166        }
167
168        @Override
169        public void onCallForwardingIndicatorChanged(boolean cfi) {
170            mCfiValue = cfi;
171            updateCallRedirect();
172        }
173    };
174
175    private Handler mHandler = new Handler() {
176        public void handleMessage(Message msg) {
177            AsyncResult ar;
178            switch (msg.what) {
179                case EVENT_PHONE_STATE_CHANGED:
180                    updatePhoneState();
181                    break;
182
183                case EVENT_SIGNAL_STRENGTH_CHANGED:
184                    updateSignalStrength();
185                    break;
186
187                case EVENT_SERVICE_STATE_CHANGED:
188                    updateServiceState();
189                    updatePowerState();
190                    break;
191
192                case EVENT_QUERY_PREFERRED_TYPE_DONE:
193                    ar= (AsyncResult) msg.obj;
194                    if (ar.exception == null) {
195                        int type = ((int[])ar.result)[0];
196                        preferredNetworkType.setSelection(type, true);
197                    } else {
198                        preferredNetworkType.setSelection(8, true);
199                    }
200                    break;
201                case EVENT_SET_PREFERRED_TYPE_DONE:
202                    ar= (AsyncResult) msg.obj;
203                    if (ar.exception != null) {
204                        phone.getPreferredNetworkType(
205                                obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
206                    }
207                    break;
208                case EVENT_QUERY_NEIGHBORING_CIDS_DONE:
209                    ar= (AsyncResult) msg.obj;
210                    if (ar.exception == null) {
211                        updateNeighboringCids((ArrayList<NeighboringCellInfo>)ar.result);
212                    } else {
213                        mNeighboringCids.setText("unknown");
214                    }
215                    break;
216                case EVENT_QUERY_SMSC_DONE:
217                    ar= (AsyncResult) msg.obj;
218                    if (ar.exception != null) {
219                        smsc.setText("refresh error");
220                    } else {
221                        smsc.setText((String)ar.result);
222                    }
223                    break;
224                case EVENT_UPDATE_SMSC_DONE:
225                    updateSmscButton.setEnabled(true);
226                    ar= (AsyncResult) msg.obj;
227                    if (ar.exception != null) {
228                        smsc.setText("update error");
229                    }
230                    break;
231                default:
232                    break;
233
234            }
235        }
236    };
237
238    @Override
239    public void onCreate(Bundle icicle) {
240        super.onCreate(icicle);
241
242        setContentView(R.layout.radio_info);
243
244        mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
245        phone = PhoneFactory.getDefaultPhone();
246
247        mDeviceId= (TextView) findViewById(R.id.imei);
248        number = (TextView) findViewById(R.id.number);
249        callState = (TextView) findViewById(R.id.call);
250        operatorName = (TextView) findViewById(R.id.operator);
251        roamingState = (TextView) findViewById(R.id.roaming);
252        gsmState = (TextView) findViewById(R.id.gsm);
253        gprsState = (TextView) findViewById(R.id.gprs);
254        network = (TextView) findViewById(R.id.network);
255        dBm = (TextView) findViewById(R.id.dbm);
256        mMwi = (TextView) findViewById(R.id.mwi);
257        mCfi = (TextView) findViewById(R.id.cfi);
258        mLocation = (TextView) findViewById(R.id.location);
259        mNeighboringCids = (TextView) findViewById(R.id.neighboring);
260
261        resets = (TextView) findViewById(R.id.resets);
262        attempts = (TextView) findViewById(R.id.attempts);
263        successes = (TextView) findViewById(R.id.successes);
264        disconnects = (TextView) findViewById(R.id.disconnects);
265        sentSinceReceived = (TextView) findViewById(R.id.sentSinceReceived);
266        sent = (TextView) findViewById(R.id.sent);
267        received = (TextView) findViewById(R.id.received);
268        smsc = (EditText) findViewById(R.id.smsc);
269        dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
270
271        mPingIpAddr = (TextView) findViewById(R.id.pingIpAddr);
272        mPingHostname = (TextView) findViewById(R.id.pingHostname);
273        mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
274
275        preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
276        ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
277                android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
278        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
279        preferredNetworkType.setAdapter(adapter);
280        preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
281
282        radioPowerButton = (Button) findViewById(R.id.radio_power);
283        radioPowerButton.setOnClickListener(mPowerButtonHandler);
284
285        pingTestButton = (Button) findViewById(R.id.ping_test);
286        pingTestButton.setOnClickListener(mPingButtonHandler);
287        updateSmscButton = (Button) findViewById(R.id.update_smsc);
288        updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
289        refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
290        refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
291        dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
292        dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
293
294        oemInfoButton = (Button) findViewById(R.id.oem_info);
295        oemInfoButton.setOnClickListener(mOemInfoButtonHandler);
296        PackageManager pm = getPackageManager();
297        Intent oemInfoIntent = new Intent("com.android.settings.OEM_RADIO_INFO");
298        List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
299        if (oemInfoIntentList.size() == 0) {
300            oemInfoButton.setEnabled(false);
301        }
302
303        mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler);
304        mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);
305        mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
306        mPhoneStateReceiver.notifyPhoneCallState(EVENT_PHONE_STATE_CHANGED);
307
308        phone.getPreferredNetworkType(
309                mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
310        phone.getNeighboringCids(
311                mHandler.obtainMessage(EVENT_QUERY_NEIGHBORING_CIDS_DONE));
312
313        CellLocation.requestLocationUpdate();
314    }
315
316    @Override
317    protected void onResume() {
318        super.onResume();
319
320        updatePhoneState();
321        updateSignalStrength();
322        updateMessageWaiting();
323        updateCallRedirect();
324        updateServiceState();
325        updateLocation(mTelephonyManager.getCellLocation());
326        updateDataState();
327        updateDataStats();
328        updateDataStats2();
329        updatePowerState();
330        updateProperties();
331        updateDnsCheckState();
332
333        Log.i(TAG, "[RadioInfo] onResume: register phone & data intents");
334
335        mPhoneStateReceiver.registerIntent();
336        mTelephonyManager.listen(mPhoneStateListener,
337                  PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
338                | PhoneStateListener.LISTEN_DATA_ACTIVITY
339                | PhoneStateListener.LISTEN_CELL_LOCATION
340                | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
341                | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
342    }
343
344    @Override
345    public void onPause() {
346        super.onPause();
347
348        Log.i(TAG, "[RadioInfo] onPause: unregister phone & data intents");
349
350        mPhoneStateReceiver.unregisterIntent();
351        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
352    }
353
354    @Override
355    public boolean onCreateOptionsMenu(Menu menu) {
356        menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
357                .setOnMenuItemClickListener(mSelectBandCallback)
358                .setAlphabeticShortcut('b');
359        menu.add(1, MENU_ITEM_VIEW_ADN, 0,
360                R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
361        menu.add(1, MENU_ITEM_VIEW_FDN, 0,
362                R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
363        menu.add(1, MENU_ITEM_VIEW_SDN, 0,
364                R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
365        menu.add(1, MENU_ITEM_GET_PDP_LIST,
366                0, R.string.radioInfo_menu_getPDP).setOnMenuItemClickListener(mGetPdpList);
367        menu.add(1, MENU_ITEM_TOGGLE_DATA,
368                0, DISABLE_DATA_STR).setOnMenuItemClickListener(mToggleData);
369        return true;
370    }
371
372    @Override
373    public boolean onPrepareOptionsMenu(Menu menu) {
374        // Get the TOGGLE DATA menu item in the right state.
375        MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
376        int state = mTelephonyManager.getDataState();
377        boolean visible = true;
378
379        switch (state) {
380            case TelephonyManager.DATA_CONNECTED:
381            case TelephonyManager.DATA_SUSPENDED:
382                item.setTitle(DISABLE_DATA_STR);
383                break;
384            case TelephonyManager.DATA_DISCONNECTED:
385                item.setTitle(ENABLE_DATA_STR);
386                break;
387            default:
388                visible = false;
389                break;
390        }
391        item.setVisible(visible);
392        return true;
393    }
394
395    private boolean isRadioOn() {
396        return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
397    }
398
399    private void updatePowerState() {
400        String buttonText = isRadioOn() ?
401                            getString(R.string.turn_off_radio) :
402                            getString(R.string.turn_on_radio);
403        radioPowerButton.setText(buttonText);
404    }
405
406    private void updateDnsCheckState() {
407        dnsCheckState.setText(phone.isDnsCheckDisabled() ?
408                "0.0.0.0 allowed" :"0.0.0.0 not allowed");
409    }
410
411    private final void
412    updateSignalStrength() {
413        // TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener
414        // should probably used instead.
415        int state = mPhoneStateReceiver.getServiceState().getState();
416        Resources r = getResources();
417
418        if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
419                (ServiceState.STATE_POWER_OFF == state)) {
420            dBm.setText("0");
421        }
422
423        int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
424
425        if (-1 == signalDbm) signalDbm = 0;
426
427        int signalAsu = mPhoneStateReceiver.getSignalStrengthLevelAsu();
428
429        if (-1 == signalAsu) signalAsu = 0;
430
431        dBm.setText(String.valueOf(signalDbm) + " "
432            + r.getString(R.string.radioInfo_display_dbm) + "   "
433            + String.valueOf(signalAsu) + " "
434            + r.getString(R.string.radioInfo_display_asu));
435    }
436
437    private final void updateLocation(CellLocation location) {
438        Resources r = getResources();
439        if (location instanceof GsmCellLocation) {
440            GsmCellLocation loc = (GsmCellLocation)location;
441            int lac = loc.getLac();
442            int cid = loc.getCid();
443            mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
444                    + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
445                    + "   "
446                    + r.getString(R.string.radioInfo_cid) + " = "
447                    + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
448        } else if (location instanceof CdmaCellLocation) {
449            CdmaCellLocation loc = (CdmaCellLocation)location;
450            int bid = loc.getBaseStationId();
451            int sid = loc.getSystemId();
452            int nid = loc.getNetworkId();
453            int lat = loc.getBaseStationLatitude();
454            int lon = loc.getBaseStationLongitude();
455            mLocation.setText("BID = "
456                    + ((bid == -1) ? "unknown" : Integer.toHexString(bid))
457                    + "   "
458                    + "SID = "
459                    + ((sid == -1) ? "unknown" : Integer.toHexString(sid))
460                    + "   "
461                    + "NID = "
462                    + ((nid == -1) ? "unknown" : Integer.toHexString(nid))
463                    + "\n"
464                    + "LAT = "
465                    + ((lat == -1) ? "unknown" : Integer.toHexString(lat))
466                    + "   "
467                    + "LONG = "
468                    + ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
469        } else {
470            mLocation.setText("unknown");
471        }
472
473
474    }
475
476    private final void updateNeighboringCids(ArrayList<NeighboringCellInfo> cids) {
477        StringBuilder sb = new StringBuilder();
478
479        if (cids != null) {
480            if ( cids.isEmpty() ) {
481                sb.append("no neighboring cells");
482            } else {
483                for (NeighboringCellInfo cell : cids) {
484                    sb.append(cell.toString()).append(" ");
485                }
486            }
487        } else {
488            sb.append("unknown");
489        }
490        mNeighboringCids.setText(sb.toString());
491    }
492
493    private final void
494    updateMessageWaiting() {
495        mMwi.setText(String.valueOf(mMwiValue));
496    }
497
498    private final void
499    updateCallRedirect() {
500        mCfi.setText(String.valueOf(mCfiValue));
501    }
502
503
504    private final void
505    updateServiceState() {
506        ServiceState serviceState = mPhoneStateReceiver.getServiceState();
507        int state = serviceState.getState();
508        Resources r = getResources();
509        String display = r.getString(R.string.radioInfo_unknown);
510
511        switch (state) {
512            case ServiceState.STATE_IN_SERVICE:
513                display = r.getString(R.string.radioInfo_service_in);
514                break;
515            case ServiceState.STATE_OUT_OF_SERVICE:
516            case ServiceState.STATE_EMERGENCY_ONLY:
517                display = r.getString(R.string.radioInfo_service_emergency);
518                break;
519            case ServiceState.STATE_POWER_OFF:
520                display = r.getString(R.string.radioInfo_service_off);
521                break;
522        }
523
524        gsmState.setText(display);
525
526        if (serviceState.getRoaming()) {
527            roamingState.setText(R.string.radioInfo_roaming_in);
528        } else {
529            roamingState.setText(R.string.radioInfo_roaming_not);
530        }
531
532        operatorName.setText(serviceState.getOperatorAlphaLong());
533    }
534
535    private final void
536    updatePhoneState() {
537        Phone.State state = mPhoneStateReceiver.getPhoneState();
538        Resources r = getResources();
539        String display = r.getString(R.string.radioInfo_unknown);
540
541        switch (state) {
542            case IDLE:
543                display = r.getString(R.string.radioInfo_phone_idle);
544                break;
545            case RINGING:
546                display = r.getString(R.string.radioInfo_phone_ringing);
547                break;
548            case OFFHOOK:
549                display = r.getString(R.string.radioInfo_phone_offhook);
550                break;
551        }
552
553        callState.setText(display);
554    }
555
556    private final void
557    updateDataState() {
558        int state = mTelephonyManager.getDataState();
559        Resources r = getResources();
560        String display = r.getString(R.string.radioInfo_unknown);
561
562        switch (state) {
563            case TelephonyManager.DATA_CONNECTED:
564                display = r.getString(R.string.radioInfo_data_connected);
565                break;
566            case TelephonyManager.DATA_CONNECTING:
567                display = r.getString(R.string.radioInfo_data_connecting);
568                break;
569            case TelephonyManager.DATA_DISCONNECTED:
570                display = r.getString(R.string.radioInfo_data_disconnected);
571                break;
572            case TelephonyManager.DATA_SUSPENDED:
573                display = r.getString(R.string.radioInfo_data_suspended);
574                break;
575        }
576
577        gprsState.setText(display);
578    }
579
580    private final void updateNetworkType() {
581        Resources r = getResources();
582        String display = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
583                r.getString(R.string.radioInfo_unknown));
584
585        network.setText(display);
586    }
587
588    private final void
589    updateProperties() {
590        String s;
591        Resources r = getResources();
592
593        s = phone.getDeviceId();
594        if (s == null) s = r.getString(R.string.radioInfo_unknown);
595        mDeviceId.setText(s);
596
597
598        s = phone.getLine1Number();
599        if (s == null) s = r.getString(R.string.radioInfo_unknown);
600        number.setText(s);
601    }
602
603    private final void updateDataStats() {
604        String s;
605
606        s = SystemProperties.get("net.gsm.radio-reset", "0");
607        resets.setText(s);
608
609        s = SystemProperties.get("net.gsm.attempt-gprs", "0");
610        attempts.setText(s);
611
612        s = SystemProperties.get("net.gsm.succeed-gprs", "0");
613        successes.setText(s);
614
615        //s = SystemProperties.get("net.gsm.disconnect", "0");
616        //disconnects.setText(s);
617
618        s = SystemProperties.get("net.ppp.reset-by-timeout", "0");
619        sentSinceReceived.setText(s);
620    }
621
622    private final void updateDataStats2() {
623        Resources r = getResources();
624
625        long txPackets = TrafficStats.getMobileTxPackets();
626        long rxPackets = TrafficStats.getMobileRxPackets();
627        long txBytes   = TrafficStats.getMobileTxBytes();
628        long rxBytes   = TrafficStats.getMobileRxBytes();
629
630        String packets = r.getString(R.string.radioInfo_display_packets);
631        String bytes   = r.getString(R.string.radioInfo_display_bytes);
632
633        sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
634        received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
635    }
636
637    /**
638     * Ping a IP address.
639     */
640    private final void pingIpAddr() {
641        try {
642            // This is hardcoded IP addr. This is for testing purposes.
643            // We would need to get rid of this before release.
644            String ipAddress = "74.125.47.104";
645            Process p = Runtime.getRuntime().exec("ping -c 1 " + ipAddress);
646            int status = p.waitFor();
647            if (status == 0) {
648                mPingIpAddrResult = "Pass";
649            } else {
650                mPingIpAddrResult = "Fail: IP addr not reachable";
651            }
652        } catch (IOException e) {
653            mPingIpAddrResult = "Fail: IOException";
654        } catch (InterruptedException e) {
655            mPingIpAddrResult = "Fail: InterruptedException";
656        }
657    }
658
659    /**
660     *  Ping a host name
661     */
662    private final void pingHostname() {
663        try {
664            Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com");
665            int status = p.waitFor();
666            if (status == 0) {
667                mPingHostnameResult = "Pass";
668            } else {
669                mPingHostnameResult = "Fail: Host unreachable";
670            }
671        } catch (UnknownHostException e) {
672            mPingHostnameResult = "Fail: Unknown Host";
673        } catch (IOException e) {
674            mPingHostnameResult= "Fail: IOException";
675        } catch (InterruptedException e) {
676            mPingHostnameResult = "Fail: InterruptedException";
677        }
678    }
679
680    /**
681     * This function checks for basic functionality of HTTP Client.
682     */
683    private void httpClientTest() {
684        HttpClient client = new DefaultHttpClient();
685        try {
686            HttpGet request = new HttpGet("http://www.google.com");
687            HttpResponse response = client.execute(request);
688            if (response.getStatusLine().getStatusCode() == 200) {
689                mHttpClientTestResult = "Pass";
690            } else {
691                mHttpClientTestResult = "Fail: Code: " + String.valueOf(response);
692            }
693            request.abort();
694        } catch (IOException e) {
695            mHttpClientTestResult = "Fail: IOException";
696        }
697    }
698
699    private void refreshSmsc() {
700        phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
701    }
702
703    private final void updatePingState() {
704        final Handler handler = new Handler();
705        // Set all to unknown since the threads will take a few secs to update.
706        mPingIpAddrResult = getResources().getString(R.string.radioInfo_unknown);
707        mPingHostnameResult = getResources().getString(R.string.radioInfo_unknown);
708        mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
709
710        mPingIpAddr.setText(mPingIpAddrResult);
711        mPingHostname.setText(mPingHostnameResult);
712        mHttpClientTest.setText(mHttpClientTestResult);
713
714        final Runnable updatePingResults = new Runnable() {
715            public void run() {
716                mPingIpAddr.setText(mPingIpAddrResult);
717                mPingHostname.setText(mPingHostnameResult);
718                mHttpClientTest.setText(mHttpClientTestResult);
719            }
720        };
721        Thread ipAddr = new Thread() {
722            @Override
723            public void run() {
724                pingIpAddr();
725                handler.post(updatePingResults);
726            }
727        };
728        ipAddr.start();
729
730        Thread hostname = new Thread() {
731            @Override
732            public void run() {
733                pingHostname();
734                handler.post(updatePingResults);
735            }
736        };
737        hostname.start();
738
739        Thread httpClient = new Thread() {
740            @Override
741            public void run() {
742                httpClientTest();
743                handler.post(updatePingResults);
744            }
745        };
746        httpClient.start();
747    }
748
749    private final void updatePdpList() {
750        StringBuilder sb = new StringBuilder("========DATA=======\n");
751
752//        List<DataConnection> dcs = phone.getCurrentDataConnectionList();
753//
754//        for (DataConnection dc : dcs) {
755//            sb.append("    State=").append(dc.getStateAsString()).append("\n");
756//            if (dc.isActive()) {
757//                long timeElapsed =
758//                    (System.currentTimeMillis() - dc.getConnectionTime())/1000;
759//                sb.append("    connected at ")
760//                  .append(DateUtils.timeString(dc.getConnectionTime()))
761//                  .append(" and elapsed ")
762//                  .append(DateUtils.formatElapsedTime(timeElapsed));
763//
764//                if (dc instanceof GsmDataConnection) {
765//                    GsmDataConnection pdp = (GsmDataConnection)dc;
766//                    sb.append("\n    to ")
767//                      .append(pdp.getApn().toString());
768//                }
769//                sb.append("\nLinkProperties: ");
770//                sb.append(phone.getLinkProperties(phone.getActiveApnTypes()[0]).toString());
771//            } else if (dc.isInactive()) {
772//                sb.append("    disconnected with last try at ")
773//                  .append(DateUtils.timeString(dc.getLastFailTime()))
774//                  .append("\n    fail because ")
775//                  .append(dc.getLastFailCause().toString());
776//            } else {
777//                if (dc instanceof GsmDataConnection) {
778//                    GsmDataConnection pdp = (GsmDataConnection)dc;
779//                    sb.append("    is connecting to ")
780//                      .append(pdp.getApn().toString());
781//                } else {
782//                    sb.append("    is connecting");
783//                }
784//            }
785//            sb.append("\n===================");
786//        }
787
788        disconnects.setText(sb.toString());
789    }
790
791    private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
792        public boolean onMenuItemClick(MenuItem item) {
793            Intent intent = new Intent(Intent.ACTION_VIEW);
794            // XXX We need to specify the component here because if we don't
795            // the activity manager will try to resolve the type by calling
796            // the content provider, which causes it to be loaded in a process
797            // other than the Dialer process, which causes a lot of stuff to
798            // break.
799            intent.setClassName("com.android.phone",
800                    "com.android.phone.SimContacts");
801            startActivity(intent);
802            return true;
803        }
804    };
805
806    private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
807        public boolean onMenuItemClick(MenuItem item) {
808            Intent intent = new Intent(Intent.ACTION_VIEW);
809            // XXX We need to specify the component here because if we don't
810            // the activity manager will try to resolve the type by calling
811            // the content provider, which causes it to be loaded in a process
812            // other than the Dialer process, which causes a lot of stuff to
813            // break.
814            intent.setClassName("com.android.phone",
815                    "com.android.phone.FdnList");
816            startActivity(intent);
817            return true;
818        }
819    };
820
821    private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
822        public boolean onMenuItemClick(MenuItem item) {
823            Intent intent = new Intent(
824                    Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
825            // XXX We need to specify the component here because if we don't
826            // the activity manager will try to resolve the type by calling
827            // the content provider, which causes it to be loaded in a process
828            // other than the Dialer process, which causes a lot of stuff to
829            // break.
830            intent.setClassName("com.android.phone",
831                    "com.android.phone.ADNList");
832            startActivity(intent);
833            return true;
834        }
835    };
836
837    private MenuItem.OnMenuItemClickListener mGetPdpList = new MenuItem.OnMenuItemClickListener() {
838        public boolean onMenuItemClick(MenuItem item) {
839            phone.getDataCallList(null);
840            return true;
841        }
842    };
843
844    private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
845        public boolean onMenuItemClick(MenuItem item) {
846            Intent intent = new Intent();
847            intent.setClass(RadioInfo.this, BandMode.class);
848            startActivity(intent);
849            return true;
850        }
851    };
852
853    private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
854        public boolean onMenuItemClick(MenuItem item) {
855            ConnectivityManager cm =
856                    (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
857            int state = mTelephonyManager.getDataState();
858            switch (state) {
859                case TelephonyManager.DATA_CONNECTED:
860                    cm.setMobileDataEnabled(false);
861                    break;
862                case TelephonyManager.DATA_DISCONNECTED:
863                    cm.setMobileDataEnabled(true);
864                    break;
865                default:
866                    // do nothing
867                    break;
868            }
869            return true;
870        }
871    };
872
873    OnClickListener mPowerButtonHandler = new OnClickListener() {
874        public void onClick(View v) {
875            //log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
876            phone.setRadioPower(!isRadioOn());
877        }
878    };
879
880    OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
881        public void onClick(View v) {
882            phone.disableDnsCheck(!phone.isDnsCheckDisabled());
883            updateDnsCheckState();
884        }
885    };
886
887    OnClickListener mOemInfoButtonHandler = new OnClickListener() {
888        public void onClick(View v) {
889            Intent intent = new Intent("com.android.settings.OEM_RADIO_INFO");
890            try {
891                startActivity(intent);
892            } catch (android.content.ActivityNotFoundException ex) {
893                Log.d(TAG, "OEM-specific Info/Settings Activity Not Found : " + ex);
894                // If the activity does not exist, there are no OEM
895                // settings, and so we can just do nothing...
896            }
897        }
898    };
899
900    OnClickListener mPingButtonHandler = new OnClickListener() {
901        public void onClick(View v) {
902            updatePingState();
903        }
904    };
905
906    OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
907        public void onClick(View v) {
908            updateSmscButton.setEnabled(false);
909            phone.setSmscAddress(smsc.getText().toString(),
910                    mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
911        }
912    };
913
914    OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
915        public void onClick(View v) {
916            refreshSmsc();
917        }
918    };
919
920    AdapterView.OnItemSelectedListener
921            mPreferredNetworkHandler = new AdapterView.OnItemSelectedListener() {
922        public void onItemSelected(AdapterView parent, View v, int pos, long id) {
923            Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
924            if (pos>=0 && pos<=7) { //IS THIS NEEDED to extend to the entire range of values
925                phone.setPreferredNetworkType(pos, msg);
926            }
927        }
928
929        public void onNothingSelected(AdapterView parent) {
930        }
931    };
932
933    private String[] mPreferredNetworkLabels = {
934            "WCDMA preferred",
935            "GSM only",
936            "WCDMA only",
937            "GSM auto (PRL)",
938            "CDMA auto (PRL)",
939            "CDMA only",
940            "EvDo only",
941            "GSM/CDMA auto (PRL)",
942            "Unknown"};
943}
944