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