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