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