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