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