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