Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.app.Dialog;
     22 import android.app.QueuedWork;
     23 import android.content.ComponentName;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.pm.PackageManager;
     27 import android.content.pm.ResolveInfo;
     28 import android.content.res.Resources;
     29 import android.graphics.Typeface;
     30 import android.net.TrafficStats;
     31 import android.net.Uri;
     32 import android.os.AsyncResult;
     33 import android.os.Bundle;
     34 import android.os.Handler;
     35 import android.os.Message;
     36 import android.telephony.CarrierConfigManager;
     37 import android.telephony.CellInfo;
     38 import android.telephony.CellInfoCdma;
     39 import android.telephony.CellInfoGsm;
     40 import android.telephony.CellInfoLte;
     41 import android.telephony.CellInfoWcdma;
     42 import android.telephony.CellIdentityCdma;
     43 import android.telephony.CellIdentityGsm;
     44 import android.telephony.CellIdentityLte;
     45 import android.telephony.CellIdentityWcdma;
     46 import android.telephony.CellLocation;
     47 import android.telephony.CellSignalStrengthCdma;
     48 import android.telephony.CellSignalStrengthGsm;
     49 import android.telephony.CellSignalStrengthLte;
     50 import android.telephony.CellSignalStrengthWcdma;
     51 import android.telephony.DataConnectionRealTimeInfo;
     52 import android.telephony.NeighboringCellInfo;
     53 import android.telephony.PreciseCallState;
     54 import android.telephony.PhoneStateListener;
     55 import android.telephony.ServiceState;
     56 import android.telephony.SignalStrength;
     57 import android.telephony.SubscriptionManager;
     58 import android.telephony.TelephonyManager;
     59 import android.telephony.cdma.CdmaCellLocation;
     60 import android.telephony.gsm.GsmCellLocation;
     61 import android.util.Log;
     62 import android.view.Menu;
     63 import android.view.MenuItem;
     64 import android.view.View;
     65 import android.view.View.OnClickListener;
     66 import android.widget.AdapterView;
     67 import android.widget.ArrayAdapter;
     68 import android.widget.Button;
     69 import android.widget.CompoundButton;
     70 import android.widget.CompoundButton.OnCheckedChangeListener;
     71 import android.widget.EditText;
     72 import android.widget.Spinner;
     73 import android.widget.Switch;
     74 import android.widget.TextView;
     75 
     76 import com.android.ims.ImsConfig;
     77 import com.android.ims.ImsException;
     78 import com.android.ims.ImsManager;
     79 import com.android.internal.telephony.Phone;
     80 import com.android.internal.telephony.PhoneConstants;
     81 import com.android.internal.telephony.PhoneFactory;
     82 import com.android.internal.telephony.RILConstants;
     83 import com.android.internal.telephony.TelephonyProperties;
     84 
     85 import java.io.IOException;
     86 import java.net.HttpURLConnection;
     87 import java.net.URL;
     88 import java.net.UnknownHostException;
     89 import java.util.ArrayList;
     90 import java.util.List;
     91 
     92 public class RadioInfo extends Activity {
     93     private static final String TAG = "RadioInfo";
     94 
     95     private static final String[] mPreferredNetworkLabels = {
     96             "WCDMA preferred",
     97             "GSM only",
     98             "WCDMA only",
     99             "GSM auto (PRL)",
    100             "CDMA auto (PRL)",
    101             "CDMA only",
    102             "EvDo only",
    103             "Global auto (PRL)",
    104             "LTE/CDMA auto (PRL)",
    105             "LTE/UMTS auto (PRL)",
    106             "LTE/CDMA/UMTS auto (PRL)",
    107             "LTE only",
    108             "LTE/WCDMA",
    109             "TD-SCDMA only",
    110             "TD-SCDMA/WCDMA",
    111             "LTE/TD-SCDMA",
    112             "TD-SCDMA/GSM",
    113             "TD-SCDMA/UMTS",
    114             "LTE/TD-SCDMA/WCDMA",
    115             "LTE/TD-SCDMA/UMTS",
    116             "TD-SCDMA/CDMA/UMTS",
    117             "Global/TD-SCDMA",
    118             "Unknown"
    119     };
    120 
    121 
    122     private static final int CELL_INFO_LIST_RATE_DISABLED = Integer.MAX_VALUE;
    123     private static final int CELL_INFO_LIST_RATE_MAX = 0;
    124 
    125 
    126     private static final int IMS_VOLTE_PROVISIONED_CONFIG_ID =
    127         ImsConfig.ConfigConstants.VLT_SETTING_ENABLED;
    128 
    129     private static final int IMS_VT_PROVISIONED_CONFIG_ID =
    130         ImsConfig.ConfigConstants.LVC_SETTING_ENABLED;
    131 
    132     private static final int IMS_WFC_PROVISIONED_CONFIG_ID =
    133         ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED;
    134 
    135     private static final int EAB_PROVISIONED_CONFIG_ID =
    136         ImsConfig.ConfigConstants.EAB_SETTING_ENABLED;
    137 
    138     //Values in must match mCellInfoRefreshRates
    139     private static final String[] mCellInfoRefreshRateLabels = {
    140             "Disabled",
    141             "Immediate",
    142             "Min 5s",
    143             "Min 10s",
    144             "Min 60s"
    145     };
    146 
    147     //Values in seconds, must match mCellInfoRefreshRateLabels
    148     private static final int mCellInfoRefreshRates[] = {
    149         CELL_INFO_LIST_RATE_DISABLED,
    150         CELL_INFO_LIST_RATE_MAX,
    151         5000,
    152         10000,
    153         60000
    154     };
    155 
    156     private void log(String s) {
    157         Log.d(TAG, s);
    158     }
    159 
    160     private static final int EVENT_CFI_CHANGED = 302;
    161 
    162     private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
    163     private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
    164     private static final int EVENT_QUERY_SMSC_DONE = 1005;
    165     private static final int EVENT_UPDATE_SMSC_DONE = 1006;
    166 
    167     private static final int MENU_ITEM_SELECT_BAND  = 0;
    168     private static final int MENU_ITEM_VIEW_ADN     = 1;
    169     private static final int MENU_ITEM_VIEW_FDN     = 2;
    170     private static final int MENU_ITEM_VIEW_SDN     = 3;
    171     private static final int MENU_ITEM_GET_IMS_STATUS = 4;
    172     private static final int MENU_ITEM_TOGGLE_DATA  = 5;
    173 
    174     private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
    175     private TextView number;
    176     private TextView mSubscriberId;
    177     private TextView callState;
    178     private TextView operatorName;
    179     private TextView roamingState;
    180     private TextView gsmState;
    181     private TextView gprsState;
    182     private TextView voiceNetwork;
    183     private TextView dataNetwork;
    184     private TextView dBm;
    185     private TextView mMwi;
    186     private TextView mCfi;
    187     private TextView mLocation;
    188     private TextView mNeighboringCids;
    189     private TextView mCellInfo;
    190     private TextView mDcRtInfoTv;
    191     private TextView sent;
    192     private TextView received;
    193     private TextView mPingHostnameV4;
    194     private TextView mPingHostnameV6;
    195     private TextView mHttpClientTest;
    196     private TextView dnsCheckState;
    197     private EditText smsc;
    198     private Switch radioPowerOnSwitch;
    199     private Button cellInfoRefreshRateButton;
    200     private Button dnsCheckToggleButton;
    201     private Button pingTestButton;
    202     private Button updateSmscButton;
    203     private Button refreshSmscButton;
    204     private Button oemInfoButton;
    205     private Button carrierProvisioningButton;
    206     private Button triggercarrierProvisioningButton;
    207     private Switch imsVolteProvisionedSwitch;
    208     private Switch imsVtProvisionedSwitch;
    209     private Switch imsWfcProvisionedSwitch;
    210     private Switch eabProvisionedSwitch;
    211     private Spinner preferredNetworkType;
    212     private Spinner cellInfoRefreshRateSpinner;
    213 
    214     private TelephonyManager mTelephonyManager;
    215     private ImsManager mImsManager = null;
    216     private Phone phone = null;
    217 
    218     private String mPingHostnameResultV4;
    219     private String mPingHostnameResultV6;
    220     private String mHttpClientTestResult;
    221     private boolean mMwiValue = false;
    222     private boolean mCfiValue = false;
    223 
    224     private List<CellInfo> mCellInfoResult = null;
    225     private CellLocation mCellLocationResult = null;
    226     private List<NeighboringCellInfo> mNeighboringCellResult = null;
    227 
    228     private int mPreferredNetworkTypeResult;
    229     private int mCellInfoRefreshRateIndex;
    230 
    231     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
    232         @Override
    233         public void onDataConnectionStateChanged(int state) {
    234             updateDataState();
    235             updateNetworkType();
    236         }
    237 
    238         @Override
    239         public void onDataActivity(int direction) {
    240             updateDataStats2();
    241         }
    242 
    243         @Override
    244         public void onCallStateChanged(int state, String incomingNumber) {
    245             updateNetworkType();
    246             updatePhoneState(state);
    247         }
    248 
    249         @Override
    250         public void onPreciseCallStateChanged(PreciseCallState preciseState) {
    251             updateNetworkType();
    252         }
    253 
    254         @Override
    255         public void onCellLocationChanged(CellLocation location) {
    256             updateLocation(location);
    257         }
    258 
    259         @Override
    260         public void onMessageWaitingIndicatorChanged(boolean mwi) {
    261             mMwiValue = mwi;
    262             updateMessageWaiting();
    263         }
    264 
    265         @Override
    266         public void onCallForwardingIndicatorChanged(boolean cfi) {
    267             mCfiValue = cfi;
    268             updateCallRedirect();
    269         }
    270 
    271         @Override
    272         public void onCellInfoChanged(List<CellInfo> arrayCi) {
    273             log("onCellInfoChanged: arrayCi=" + arrayCi);
    274             mCellInfoResult = arrayCi;
    275             updateCellInfo(mCellInfoResult);
    276         }
    277 
    278         @Override
    279         public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) {
    280             log("onDataConnectionRealTimeInfoChanged: dcRtInfo=" + dcRtInfo);
    281             updateDcRtInfoTv(dcRtInfo);
    282         }
    283 
    284         @Override
    285         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
    286             log("onSignalStrengthChanged: SignalStrength=" +signalStrength);
    287             updateSignalStrength(signalStrength);
    288         }
    289 
    290         @Override
    291         public void onServiceStateChanged(ServiceState serviceState) {
    292             log("onServiceStateChanged: ServiceState=" + serviceState);
    293             updateServiceState(serviceState);
    294             updateRadioPowerState();
    295             updateNetworkType();
    296             updateImsProvisionedState();
    297         }
    298     };
    299 
    300     private void updatePreferredNetworkType(int type) {
    301         if (type >= mPreferredNetworkLabels.length || type < 0) {
    302             log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown " +
    303                     "type=" + type);
    304             type = mPreferredNetworkLabels.length - 1; //set to Unknown
    305         }
    306         mPreferredNetworkTypeResult = type;
    307 
    308         preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
    309     }
    310 
    311     private Handler mHandler = new Handler() {
    312         @Override
    313         public void handleMessage(Message msg) {
    314             AsyncResult ar;
    315             switch (msg.what) {
    316                 case EVENT_QUERY_PREFERRED_TYPE_DONE:
    317                     ar= (AsyncResult) msg.obj;
    318                     if (ar.exception == null && ar.result != null) {
    319                         updatePreferredNetworkType(((int[])ar.result)[0]);
    320                     } else {
    321                         //In case of an exception, we will set this to unknown
    322                         updatePreferredNetworkType(mPreferredNetworkLabels.length-1);
    323                     }
    324                     break;
    325                 case EVENT_SET_PREFERRED_TYPE_DONE:
    326                     ar= (AsyncResult) msg.obj;
    327                     if (ar.exception != null) {
    328                         log("Set preferred network type failed.");
    329                     }
    330                     break;
    331                 case EVENT_QUERY_SMSC_DONE:
    332                     ar= (AsyncResult) msg.obj;
    333                     if (ar.exception != null) {
    334                         smsc.setText("refresh error");
    335                     } else {
    336                         smsc.setText((String)ar.result);
    337                     }
    338                     break;
    339                 case EVENT_UPDATE_SMSC_DONE:
    340                     updateSmscButton.setEnabled(true);
    341                     ar= (AsyncResult) msg.obj;
    342                     if (ar.exception != null) {
    343                         smsc.setText("update error");
    344                     }
    345                     break;
    346                 default:
    347                     super.handleMessage(msg);
    348                     break;
    349 
    350             }
    351         }
    352     };
    353 
    354     @Override
    355     public void onCreate(Bundle icicle) {
    356         super.onCreate(icicle);
    357         if (!android.os.Process.myUserHandle().isSystem()) {
    358             Log.e(TAG, "Not run from system user, don't do anything.");
    359             finish();
    360             return;
    361         }
    362 
    363         setContentView(R.layout.radio_info);
    364 
    365         log("Started onCreate");
    366 
    367         mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
    368         phone = PhoneFactory.getDefaultPhone();
    369 
    370         //TODO: Need to update this if the default phoneId changes?
    371         //      Better to have an instance per phone?
    372         mImsManager = ImsManager.getInstance(getApplicationContext(),
    373                 SubscriptionManager.getDefaultVoicePhoneId());
    374 
    375         mDeviceId = (TextView) findViewById(R.id.imei);
    376         number = (TextView) findViewById(R.id.number);
    377         mSubscriberId = (TextView) findViewById(R.id.imsi);
    378         callState = (TextView) findViewById(R.id.call);
    379         operatorName = (TextView) findViewById(R.id.operator);
    380         roamingState = (TextView) findViewById(R.id.roaming);
    381         gsmState = (TextView) findViewById(R.id.gsm);
    382         gprsState = (TextView) findViewById(R.id.gprs);
    383         voiceNetwork = (TextView) findViewById(R.id.voice_network);
    384         dataNetwork = (TextView) findViewById(R.id.data_network);
    385         dBm = (TextView) findViewById(R.id.dbm);
    386         mMwi = (TextView) findViewById(R.id.mwi);
    387         mCfi = (TextView) findViewById(R.id.cfi);
    388         mLocation = (TextView) findViewById(R.id.location);
    389         mNeighboringCids = (TextView) findViewById(R.id.neighboring);
    390         mCellInfo = (TextView) findViewById(R.id.cellinfo);
    391         mCellInfo.setTypeface(Typeface.MONOSPACE);
    392         mDcRtInfoTv = (TextView) findViewById(R.id.dcrtinfo);
    393 
    394         sent = (TextView) findViewById(R.id.sent);
    395         received = (TextView) findViewById(R.id.received);
    396         smsc = (EditText) findViewById(R.id.smsc);
    397         dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
    398         mPingHostnameV4 = (TextView) findViewById(R.id.pingHostnameV4);
    399         mPingHostnameV6 = (TextView) findViewById(R.id.pingHostnameV6);
    400         mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
    401 
    402         preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
    403         ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
    404                 android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
    405         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    406         preferredNetworkType.setAdapter(adapter);
    407 
    408         cellInfoRefreshRateSpinner = (Spinner) findViewById(R.id.cell_info_rate_select);
    409         ArrayAdapter<String> cellInfoAdapter = new ArrayAdapter<String>(this,
    410                 android.R.layout.simple_spinner_item, mCellInfoRefreshRateLabels);
    411         cellInfoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    412         cellInfoRefreshRateSpinner.setAdapter(cellInfoAdapter);
    413 
    414         imsVolteProvisionedSwitch = (Switch) findViewById(R.id.volte_provisioned_switch);
    415         imsVtProvisionedSwitch = (Switch) findViewById(R.id.vt_provisioned_switch);
    416         imsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
    417         eabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch);
    418 
    419         radioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
    420 
    421         pingTestButton = (Button) findViewById(R.id.ping_test);
    422         pingTestButton.setOnClickListener(mPingButtonHandler);
    423         updateSmscButton = (Button) findViewById(R.id.update_smsc);
    424         updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
    425         refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
    426         refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
    427         dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
    428         dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
    429         carrierProvisioningButton = (Button) findViewById(R.id.carrier_provisioning);
    430         carrierProvisioningButton.setOnClickListener(mCarrierProvisioningButtonHandler);
    431         triggercarrierProvisioningButton = (Button) findViewById(R.id.trigger_carrier_provisioning);
    432         triggercarrierProvisioningButton.setOnClickListener(
    433                 mTriggerCarrierProvisioningButtonHandler);
    434 
    435         oemInfoButton = (Button) findViewById(R.id.oem_info);
    436         oemInfoButton.setOnClickListener(mOemInfoButtonHandler);
    437         PackageManager pm = getPackageManager();
    438         Intent oemInfoIntent = new Intent("com.android.settings.OEM_RADIO_INFO");
    439         List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
    440         if (oemInfoIntentList.size() == 0) {
    441             oemInfoButton.setEnabled(false);
    442         }
    443 
    444         mCellInfoRefreshRateIndex = 0; //disabled
    445         mPreferredNetworkTypeResult = mPreferredNetworkLabels.length - 1; //Unknown
    446 
    447         //FIXME: Replace with TelephonyManager call
    448         phone.getPreferredNetworkType(
    449                 mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
    450 
    451         restoreFromBundle(icicle);
    452     }
    453 
    454     @Override
    455     protected void onResume() {
    456         super.onResume();
    457 
    458         log("Started onResume");
    459 
    460         updateMessageWaiting();
    461         updateCallRedirect();
    462         updateDataState();
    463         updateDataStats2();
    464         updateRadioPowerState();
    465         updateImsProvisionedState();
    466         updateProperties();
    467         updateDnsCheckState();
    468         updateNetworkType();
    469 
    470         updateNeighboringCids(mNeighboringCellResult);
    471         updateLocation(mCellLocationResult);
    472         updateCellInfo(mCellInfoResult);
    473 
    474         mPingHostnameV4.setText(mPingHostnameResultV4);
    475         mPingHostnameV6.setText(mPingHostnameResultV6);
    476         mHttpClientTest.setText(mHttpClientTestResult);
    477 
    478         cellInfoRefreshRateSpinner.setOnItemSelectedListener(mCellInfoRefreshRateHandler);
    479         //set selection after registering listener to force update
    480         cellInfoRefreshRateSpinner.setSelection(mCellInfoRefreshRateIndex);
    481 
    482         //set selection before registering to prevent update
    483         preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
    484         preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
    485 
    486         radioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
    487         imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
    488         imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
    489         imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
    490         eabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
    491 
    492         mTelephonyManager.listen(mPhoneStateListener,
    493                   PhoneStateListener.LISTEN_CALL_STATE
    494         //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
    495         //      | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
    496                 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
    497                 | PhoneStateListener.LISTEN_DATA_ACTIVITY
    498                 | PhoneStateListener.LISTEN_CELL_LOCATION
    499                 | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
    500                 | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
    501                 | PhoneStateListener.LISTEN_CELL_INFO
    502                 | PhoneStateListener.LISTEN_SERVICE_STATE
    503                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
    504                 | PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
    505 
    506         smsc.clearFocus();
    507     }
    508 
    509     @Override
    510     protected void onPause() {
    511         super.onPause();
    512 
    513         log("onPause: unregister phone & data intents");
    514 
    515         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
    516         mTelephonyManager.setCellInfoListRate(CELL_INFO_LIST_RATE_DISABLED);
    517     }
    518 
    519     private void restoreFromBundle(Bundle b) {
    520         if(b == null) {
    521             return;
    522         }
    523 
    524         mPingHostnameResultV4 = b.getString("mPingHostnameResultV4","");
    525         mPingHostnameResultV6 = b.getString("mPingHostnameResultV6","");
    526         mHttpClientTestResult = b.getString("mHttpClientTestResult","");
    527 
    528         mPingHostnameV4.setText(mPingHostnameResultV4);
    529         mPingHostnameV6.setText(mPingHostnameResultV6);
    530         mHttpClientTest.setText(mHttpClientTestResult);
    531 
    532         mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult",
    533                                                mPreferredNetworkLabels.length - 1);
    534 
    535         mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0);
    536     }
    537 
    538     @Override
    539     protected void onSaveInstanceState(Bundle outState) {
    540         outState.putString("mPingHostnameResultV4", mPingHostnameResultV4);
    541         outState.putString("mPingHostnameResultV6", mPingHostnameResultV6);
    542         outState.putString("mHttpClientTestResult", mHttpClientTestResult);
    543 
    544         outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult);
    545         outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex);
    546 
    547     }
    548 
    549     @Override
    550     public boolean onCreateOptionsMenu(Menu menu) {
    551         menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
    552                 .setOnMenuItemClickListener(mSelectBandCallback)
    553                 .setAlphabeticShortcut('b');
    554         menu.add(1, MENU_ITEM_VIEW_ADN, 0,
    555                 R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
    556         menu.add(1, MENU_ITEM_VIEW_FDN, 0,
    557                 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
    558         menu.add(1, MENU_ITEM_VIEW_SDN, 0,
    559                 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
    560         menu.add(1, MENU_ITEM_GET_IMS_STATUS,
    561                 0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus);
    562         menu.add(1, MENU_ITEM_TOGGLE_DATA,
    563                 0, R.string.radio_info_data_connection_disable).setOnMenuItemClickListener(mToggleData);
    564         return true;
    565     }
    566 
    567     @Override
    568     public boolean onPrepareOptionsMenu(Menu menu) {
    569         // Get the TOGGLE DATA menu item in the right state.
    570         MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
    571         int state = mTelephonyManager.getDataState();
    572         boolean visible = true;
    573 
    574         switch (state) {
    575             case TelephonyManager.DATA_CONNECTED:
    576             case TelephonyManager.DATA_SUSPENDED:
    577                 item.setTitle(R.string.radio_info_data_connection_disable);
    578                 break;
    579             case TelephonyManager.DATA_DISCONNECTED:
    580                 item.setTitle(R.string.radio_info_data_connection_enable);
    581                 break;
    582             default:
    583                 visible = false;
    584                 break;
    585         }
    586         item.setVisible(visible);
    587         return true;
    588     }
    589 
    590     private void updateDnsCheckState() {
    591         //FIXME: Replace with a TelephonyManager call
    592         dnsCheckState.setText(phone.isDnsCheckDisabled() ?
    593                 "0.0.0.0 allowed" :"0.0.0.0 not allowed");
    594     }
    595 
    596     private final void
    597     updateSignalStrength(SignalStrength signalStrength) {
    598         Resources r = getResources();
    599 
    600         int signalDbm = signalStrength.getDbm();
    601 
    602         int signalAsu = signalStrength.getAsuLevel();
    603 
    604         if (-1 == signalAsu) signalAsu = 0;
    605 
    606         dBm.setText(String.valueOf(signalDbm) + " "
    607             + r.getString(R.string.radioInfo_display_dbm) + "   "
    608             + String.valueOf(signalAsu) + " "
    609             + r.getString(R.string.radioInfo_display_asu));
    610     }
    611 
    612     private final void updateLocation(CellLocation location) {
    613         Resources r = getResources();
    614         if (location instanceof GsmCellLocation) {
    615             GsmCellLocation loc = (GsmCellLocation)location;
    616             int lac = loc.getLac();
    617             int cid = loc.getCid();
    618             mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
    619                     + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
    620                     + "   "
    621                     + r.getString(R.string.radioInfo_cid) + " = "
    622                     + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
    623         } else if (location instanceof CdmaCellLocation) {
    624             CdmaCellLocation loc = (CdmaCellLocation)location;
    625             int bid = loc.getBaseStationId();
    626             int sid = loc.getSystemId();
    627             int nid = loc.getNetworkId();
    628             int lat = loc.getBaseStationLatitude();
    629             int lon = loc.getBaseStationLongitude();
    630             mLocation.setText("BID = "
    631                     + ((bid == -1) ? "unknown" : Integer.toHexString(bid))
    632                     + "   "
    633                     + "SID = "
    634                     + ((sid == -1) ? "unknown" : Integer.toHexString(sid))
    635                     + "   "
    636                     + "NID = "
    637                     + ((nid == -1) ? "unknown" : Integer.toHexString(nid))
    638                     + "\n"
    639                     + "LAT = "
    640                     + ((lat == -1) ? "unknown" : Integer.toHexString(lat))
    641                     + "   "
    642                     + "LONG = "
    643                     + ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
    644         } else {
    645             mLocation.setText("unknown");
    646         }
    647 
    648 
    649     }
    650 
    651     private final void updateNeighboringCids(List<NeighboringCellInfo> cids) {
    652         StringBuilder sb = new StringBuilder();
    653 
    654         if (cids != null) {
    655             if (cids.isEmpty()) {
    656                 sb.append("no neighboring cells");
    657             } else {
    658                 for (NeighboringCellInfo cell : cids) {
    659                     sb.append(cell.toString()).append(" ");
    660                 }
    661             }
    662         } else {
    663             sb.append("unknown");
    664         }
    665         mNeighboringCids.setText(sb.toString());
    666     }
    667 
    668     private final String getCellInfoDisplayString(int i) {
    669         return (i != Integer.MAX_VALUE) ? Integer.toString(i) : "";
    670     }
    671 
    672     private final String getCellInfoDisplayString(long i) {
    673         return (i != Long.MAX_VALUE) ? Long.toString(i) : "";
    674     }
    675 
    676     private final String buildCdmaInfoString(CellInfoCdma ci) {
    677         CellIdentityCdma cidCdma = ci.getCellIdentity();
    678         CellSignalStrengthCdma ssCdma = ci.getCellSignalStrength();
    679 
    680         return String.format("%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s",
    681                 ci.isRegistered() ? "S  " : "   ",
    682                 getCellInfoDisplayString(cidCdma.getSystemId()),
    683                 getCellInfoDisplayString(cidCdma.getNetworkId()),
    684                 getCellInfoDisplayString(cidCdma.getBasestationId()),
    685                 getCellInfoDisplayString(ssCdma.getCdmaDbm()),
    686                 getCellInfoDisplayString(ssCdma.getCdmaEcio()),
    687                 getCellInfoDisplayString(ssCdma.getEvdoDbm()),
    688                 getCellInfoDisplayString(ssCdma.getEvdoEcio()),
    689                 getCellInfoDisplayString(ssCdma.getEvdoSnr()));
    690     }
    691 
    692     private final String buildGsmInfoString(CellInfoGsm ci) {
    693         CellIdentityGsm cidGsm = ci.getCellIdentity();
    694         CellSignalStrengthGsm ssGsm = ci.getCellSignalStrength();
    695 
    696         return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
    697                 ci.isRegistered() ? "S  " : "   ",
    698                 getCellInfoDisplayString(cidGsm.getMcc()),
    699                 getCellInfoDisplayString(cidGsm.getMnc()),
    700                 getCellInfoDisplayString(cidGsm.getLac()),
    701                 getCellInfoDisplayString(cidGsm.getCid()),
    702                 getCellInfoDisplayString(cidGsm.getArfcn()),
    703                 getCellInfoDisplayString(cidGsm.getBsic()),
    704                 getCellInfoDisplayString(ssGsm.getDbm()));
    705     }
    706 
    707     private final String buildLteInfoString(CellInfoLte ci) {
    708         CellIdentityLte cidLte = ci.getCellIdentity();
    709         CellSignalStrengthLte ssLte = ci.getCellSignalStrength();
    710 
    711         return String.format(
    712                 "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
    713                 ci.isRegistered() ? "S  " : "   ",
    714                 getCellInfoDisplayString(cidLte.getMcc()),
    715                 getCellInfoDisplayString(cidLte.getMnc()),
    716                 getCellInfoDisplayString(cidLte.getTac()),
    717                 getCellInfoDisplayString(cidLte.getCi()),
    718                 getCellInfoDisplayString(cidLte.getPci()),
    719                 getCellInfoDisplayString(cidLte.getEarfcn()),
    720                 getCellInfoDisplayString(ssLte.getDbm()),
    721                 getCellInfoDisplayString(ssLte.getRsrq()),
    722                 getCellInfoDisplayString(ssLte.getTimingAdvance()));
    723     }
    724 
    725     private final String buildWcdmaInfoString(CellInfoWcdma ci) {
    726         CellIdentityWcdma cidWcdma = ci.getCellIdentity();
    727         CellSignalStrengthWcdma ssWcdma = ci.getCellSignalStrength();
    728 
    729         return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
    730                 ci.isRegistered() ? "S  " : "   ",
    731                 getCellInfoDisplayString(cidWcdma.getMcc()),
    732                 getCellInfoDisplayString(cidWcdma.getMnc()),
    733                 getCellInfoDisplayString(cidWcdma.getLac()),
    734                 getCellInfoDisplayString(cidWcdma.getCid()),
    735                 getCellInfoDisplayString(cidWcdma.getUarfcn()),
    736                 getCellInfoDisplayString(cidWcdma.getPsc()),
    737                 getCellInfoDisplayString(ssWcdma.getDbm()));
    738     }
    739 
    740     private final String buildCellInfoString(List<CellInfo> arrayCi) {
    741         String value = new String();
    742         StringBuilder cdmaCells = new StringBuilder(),
    743                 gsmCells = new StringBuilder(),
    744                 lteCells = new StringBuilder(),
    745                 wcdmaCells = new StringBuilder();
    746 
    747         if (arrayCi != null) {
    748             for (CellInfo ci : arrayCi) {
    749 
    750                 if (ci instanceof CellInfoLte) {
    751                     lteCells.append(buildLteInfoString((CellInfoLte) ci));
    752                 } else if (ci instanceof CellInfoWcdma) {
    753                     wcdmaCells.append(buildWcdmaInfoString((CellInfoWcdma) ci));
    754                 } else if (ci instanceof CellInfoGsm) {
    755                     gsmCells.append(buildGsmInfoString((CellInfoGsm) ci));
    756                 } else if (ci instanceof CellInfoCdma) {
    757                     cdmaCells.append(buildCdmaInfoString((CellInfoCdma) ci));
    758                 }
    759             }
    760             if (lteCells.length() != 0) {
    761                 value += String.format(
    762                         "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
    763                         "SRV", "MCC", "MNC", "TAC", "CID", "PCI", "EARFCN", "RSRP", "RSRQ", "TA");
    764                 value += lteCells.toString();
    765             }
    766             if (wcdmaCells.length() != 0) {
    767                 value += String.format("WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
    768                         "SRV", "MCC", "MNC", "LAC", "CID", "UARFCN", "PSC", "RSCP");
    769                 value += wcdmaCells.toString();
    770             }
    771             if (gsmCells.length() != 0) {
    772                 value += String.format("GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
    773                         "SRV", "MCC", "MNC", "LAC", "CID", "ARFCN", "BSIC", "RSSI");
    774                 value += gsmCells.toString();
    775             }
    776             if (cdmaCells.length() != 0) {
    777                 value += String.format(
    778                         "CDMA/EVDO\n%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s\n",
    779                         "SRV", "SID", "NID", "BSID", "C-RSSI", "C-ECIO", "E-RSSI", "E-ECIO", "E-SNR");
    780                 value += cdmaCells.toString();
    781             }
    782         } else {
    783             value ="unknown";
    784         }
    785 
    786         return value.toString();
    787     }
    788 
    789     private final void updateCellInfo(List<CellInfo> arrayCi) {
    790         mCellInfo.setText(buildCellInfoString(arrayCi));
    791     }
    792 
    793     private final void updateDcRtInfoTv(DataConnectionRealTimeInfo dcRtInfo) {
    794         mDcRtInfoTv.setText(dcRtInfo.toString());
    795     }
    796 
    797     private final void
    798     updateMessageWaiting() {
    799         mMwi.setText(String.valueOf(mMwiValue));
    800     }
    801 
    802     private final void
    803     updateCallRedirect() {
    804         mCfi.setText(String.valueOf(mCfiValue));
    805     }
    806 
    807 
    808     private final void
    809     updateServiceState(ServiceState serviceState) {
    810         int state = serviceState.getState();
    811         Resources r = getResources();
    812         String display = r.getString(R.string.radioInfo_unknown);
    813 
    814         switch (state) {
    815             case ServiceState.STATE_IN_SERVICE:
    816                 display = r.getString(R.string.radioInfo_service_in);
    817                 break;
    818             case ServiceState.STATE_OUT_OF_SERVICE:
    819             case ServiceState.STATE_EMERGENCY_ONLY:
    820                 display = r.getString(R.string.radioInfo_service_emergency);
    821                 break;
    822             case ServiceState.STATE_POWER_OFF:
    823                 display = r.getString(R.string.radioInfo_service_off);
    824                 break;
    825         }
    826 
    827         gsmState.setText(display);
    828 
    829         if (serviceState.getRoaming()) {
    830             roamingState.setText(R.string.radioInfo_roaming_in);
    831         } else {
    832             roamingState.setText(R.string.radioInfo_roaming_not);
    833         }
    834 
    835         operatorName.setText(serviceState.getOperatorAlphaLong());
    836     }
    837 
    838     private final void
    839     updatePhoneState(int state) {
    840         Resources r = getResources();
    841         String display = r.getString(R.string.radioInfo_unknown);
    842 
    843         switch (state) {
    844             case TelephonyManager.CALL_STATE_IDLE:
    845                 display = r.getString(R.string.radioInfo_phone_idle);
    846                 break;
    847             case TelephonyManager.CALL_STATE_RINGING:
    848                 display = r.getString(R.string.radioInfo_phone_ringing);
    849                 break;
    850             case TelephonyManager.CALL_STATE_OFFHOOK:
    851                 display = r.getString(R.string.radioInfo_phone_offhook);
    852                 break;
    853         }
    854 
    855         callState.setText(display);
    856     }
    857 
    858     private final void
    859     updateDataState() {
    860         int state = mTelephonyManager.getDataState();
    861         Resources r = getResources();
    862         String display = r.getString(R.string.radioInfo_unknown);
    863 
    864         switch (state) {
    865             case TelephonyManager.DATA_CONNECTED:
    866                 display = r.getString(R.string.radioInfo_data_connected);
    867                 break;
    868             case TelephonyManager.DATA_CONNECTING:
    869                 display = r.getString(R.string.radioInfo_data_connecting);
    870                 break;
    871             case TelephonyManager.DATA_DISCONNECTED:
    872                 display = r.getString(R.string.radioInfo_data_disconnected);
    873                 break;
    874             case TelephonyManager.DATA_SUSPENDED:
    875                 display = r.getString(R.string.radioInfo_data_suspended);
    876                 break;
    877         }
    878 
    879         gprsState.setText(display);
    880     }
    881 
    882     private final void updateNetworkType() {
    883         if(phone != null) {
    884             ServiceState ss = phone.getServiceState();
    885             dataNetwork.setText(ServiceState.rilRadioTechnologyToString(
    886                     phone.getServiceState().getRilDataRadioTechnology()));
    887             voiceNetwork.setText(ServiceState.rilRadioTechnologyToString(
    888                     phone.getServiceState().getRilVoiceRadioTechnology()));
    889         }
    890     }
    891 
    892     private final void
    893     updateProperties() {
    894         String s;
    895         Resources r = getResources();
    896 
    897         s = phone.getDeviceId();
    898         if (s == null) s = r.getString(R.string.radioInfo_unknown);
    899         mDeviceId.setText(s);
    900 
    901         s = phone.getSubscriberId();
    902         if (s == null) s = r.getString(R.string.radioInfo_unknown);
    903         mSubscriberId.setText(s);
    904 
    905         //FIXME: Replace with a TelephonyManager call
    906         s = phone.getLine1Number();
    907         if (s == null) s = r.getString(R.string.radioInfo_unknown);
    908         number.setText(s);
    909     }
    910 
    911     private final void updateDataStats2() {
    912         Resources r = getResources();
    913 
    914         long txPackets = TrafficStats.getMobileTxPackets();
    915         long rxPackets = TrafficStats.getMobileRxPackets();
    916         long txBytes   = TrafficStats.getMobileTxBytes();
    917         long rxBytes   = TrafficStats.getMobileRxBytes();
    918 
    919         String packets = r.getString(R.string.radioInfo_display_packets);
    920         String bytes   = r.getString(R.string.radioInfo_display_bytes);
    921 
    922         sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
    923         received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
    924     }
    925 
    926     /**
    927      *  Ping a host name
    928      */
    929     private final void pingHostname() {
    930         try {
    931             try {
    932                 Process p4 = Runtime.getRuntime().exec("ping -c 1 www.google.com");
    933                 int status4 = p4.waitFor();
    934                 if (status4 == 0) {
    935                     mPingHostnameResultV4 = "Pass";
    936                 } else {
    937                     mPingHostnameResultV4 = String.format("Fail(%d)", status4);
    938                 }
    939             } catch (IOException e) {
    940                 mPingHostnameResultV4 = "Fail: IOException";
    941             }
    942             try {
    943                 Process p6 = Runtime.getRuntime().exec("ping6 -c 1 www.google.com");
    944                 int status6 = p6.waitFor();
    945                 if (status6 == 0) {
    946                     mPingHostnameResultV6 = "Pass";
    947                 } else {
    948                     mPingHostnameResultV6 = String.format("Fail(%d)", status6);
    949                 }
    950             } catch (IOException e) {
    951                 mPingHostnameResultV6 = "Fail: IOException";
    952             }
    953         } catch (InterruptedException e) {
    954             mPingHostnameResultV4 = mPingHostnameResultV6 = "Fail: InterruptedException";
    955         }
    956     }
    957 
    958     /**
    959      * This function checks for basic functionality of HTTP Client.
    960      */
    961     private void httpClientTest() {
    962         HttpURLConnection urlConnection = null;
    963         try {
    964             // TODO: Hardcoded for now, make it UI configurable
    965             URL url = new URL("https://www.google.com");
    966             urlConnection = (HttpURLConnection) url.openConnection();
    967             if (urlConnection.getResponseCode() == 200) {
    968                 mHttpClientTestResult = "Pass";
    969             } else {
    970                 mHttpClientTestResult = "Fail: Code: " + urlConnection.getResponseMessage();
    971             }
    972         } catch (IOException e) {
    973             mHttpClientTestResult = "Fail: IOException";
    974         } finally {
    975             if (urlConnection != null) {
    976                 urlConnection.disconnect();
    977             }
    978         }
    979     }
    980 
    981     private void refreshSmsc() {
    982         //FIXME: Replace with a TelephonyManager call
    983         phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
    984     }
    985 
    986     private final void updateAllCellInfo() {
    987 
    988         mCellInfo.setText("");
    989         mNeighboringCids.setText("");
    990         mLocation.setText("");
    991 
    992         final Runnable updateAllCellInfoResults = new Runnable() {
    993             public void run() {
    994                 updateNeighboringCids(mNeighboringCellResult);
    995                 updateLocation(mCellLocationResult);
    996                 updateCellInfo(mCellInfoResult);
    997             }
    998         };
    999 
   1000         Thread locThread = new Thread() {
   1001             @Override
   1002             public void run() {
   1003                 mCellInfoResult = mTelephonyManager.getAllCellInfo();
   1004                 mCellLocationResult = mTelephonyManager.getCellLocation();
   1005                 mNeighboringCellResult = mTelephonyManager.getNeighboringCellInfo();
   1006 
   1007                 mHandler.post(updateAllCellInfoResults);
   1008             }
   1009         };
   1010         locThread.start();
   1011     }
   1012 
   1013     private final void updatePingState() {
   1014         // Set all to unknown since the threads will take a few secs to update.
   1015         mPingHostnameResultV4 = getResources().getString(R.string.radioInfo_unknown);
   1016         mPingHostnameResultV6 = getResources().getString(R.string.radioInfo_unknown);
   1017         mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
   1018 
   1019         mPingHostnameV4.setText(mPingHostnameResultV4);
   1020         mPingHostnameV6.setText(mPingHostnameResultV6);
   1021         mHttpClientTest.setText(mHttpClientTestResult);
   1022 
   1023         final Runnable updatePingResults = new Runnable() {
   1024             public void run() {
   1025                 mPingHostnameV4.setText(mPingHostnameResultV4);
   1026                 mPingHostnameV6.setText(mPingHostnameResultV6);
   1027                 mHttpClientTest.setText(mHttpClientTestResult);
   1028             }
   1029         };
   1030 
   1031         Thread hostname = new Thread() {
   1032             @Override
   1033             public void run() {
   1034                 pingHostname();
   1035                 mHandler.post(updatePingResults);
   1036             }
   1037         };
   1038         hostname.start();
   1039 
   1040         Thread httpClient = new Thread() {
   1041             @Override
   1042             public void run() {
   1043                 httpClientTest();
   1044                 mHandler.post(updatePingResults);
   1045             }
   1046         };
   1047         httpClient.start();
   1048     }
   1049 
   1050     private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
   1051         public boolean onMenuItemClick(MenuItem item) {
   1052             Intent intent = new Intent(Intent.ACTION_VIEW);
   1053             // XXX We need to specify the component here because if we don't
   1054             // the activity manager will try to resolve the type by calling
   1055             // the content provider, which causes it to be loaded in a process
   1056             // other than the Dialer process, which causes a lot of stuff to
   1057             // break.
   1058             intent.setClassName("com.android.phone",
   1059                     "com.android.phone.SimContacts");
   1060             startActivity(intent);
   1061             return true;
   1062         }
   1063     };
   1064 
   1065     private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
   1066         public boolean onMenuItemClick(MenuItem item) {
   1067             Intent intent = new Intent(Intent.ACTION_VIEW);
   1068             // XXX We need to specify the component here because if we don't
   1069             // the activity manager will try to resolve the type by calling
   1070             // the content provider, which causes it to be loaded in a process
   1071             // other than the Dialer process, which causes a lot of stuff to
   1072             // break.
   1073             intent.setClassName("com.android.phone",
   1074                     "com.android.phone.settings.fdn.FdnList");
   1075             startActivity(intent);
   1076             return true;
   1077         }
   1078     };
   1079 
   1080     private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
   1081         public boolean onMenuItemClick(MenuItem item) {
   1082             Intent intent = new Intent(
   1083                     Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
   1084             // XXX We need to specify the component here because if we don't
   1085             // the activity manager will try to resolve the type by calling
   1086             // the content provider, which causes it to be loaded in a process
   1087             // other than the Dialer process, which causes a lot of stuff to
   1088             // break.
   1089             intent.setClassName("com.android.phone",
   1090                     "com.android.phone.ADNList");
   1091             startActivity(intent);
   1092             return true;
   1093         }
   1094     };
   1095 
   1096     private MenuItem.OnMenuItemClickListener mGetImsStatus = new MenuItem.OnMenuItemClickListener() {
   1097         public boolean onMenuItemClick(MenuItem item) {
   1098             boolean isImsRegistered = phone.isImsRegistered();
   1099             boolean availableVolte = phone.isVolteEnabled();
   1100             boolean availableWfc = phone.isWifiCallingEnabled();
   1101             boolean availableVt = phone.isVideoEnabled();
   1102             boolean availableUt = phone.isUtEnabled();
   1103 
   1104             final String imsRegString = isImsRegistered ?
   1105                 getString(R.string.radio_info_ims_reg_status_registered) :
   1106                 getString(R.string.radio_info_ims_reg_status_not_registered);
   1107 
   1108             final String available = getString(R.string.radio_info_ims_feature_status_available);
   1109             final String unavailable = getString(
   1110                     R.string.radio_info_ims_feature_status_unavailable);
   1111 
   1112             String imsStatus = getString(R.string.radio_info_ims_reg_status,
   1113                     imsRegString,
   1114                     availableVolte ? available : unavailable,
   1115                     availableWfc ? available : unavailable,
   1116                     availableVt ? available : unavailable,
   1117                     availableUt ? available : unavailable);
   1118 
   1119             AlertDialog imsDialog = new AlertDialog.Builder(RadioInfo.this)
   1120                 .setMessage(imsStatus)
   1121                 .setTitle(getString(R.string.radio_info_ims_reg_status_title))
   1122                 .create();
   1123 
   1124             imsDialog.show();
   1125 
   1126             return true;
   1127         }
   1128     };
   1129 
   1130     private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
   1131         public boolean onMenuItemClick(MenuItem item) {
   1132             Intent intent = new Intent();
   1133             intent.setClass(RadioInfo.this, BandMode.class);
   1134             startActivity(intent);
   1135             return true;
   1136         }
   1137     };
   1138 
   1139     private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
   1140         public boolean onMenuItemClick(MenuItem item) {
   1141             int state = mTelephonyManager.getDataState();
   1142             switch (state) {
   1143                 case TelephonyManager.DATA_CONNECTED:
   1144                     //FIXME: Replace with a TelephonyManager call
   1145                     phone.setDataEnabled(false);
   1146                     break;
   1147                 case TelephonyManager.DATA_DISCONNECTED:
   1148                     //FIXME: Replace with a TelephonyManager call
   1149                     phone.setDataEnabled(true);
   1150                     break;
   1151                 default:
   1152                     // do nothing
   1153                     break;
   1154             }
   1155             return true;
   1156         }
   1157     };
   1158 
   1159     private boolean isRadioOn() {
   1160         //FIXME: Replace with a TelephonyManager call
   1161         return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
   1162     }
   1163 
   1164     private void updateRadioPowerState() {
   1165         //delightful hack to prevent on-checked-changed calls from
   1166         //actually forcing the radio preference to its transient/current value.
   1167         radioPowerOnSwitch.setOnCheckedChangeListener(null);
   1168         radioPowerOnSwitch.setChecked(isRadioOn());
   1169         radioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
   1170     }
   1171 
   1172     void setImsVolteProvisionedState(boolean state) {
   1173         Log.d(TAG, "setImsVolteProvisioned state: " + ((state)? "on":"off"));
   1174         setImsConfigProvisionedState(IMS_VOLTE_PROVISIONED_CONFIG_ID, state);
   1175     }
   1176 
   1177     void setImsVtProvisionedState(boolean state) {
   1178         Log.d(TAG, "setImsVtProvisioned() state: " + ((state)? "on":"off"));
   1179         setImsConfigProvisionedState(IMS_VT_PROVISIONED_CONFIG_ID, state);
   1180     }
   1181 
   1182     void setImsWfcProvisionedState(boolean state) {
   1183         Log.d(TAG, "setImsWfcProvisioned() state: " + ((state)? "on":"off"));
   1184         setImsConfigProvisionedState(IMS_WFC_PROVISIONED_CONFIG_ID, state);
   1185     }
   1186 
   1187     void setEabProvisionedState(boolean state) {
   1188         Log.d(TAG, "setEabProvisioned() state: " + ((state)? "on":"off"));
   1189         setImsConfigProvisionedState(EAB_PROVISIONED_CONFIG_ID, state);
   1190     }
   1191 
   1192     void setImsConfigProvisionedState(int configItem, boolean state) {
   1193         if (phone != null && mImsManager != null) {
   1194             QueuedWork.queue(new Runnable() {
   1195                 public void run() {
   1196                     try {
   1197                         mImsManager.getConfigInterface().setProvisionedValue(
   1198                                 configItem,
   1199                                 state? 1 : 0);
   1200                     } catch (ImsException e) {
   1201                         Log.e(TAG, "setImsConfigProvisioned() exception:", e);
   1202                     }
   1203                 }
   1204             }, false);
   1205         }
   1206     }
   1207 
   1208     OnCheckedChangeListener mRadioPowerOnChangeListener = new OnCheckedChangeListener() {
   1209         @Override
   1210         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   1211             log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
   1212             phone.setRadioPower(isChecked);
   1213        }
   1214     };
   1215 
   1216     private boolean isImsVolteProvisioned() {
   1217         if (phone != null && mImsManager != null) {
   1218             return mImsManager.isVolteEnabledByPlatform(phone.getContext())
   1219                 && mImsManager.isVolteProvisionedOnDevice(phone.getContext());
   1220         }
   1221         return false;
   1222     }
   1223 
   1224     OnCheckedChangeListener mImsVolteCheckedChangeListener = new OnCheckedChangeListener() {
   1225         @Override
   1226         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   1227             setImsVolteProvisionedState(isChecked);
   1228         }
   1229     };
   1230 
   1231     private boolean isImsVtProvisioned() {
   1232         if (phone != null && mImsManager != null) {
   1233             return mImsManager.isVtEnabledByPlatform(phone.getContext())
   1234                 && mImsManager.isVtProvisionedOnDevice(phone.getContext());
   1235         }
   1236         return false;
   1237     }
   1238 
   1239     OnCheckedChangeListener mImsVtCheckedChangeListener = new OnCheckedChangeListener() {
   1240         @Override
   1241         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   1242             setImsVtProvisionedState(isChecked);
   1243         }
   1244     };
   1245 
   1246     private boolean isImsWfcProvisioned() {
   1247         if (phone != null && mImsManager != null) {
   1248             return mImsManager.isWfcEnabledByPlatform(phone.getContext())
   1249                 && mImsManager.isWfcProvisionedOnDevice(phone.getContext());
   1250         }
   1251         return false;
   1252     }
   1253 
   1254     OnCheckedChangeListener mImsWfcCheckedChangeListener = new OnCheckedChangeListener() {
   1255         @Override
   1256         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   1257             setImsWfcProvisionedState(isChecked);
   1258         }
   1259     };
   1260 
   1261     private boolean isEabProvisioned() {
   1262         return isFeatureProvisioned(EAB_PROVISIONED_CONFIG_ID, false);
   1263     }
   1264 
   1265     OnCheckedChangeListener mEabCheckedChangeListener = new OnCheckedChangeListener() {
   1266         @Override
   1267         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   1268             setEabProvisionedState(isChecked);
   1269         }
   1270     };
   1271 
   1272     private boolean isFeatureProvisioned(int featureId, boolean defaultValue) {
   1273         boolean provisioned = defaultValue;
   1274         if (mImsManager != null) {
   1275             try {
   1276                 ImsConfig imsConfig = mImsManager.getConfigInterface();
   1277                 if (imsConfig != null) {
   1278                     provisioned =
   1279                             (imsConfig.getProvisionedValue(featureId)
   1280                                     == ImsConfig.FeatureValueConstants.ON);
   1281                 }
   1282             } catch (ImsException ex) {
   1283                 Log.e(TAG, "isFeatureProvisioned() exception:", ex);
   1284             }
   1285         }
   1286 
   1287         log("isFeatureProvisioned() featureId=" + featureId + " provisioned=" + provisioned);
   1288         return provisioned;
   1289     }
   1290 
   1291     private static boolean isEabEnabledByPlatform(Context context) {
   1292         if (context != null) {
   1293             CarrierConfigManager configManager = (CarrierConfigManager)
   1294                     context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
   1295             if (configManager != null && configManager.getConfig().getBoolean(
   1296                         CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL)) {
   1297                 return true;
   1298             }
   1299         }
   1300         return false;
   1301     }
   1302 
   1303     private void updateImsProvisionedState() {
   1304         log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned());
   1305         //delightful hack to prevent on-checked-changed calls from
   1306         //actually forcing the ims provisioning to its transient/current value.
   1307         imsVolteProvisionedSwitch.setOnCheckedChangeListener(null);
   1308         imsVolteProvisionedSwitch.setChecked(isImsVolteProvisioned());
   1309         imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
   1310         imsVolteProvisionedSwitch.setEnabled(
   1311                 mImsManager.isVolteEnabledByPlatform(phone.getContext()));
   1312 
   1313         imsVtProvisionedSwitch.setOnCheckedChangeListener(null);
   1314         imsVtProvisionedSwitch.setChecked(isImsVtProvisioned());
   1315         imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
   1316         imsVtProvisionedSwitch.setEnabled(
   1317             mImsManager.isVtEnabledByPlatform(phone.getContext()));
   1318 
   1319         imsWfcProvisionedSwitch.setOnCheckedChangeListener(null);
   1320         imsWfcProvisionedSwitch.setChecked(isImsWfcProvisioned());
   1321         imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
   1322         imsWfcProvisionedSwitch.setEnabled(
   1323             mImsManager.isWfcEnabledByPlatform(phone.getContext()));
   1324 
   1325         eabProvisionedSwitch.setOnCheckedChangeListener(null);
   1326         eabProvisionedSwitch.setChecked(isEabProvisioned());
   1327         eabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
   1328         eabProvisionedSwitch.setEnabled(isEabEnabledByPlatform(phone.getContext()));
   1329     }
   1330 
   1331     OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
   1332         public void onClick(View v) {
   1333             //FIXME: Replace with a TelephonyManager call
   1334             phone.disableDnsCheck(!phone.isDnsCheckDisabled());
   1335             updateDnsCheckState();
   1336         }
   1337     };
   1338 
   1339     OnClickListener mOemInfoButtonHandler = new OnClickListener() {
   1340         public void onClick(View v) {
   1341             Intent intent = new Intent("com.android.settings.OEM_RADIO_INFO");
   1342             try {
   1343                 startActivity(intent);
   1344             } catch (android.content.ActivityNotFoundException ex) {
   1345                 log("OEM-specific Info/Settings Activity Not Found : " + ex);
   1346                 // If the activity does not exist, there are no OEM
   1347                 // settings, and so we can just do nothing...
   1348             }
   1349         }
   1350     };
   1351 
   1352     OnClickListener mPingButtonHandler = new OnClickListener() {
   1353         public void onClick(View v) {
   1354             updatePingState();
   1355         }
   1356     };
   1357 
   1358     OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
   1359         public void onClick(View v) {
   1360             updateSmscButton.setEnabled(false);
   1361             phone.setSmscAddress(smsc.getText().toString(),
   1362                     mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
   1363         }
   1364     };
   1365 
   1366     OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
   1367         public void onClick(View v) {
   1368             refreshSmsc();
   1369         }
   1370     };
   1371 
   1372     OnClickListener mCarrierProvisioningButtonHandler = new OnClickListener() {
   1373         public void onClick(View v) {
   1374             final Intent intent = new Intent("com.android.settings.CARRIER_PROVISIONING");
   1375             final ComponentName serviceComponent = ComponentName.unflattenFromString(
   1376                     "com.android.omadm.service/.DMIntentReceiver");
   1377             intent.setComponent(serviceComponent);
   1378             sendBroadcast(intent);
   1379         }
   1380     };
   1381 
   1382     OnClickListener mTriggerCarrierProvisioningButtonHandler = new OnClickListener() {
   1383         public void onClick(View v) {
   1384             final Intent intent = new Intent("com.android.settings.TRIGGER_CARRIER_PROVISIONING");
   1385             final ComponentName serviceComponent = ComponentName.unflattenFromString(
   1386                     "com.android.omadm.service/.DMIntentReceiver");
   1387             intent.setComponent(serviceComponent);
   1388             sendBroadcast(intent);
   1389         }
   1390     };
   1391 
   1392     AdapterView.OnItemSelectedListener mPreferredNetworkHandler =
   1393             new AdapterView.OnItemSelectedListener() {
   1394 
   1395         public void onItemSelected(AdapterView parent, View v, int pos, long id) {
   1396             if (mPreferredNetworkTypeResult != pos && pos >= 0
   1397                     && pos <= mPreferredNetworkLabels.length - 2) {
   1398                 mPreferredNetworkTypeResult = pos;
   1399                 Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
   1400                 phone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
   1401             }
   1402         }
   1403 
   1404         public void onNothingSelected(AdapterView parent) {
   1405         }
   1406     };
   1407 
   1408     AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler  =
   1409             new AdapterView.OnItemSelectedListener() {
   1410 
   1411         public void onItemSelected(AdapterView parent, View v, int pos, long id) {
   1412             mCellInfoRefreshRateIndex = pos;
   1413             mTelephonyManager.setCellInfoListRate(mCellInfoRefreshRates[pos]);
   1414             updateAllCellInfo();
   1415         }
   1416 
   1417         public void onNothingSelected(AdapterView parent) {
   1418         }
   1419     };
   1420 
   1421 }
   1422