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