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