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