OSDN Git Service

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