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