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