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