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