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