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