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