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.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY; 21 import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE; 22 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL; 23 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_DATA_SUPPORT_MODE_INT; 24 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL; 25 import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO; 26 import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE; 27 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_3G; 28 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM; 29 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN; 30 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE; 31 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NR; 32 33 import static java.util.concurrent.TimeUnit.MILLISECONDS; 34 35 import android.annotation.NonNull; 36 import android.content.ActivityNotFoundException; 37 import android.content.ComponentName; 38 import android.content.DialogInterface; 39 import android.content.Intent; 40 import android.content.pm.ComponentInfo; 41 import android.content.pm.PackageManager; 42 import android.content.pm.ResolveInfo; 43 import android.content.res.Resources; 44 import android.graphics.Typeface; 45 import android.net.ConnectivityManager; 46 import android.net.Network; 47 import android.net.NetworkCapabilities; 48 import android.net.NetworkRequest; 49 import android.net.TrafficStats; 50 import android.net.Uri; 51 import android.os.AsyncResult; 52 import android.os.Build; 53 import android.os.Bundle; 54 import android.os.Handler; 55 import android.os.HandlerExecutor; 56 import android.os.HandlerThread; 57 import android.os.Message; 58 import android.os.PersistableBundle; 59 import android.os.SystemProperties; 60 import android.os.UserHandle; 61 import android.os.UserManager; 62 import android.telephony.AccessNetworkConstants; 63 import android.telephony.CarrierConfigManager; 64 import android.telephony.CellIdentityCdma; 65 import android.telephony.CellIdentityGsm; 66 import android.telephony.CellIdentityLte; 67 import android.telephony.CellIdentityNr; 68 import android.telephony.CellIdentityWcdma; 69 import android.telephony.CellInfo; 70 import android.telephony.CellInfoCdma; 71 import android.telephony.CellInfoGsm; 72 import android.telephony.CellInfoLte; 73 import android.telephony.CellInfoNr; 74 import android.telephony.CellInfoWcdma; 75 import android.telephony.CellSignalStrength; 76 import android.telephony.CellSignalStrengthCdma; 77 import android.telephony.CellSignalStrengthGsm; 78 import android.telephony.CellSignalStrengthLte; 79 import android.telephony.CellSignalStrengthNr; 80 import android.telephony.CellSignalStrengthWcdma; 81 import android.telephony.DataSpecificRegistrationInfo; 82 import android.telephony.NetworkRegistrationInfo; 83 import android.telephony.PhysicalChannelConfig; 84 import android.telephony.RadioAccessFamily; 85 import android.telephony.RadioAccessSpecifier; 86 import android.telephony.ServiceState; 87 import android.telephony.SignalStrength; 88 import android.telephony.SubscriptionManager; 89 import android.telephony.TelephonyCallback; 90 import android.telephony.TelephonyDisplayInfo; 91 import android.telephony.TelephonyManager; 92 import android.telephony.data.NetworkSlicingConfig; 93 import android.telephony.euicc.EuiccManager; 94 import android.telephony.ims.ImsException; 95 import android.telephony.ims.ImsManager; 96 import android.telephony.ims.ImsMmTelManager; 97 import android.telephony.ims.ImsRcsManager; 98 import android.telephony.ims.ProvisioningManager; 99 import android.telephony.ims.feature.MmTelFeature; 100 import android.telephony.satellite.SatelliteManager; 101 import android.text.TextUtils; 102 import android.util.Log; 103 import android.view.Menu; 104 import android.view.MenuItem; 105 import android.view.View; 106 import android.view.View.OnClickListener; 107 import android.widget.AdapterView; 108 import android.widget.ArrayAdapter; 109 import android.widget.Button; 110 import android.widget.CompoundButton; 111 import android.widget.CompoundButton.OnCheckedChangeListener; 112 import android.widget.EditText; 113 import android.widget.RadioGroup; 114 import android.widget.Spinner; 115 import android.widget.Switch; 116 import android.widget.TextView; 117 118 import androidx.appcompat.app.AlertDialog; 119 import androidx.appcompat.app.AlertDialog.Builder; 120 import androidx.appcompat.app.AppCompatActivity; 121 122 import com.android.internal.telephony.Phone; 123 import com.android.internal.telephony.PhoneFactory; 124 import com.android.internal.telephony.RILConstants; 125 import com.android.internal.telephony.euicc.EuiccConnector; 126 import com.android.internal.telephony.satellite.SatelliteServiceUtils; 127 import com.android.phone.R; 128 129 import java.io.IOException; 130 import java.net.HttpURLConnection; 131 import java.net.URL; 132 import java.util.ArrayList; 133 import java.util.Arrays; 134 import java.util.Collections; 135 import java.util.List; 136 import java.util.Locale; 137 import java.util.Map; 138 import java.util.Set; 139 import java.util.concurrent.CompletableFuture; 140 import java.util.concurrent.CountDownLatch; 141 import java.util.concurrent.ExecutionException; 142 import java.util.concurrent.LinkedBlockingDeque; 143 import java.util.concurrent.ThreadPoolExecutor; 144 import java.util.concurrent.TimeUnit; 145 import java.util.concurrent.TimeoutException; 146 import java.util.concurrent.atomic.AtomicBoolean; 147 148 /** 149 * Radio Information Class 150 * 151 * Allows user to read and alter some of the radio related information. 152 * 153 */ 154 public class RadioInfo extends AppCompatActivity { 155 private static final String TAG = "RadioInfo"; 156 157 private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 158 159 private static final String[] PREFERRED_NETWORK_LABELS = { 160 "GSM/WCDMA preferred", 161 "GSM only", 162 "WCDMA only", 163 "GSM/WCDMA auto (PRL)", 164 "CDMA/EvDo auto (PRL)", 165 "CDMA only", 166 "EvDo only", 167 "CDMA/EvDo/GSM/WCDMA (PRL)", 168 "CDMA + LTE/EvDo (PRL)", 169 "GSM/WCDMA/LTE (PRL)", 170 "LTE/CDMA/EvDo/GSM/WCDMA (PRL)", 171 "LTE only", 172 "LTE/WCDMA", 173 "TDSCDMA only", 174 "TDSCDMA/WCDMA", 175 "LTE/TDSCDMA", 176 "TDSCDMA/GSM", 177 "LTE/TDSCDMA/GSM", 178 "TDSCDMA/GSM/WCDMA", 179 "LTE/TDSCDMA/WCDMA", 180 "LTE/TDSCDMA/GSM/WCDMA", 181 "TDSCDMA/CDMA/EvDo/GSM/WCDMA ", 182 "LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA", 183 "NR only", 184 "NR/LTE", 185 "NR/LTE/CDMA/EvDo", 186 "NR/LTE/GSM/WCDMA", 187 "NR/LTE/CDMA/EvDo/GSM/WCDMA", 188 "NR/LTE/WCDMA", 189 "NR/LTE/TDSCDMA", 190 "NR/LTE/TDSCDMA/GSM", 191 "NR/LTE/TDSCDMA/WCDMA", 192 "NR/LTE/TDSCDMA/GSM/WCDMA", 193 "NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA", 194 "Unknown" 195 }; 196 197 private static final Integer[] SIGNAL_STRENGTH_LEVEL = new Integer[] { 198 -1 /*clear mock*/, 199 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, 200 CellSignalStrength.SIGNAL_STRENGTH_POOR, 201 CellSignalStrength.SIGNAL_STRENGTH_MODERATE, 202 CellSignalStrength.SIGNAL_STRENGTH_GOOD, 203 CellSignalStrength.SIGNAL_STRENGTH_GREAT 204 }; 205 private static final Integer[] MOCK_DATA_NETWORK_TYPE = new Integer[] { 206 -1 /*clear mock*/, 207 ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, 208 ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, 209 ServiceState.RIL_RADIO_TECHNOLOGY_UMTS, 210 ServiceState.RIL_RADIO_TECHNOLOGY_IS95A, 211 ServiceState.RIL_RADIO_TECHNOLOGY_IS95B, 212 ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT, 213 ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0, 214 ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A, 215 ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA, 216 ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA, 217 ServiceState.RIL_RADIO_TECHNOLOGY_HSPA, 218 ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B, 219 ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD, 220 ServiceState.RIL_RADIO_TECHNOLOGY_LTE, 221 ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP, 222 ServiceState.RIL_RADIO_TECHNOLOGY_GSM, 223 ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA, 224 ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA, 225 ServiceState.RIL_RADIO_TECHNOLOGY_NR 226 }; 227 private static String[] sPhoneIndexLabels = new String[0]; 228 229 private static final int sCellInfoListRateDisabled = Integer.MAX_VALUE; 230 private static final int sCellInfoListRateMax = 0; 231 232 private static final String OEM_RADIO_INFO_INTENT = 233 "com.android.phone.settings.OEM_RADIO_INFO"; 234 235 private static final String DSDS_MODE_PROPERTY = "ro.boot.hardware.dsds"; 236 237 /** 238 * A value indicates the device is always on dsds mode. 239 * @see {@link #DSDS_MODE_PROPERTY} 240 */ 241 private static final int ALWAYS_ON_DSDS_MODE = 1; 242 243 //Values in must match CELL_INFO_REFRESH_RATES 244 private static final String[] CELL_INFO_REFRESH_RATE_LABELS = { 245 "Disabled", 246 "Immediate", 247 "Min 5s", 248 "Min 10s", 249 "Min 60s" 250 }; 251 252 //Values in seconds, must match CELL_INFO_REFRESH_RATE_LABELS 253 private static final int [] CELL_INFO_REFRESH_RATES = { 254 sCellInfoListRateDisabled, 255 sCellInfoListRateMax, 256 5000, 257 10000, 258 60000 259 }; 260 log(String s)261 private static void log(String s) { 262 Log.d(TAG, s); 263 } 264 loge(String s)265 private static void loge(String s) { 266 Log.e(TAG, s); 267 } 268 269 private static final int EVENT_QUERY_SMSC_DONE = 1005; 270 private static final int EVENT_UPDATE_SMSC_DONE = 1006; 271 private static final int EVENT_UPDATE_NR_STATS = 1008; 272 273 private static final int MENU_ITEM_VIEW_ADN = 1; 274 private static final int MENU_ITEM_VIEW_FDN = 2; 275 private static final int MENU_ITEM_VIEW_SDN = 3; 276 private static final int MENU_ITEM_GET_IMS_STATUS = 4; 277 private static final int MENU_ITEM_TOGGLE_DATA = 5; 278 279 private static final String CARRIER_PROVISIONING_ACTION = 280 "com.android.phone.settings.CARRIER_PROVISIONING"; 281 private static final String TRIGGER_CARRIER_PROVISIONING_ACTION = 282 "com.android.phone.settings.TRIGGER_CARRIER_PROVISIONING"; 283 284 private static final String ACTION_REMOVABLE_ESIM_AS_DEFAULT = 285 "android.telephony.euicc.action.REMOVABLE_ESIM_AS_DEFAULT"; 286 287 private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA 288 private TextView mLine1Number; 289 private TextView mSubscriptionId; 290 private TextView mDds; 291 private TextView mSubscriberId; 292 private TextView mCallState; 293 private TextView mOperatorName; 294 private TextView mRoamingState; 295 private TextView mGsmState; 296 private TextView mGprsState; 297 private TextView mVoiceNetwork; 298 private TextView mDataNetwork; 299 private TextView mVoiceRawReg; 300 private TextView mDataRawReg; 301 private TextView mWlanDataRawReg; 302 private TextView mOverrideNetwork; 303 private TextView mDBm; 304 private TextView mMwi; 305 private TextView mCfi; 306 private TextView mCellInfo; 307 private TextView mSent; 308 private TextView mReceived; 309 private TextView mPingHostnameV4; 310 private TextView mPingHostnameV6; 311 private TextView mHttpClientTest; 312 private TextView mPhyChanConfig; 313 private TextView mDownlinkKbps; 314 private TextView mUplinkKbps; 315 private TextView mEndcAvailable; 316 private TextView mDcnrRestricted; 317 private TextView mNrAvailable; 318 private TextView mNrState; 319 private TextView mNrFrequency; 320 private TextView mNetworkSlicingConfig; 321 private TextView mEuiccInfo; 322 private EditText mSmsc; 323 private Switch mRadioPowerOnSwitch; 324 private Switch mSimulateOutOfServiceSwitch; 325 private Switch mEnforceSatelliteChannel; 326 private Switch mMockSatellite; 327 private Switch mMockSatelliteDataSwitch; 328 private RadioGroup mMockSatelliteData; 329 private Button mPingTestButton; 330 private Button mUpdateSmscButton; 331 private Button mRefreshSmscButton; 332 private Button mOemInfoButton; 333 private Button mCarrierProvisioningButton; 334 private Button mTriggerCarrierProvisioningButton; 335 private Button mEsosButton; 336 private Button mSatelliteEnableNonEmergencyModeButton; 337 private Button mEsosDemoButton; 338 private Button mSatelliteConfigViewerButton; 339 private Switch mImsVolteProvisionedSwitch; 340 private Switch mImsVtProvisionedSwitch; 341 private Switch mImsWfcProvisionedSwitch; 342 private Switch mEabProvisionedSwitch; 343 private Switch mCbrsDataSwitch; 344 private Switch mDsdsSwitch; 345 private Switch mRemovableEsimSwitch; 346 private Spinner mPreferredNetworkType; 347 private Spinner mMockSignalStrength; 348 private Spinner mMockDataNetworkType; 349 350 private Spinner mSelectPhoneIndex; 351 private Spinner mCellInfoRefreshRateSpinner; 352 353 private static final long RUNNABLE_TIMEOUT_MS = 5 * 60 * 1000L; 354 355 private ThreadPoolExecutor mQueuedWork; 356 357 private ConnectivityManager mConnectivityManager; 358 private TelephonyManager mTelephonyManager; 359 private ImsManager mImsManager = null; 360 private Phone mPhone = null; 361 private ProvisioningManager mProvisioningManager = null; 362 private EuiccManager mEuiccManager; 363 364 private String mPingHostnameResultV4; 365 private String mPingHostnameResultV6; 366 private String mHttpClientTestResult; 367 private boolean mMwiValue = false; 368 private boolean mCfiValue = false; 369 370 private boolean mSystemUser = true; 371 372 private final PersistableBundle[] mCarrierSatelliteOriginalBundle = new PersistableBundle[2]; 373 private final PersistableBundle[] mSatelliteDataOriginalBundle = new PersistableBundle[2]; 374 private final PersistableBundle[] mOriginalSystemChannels = new PersistableBundle[2]; 375 private List<CellInfo> mCellInfoResult = null; 376 private final boolean[] mSimulateOos = new boolean[2]; 377 private int[] mSelectedSignalStrengthIndex = new int[2]; 378 private int[] mSelectedMockDataNetworkTypeIndex = new int[2]; 379 private String mEuiccInfoResult = ""; 380 381 private int mPreferredNetworkTypeResult; 382 private int mCellInfoRefreshRateIndex; 383 private int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX; 384 private static final int DEFAULT_PHONE_ID = 0; 385 386 private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 387 388 private String mActionEsos; 389 private String mActionEsosDemo; 390 private Intent mNonEsosIntent; 391 private TelephonyDisplayInfo mDisplayInfo; 392 private CarrierConfigManager mCarrierConfigManager; 393 394 private List<PhysicalChannelConfig> mPhysicalChannelConfigs = new ArrayList<>(); 395 396 private final NetworkRequest mDefaultNetworkRequest = new NetworkRequest.Builder() 397 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) 398 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 399 .build(); 400 401 private final NetworkCallback mNetworkCallback = new NetworkCallback() { 402 public void onCapabilitiesChanged(Network n, NetworkCapabilities nc) { 403 int dlbw = nc.getLinkDownstreamBandwidthKbps(); 404 int ulbw = nc.getLinkUpstreamBandwidthKbps(); 405 updateBandwidths(dlbw, ulbw); 406 } 407 }; 408 409 private static final int DEFAULT_TIMEOUT_MS = 1000; 410 411 // not final because we need to recreate this object to register on a new subId (b/117555407) 412 private TelephonyCallback mTelephonyCallback = new RadioInfoTelephonyCallback(); 413 private class RadioInfoTelephonyCallback extends TelephonyCallback implements 414 TelephonyCallback.DataConnectionStateListener, 415 TelephonyCallback.DataActivityListener, 416 TelephonyCallback.CallStateListener, 417 TelephonyCallback.MessageWaitingIndicatorListener, 418 TelephonyCallback.CallForwardingIndicatorListener, 419 TelephonyCallback.CellInfoListener, 420 TelephonyCallback.SignalStrengthsListener, 421 TelephonyCallback.ServiceStateListener, 422 TelephonyCallback.PhysicalChannelConfigListener, 423 TelephonyCallback.DisplayInfoListener { 424 425 @Override onDataConnectionStateChanged(int state, int networkType)426 public void onDataConnectionStateChanged(int state, int networkType) { 427 updateDataState(); 428 updateNetworkType(); 429 } 430 431 @Override onDataActivity(int direction)432 public void onDataActivity(int direction) { 433 updateDataStats2(); 434 } 435 436 @Override onCallStateChanged(int state)437 public void onCallStateChanged(int state) { 438 updateNetworkType(); 439 updatePhoneState(state); 440 } 441 442 @Override onMessageWaitingIndicatorChanged(boolean mwi)443 public void onMessageWaitingIndicatorChanged(boolean mwi) { 444 mMwiValue = mwi; 445 updateMessageWaiting(); 446 } 447 448 @Override onCallForwardingIndicatorChanged(boolean cfi)449 public void onCallForwardingIndicatorChanged(boolean cfi) { 450 mCfiValue = cfi; 451 updateCallRedirect(); 452 } 453 454 @Override onCellInfoChanged(List<CellInfo> arrayCi)455 public void onCellInfoChanged(List<CellInfo> arrayCi) { 456 log("onCellInfoChanged: arrayCi=" + arrayCi); 457 mCellInfoResult = arrayCi; 458 updateCellInfo(mCellInfoResult); 459 } 460 461 @Override onSignalStrengthsChanged(SignalStrength signalStrength)462 public void onSignalStrengthsChanged(SignalStrength signalStrength) { 463 log("onSignalStrengthChanged: SignalStrength=" + signalStrength); 464 updateSignalStrength(signalStrength); 465 } 466 467 @Override onServiceStateChanged(ServiceState serviceState)468 public void onServiceStateChanged(ServiceState serviceState) { 469 log("onServiceStateChanged: ServiceState=" + serviceState); 470 updateServiceState(serviceState); 471 updateRadioPowerState(); 472 updateNetworkType(); 473 updateRawRegistrationState(serviceState); 474 updateImsProvisionedState(); 475 476 // Since update NR stats includes a ril message to get slicing information, it runs 477 // as blocking during the timeout period of 1 second. if ServiceStateChanged event 478 // fires consecutively, RadioInfo can run for more than 10 seconds. This can cause ANR. 479 // Therefore, send event only when there is no same event being processed. 480 if (!mHandler.hasMessages(EVENT_UPDATE_NR_STATS)) { 481 mHandler.obtainMessage(EVENT_UPDATE_NR_STATS).sendToTarget(); 482 } 483 } 484 485 @Override onDisplayInfoChanged(TelephonyDisplayInfo displayInfo)486 public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo) { 487 mDisplayInfo = displayInfo; 488 updateNetworkType(); 489 } 490 491 @Override onPhysicalChannelConfigChanged(@onNull List<PhysicalChannelConfig> configs)492 public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs) { 493 updatePhysicalChannelConfiguration(configs); 494 } 495 } 496 updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs)497 private void updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) { 498 mPhysicalChannelConfigs = configs; 499 StringBuilder sb = new StringBuilder(); 500 String div = ""; 501 sb.append("{"); 502 if (mPhysicalChannelConfigs != null) { 503 for (PhysicalChannelConfig c : mPhysicalChannelConfigs) { 504 sb.append(div).append(c); 505 div = ","; 506 } 507 } 508 sb.append("}"); 509 mPhyChanConfig.setText(sb.toString()); 510 } 511 updatePreferredNetworkType(int type)512 private void updatePreferredNetworkType(int type) { 513 if (type >= PREFERRED_NETWORK_LABELS.length || type < 0) { 514 log("Network type: unknown type value=" + type); 515 type = PREFERRED_NETWORK_LABELS.length - 1; //set to Unknown 516 } 517 mPreferredNetworkTypeResult = type; 518 519 mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true); 520 } 521 updatePhoneIndex()522 private void updatePhoneIndex() { 523 // unregister listeners on the old subId 524 unregisterPhoneStateListener(); 525 mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled, mSubId); 526 527 // update the subId 528 mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId); 529 530 // update the phoneId 531 if (mSystemUser) { 532 mPhone = PhoneFactory.getPhone(mPhoneId); 533 } 534 mImsManager = new ImsManager(this); 535 try { 536 mProvisioningManager = ProvisioningManager.createForSubscriptionId(mSubId); 537 } catch (IllegalArgumentException e) { 538 log("updatePhoneIndex : IllegalArgumentException " + e.getMessage()); 539 mProvisioningManager = null; 540 } 541 542 updateAllFields(); 543 } 544 545 private Handler mHandler = new Handler() { 546 @Override 547 public void handleMessage(Message msg) { 548 AsyncResult ar; 549 switch (msg.what) { 550 case EVENT_QUERY_SMSC_DONE: 551 ar = (AsyncResult) msg.obj; 552 if (ar.exception != null) { 553 mSmsc.setText("refresh error"); 554 } else { 555 mSmsc.setText((String) ar.result); 556 } 557 break; 558 case EVENT_UPDATE_SMSC_DONE: 559 mUpdateSmscButton.setEnabled(true); 560 ar = (AsyncResult) msg.obj; 561 if (ar.exception != null) { 562 mSmsc.setText("update error"); 563 } 564 break; 565 case EVENT_UPDATE_NR_STATS: 566 log("got EVENT_UPDATE_NR_STATS"); 567 updateNrStats(); 568 break; 569 default: 570 super.handleMessage(msg); 571 break; 572 573 } 574 } 575 }; 576 577 @Override onCreate(Bundle icicle)578 public void onCreate(Bundle icicle) { 579 super.onCreate(icicle); 580 SettingsConstants.setupEdgeToEdge(this); 581 mSystemUser = android.os.Process.myUserHandle().isSystem(); 582 log("onCreate: mSystemUser=" + mSystemUser); 583 UserManager userManager = getSystemService(UserManager.class); 584 if (userManager != null 585 && userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) { 586 Log.w(TAG, "User is restricted from configuring mobile networks."); 587 finish(); 588 return; 589 } 590 591 setContentView(R.layout.radio_info); 592 Resources r = getResources(); 593 mActionEsos = 594 r.getString( 595 com.android.internal.R.string 596 .config_satellite_test_with_esp_replies_intent_action); 597 598 mActionEsosDemo = 599 r.getString( 600 com.android.internal.R.string.config_satellite_demo_mode_sos_intent_action); 601 602 mQueuedWork = new ThreadPoolExecutor(1, 1, RUNNABLE_TIMEOUT_MS, TimeUnit.MICROSECONDS, 603 new LinkedBlockingDeque<>()); 604 mConnectivityManager = getSystemService(ConnectivityManager.class); 605 if (mSystemUser) { 606 mPhone = getPhone(SubscriptionManager.getDefaultSubscriptionId()); 607 } 608 mSubId = SubscriptionManager.getDefaultSubscriptionId(); 609 if (mPhone != null) { 610 mPhoneId = mPhone.getPhoneId(); 611 } else { 612 mPhoneId = SubscriptionManager.getPhoneId(mSubId); 613 } 614 if (!SubscriptionManager.isValidPhoneId(mPhoneId)) { 615 mPhoneId = DEFAULT_PHONE_ID; 616 } 617 618 mTelephonyManager = getSystemService(TelephonyManager.class) 619 .createForSubscriptionId(mSubId); 620 mEuiccManager = getSystemService(EuiccManager.class); 621 622 mImsManager = new ImsManager(this); 623 try { 624 mProvisioningManager = ProvisioningManager.createForSubscriptionId(mSubId); 625 } catch (IllegalArgumentException e) { 626 log("onCreate : IllegalArgumentException " + e.getMessage()); 627 mProvisioningManager = null; 628 } 629 630 sPhoneIndexLabels = getPhoneIndexLabels(mTelephonyManager); 631 632 mDeviceId = (TextView) findViewById(R.id.imei); 633 mLine1Number = (TextView) findViewById(R.id.number); 634 mSubscriptionId = (TextView) findViewById(R.id.subid); 635 mDds = (TextView) findViewById(R.id.dds); 636 mSubscriberId = (TextView) findViewById(R.id.imsi); 637 mCallState = (TextView) findViewById(R.id.call); 638 mOperatorName = (TextView) findViewById(R.id.operator); 639 mRoamingState = (TextView) findViewById(R.id.roaming); 640 mGsmState = (TextView) findViewById(R.id.gsm); 641 mGprsState = (TextView) findViewById(R.id.gprs); 642 mVoiceNetwork = (TextView) findViewById(R.id.voice_network); 643 mDataNetwork = (TextView) findViewById(R.id.data_network); 644 mVoiceRawReg = (TextView) findViewById(R.id.voice_raw_registration_state); 645 mDataRawReg = (TextView) findViewById(R.id.data_raw_registration_state); 646 mWlanDataRawReg = (TextView) findViewById(R.id.wlan_data_raw_registration_state); 647 mOverrideNetwork = (TextView) findViewById(R.id.override_network); 648 mDBm = (TextView) findViewById(R.id.dbm); 649 mMwi = (TextView) findViewById(R.id.mwi); 650 mCfi = (TextView) findViewById(R.id.cfi); 651 mCellInfo = (TextView) findViewById(R.id.cellinfo); 652 mCellInfo.setTypeface(Typeface.MONOSPACE); 653 654 mSent = (TextView) findViewById(R.id.sent); 655 mReceived = (TextView) findViewById(R.id.received); 656 mSmsc = (EditText) findViewById(R.id.smsc); 657 mPingHostnameV4 = (TextView) findViewById(R.id.pingHostnameV4); 658 mPingHostnameV6 = (TextView) findViewById(R.id.pingHostnameV6); 659 mHttpClientTest = (TextView) findViewById(R.id.httpClientTest); 660 mEndcAvailable = (TextView) findViewById(R.id.endc_available); 661 mDcnrRestricted = (TextView) findViewById(R.id.dcnr_restricted); 662 mNrAvailable = (TextView) findViewById(R.id.nr_available); 663 mNrState = (TextView) findViewById(R.id.nr_state); 664 mNrFrequency = (TextView) findViewById(R.id.nr_frequency); 665 mPhyChanConfig = (TextView) findViewById(R.id.phy_chan_config); 666 mNetworkSlicingConfig = (TextView) findViewById(R.id.network_slicing_config); 667 mEuiccInfo = (TextView) findViewById(R.id.euicc_info); 668 669 // hide 5G stats on devices that don't support 5G 670 if ((mTelephonyManager.getSupportedRadioAccessFamily() 671 & TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) { 672 setNrStatsVisibility(View.GONE); 673 } 674 675 mPreferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType); 676 ArrayAdapter<String> mPreferredNetworkTypeAdapter = new ArrayAdapter<String>(this, 677 android.R.layout.simple_spinner_item, PREFERRED_NETWORK_LABELS); 678 mPreferredNetworkTypeAdapter 679 .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 680 mPreferredNetworkType.setAdapter(mPreferredNetworkTypeAdapter); 681 682 mMockSignalStrength = (Spinner) findViewById(R.id.signalStrength); 683 if (!Build.isDebuggable() || !mSystemUser) { 684 mMockSignalStrength.setVisibility(View.GONE); 685 findViewById(R.id.signalStrength).setVisibility(View.GONE); 686 findViewById(R.id.signal_strength_label).setVisibility(View.GONE); 687 } else { 688 ArrayAdapter<Integer> mSignalStrengthAdapter = new ArrayAdapter<>(this, 689 android.R.layout.simple_spinner_item, SIGNAL_STRENGTH_LEVEL); 690 mSignalStrengthAdapter 691 .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 692 mMockSignalStrength.setAdapter(mSignalStrengthAdapter); 693 } 694 695 mMockDataNetworkType = (Spinner) findViewById(R.id.dataNetworkType); 696 if (!Build.isDebuggable() || !mSystemUser) { 697 mMockDataNetworkType.setVisibility(View.GONE); 698 findViewById(R.id.dataNetworkType).setVisibility(View.GONE); 699 findViewById(R.id.data_network_type_label).setVisibility(View.GONE); 700 } else { 701 ArrayAdapter<String> mNetworkTypeAdapter = new ArrayAdapter<>(this, 702 android.R.layout.simple_spinner_item, Arrays.stream(MOCK_DATA_NETWORK_TYPE) 703 .map(ServiceState::rilRadioTechnologyToString).toArray(String[]::new)); 704 mNetworkTypeAdapter 705 .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 706 mMockDataNetworkType.setAdapter(mNetworkTypeAdapter); 707 } 708 709 mSelectPhoneIndex = (Spinner) findViewById(R.id.phoneIndex); 710 ArrayAdapter<String> phoneIndexAdapter = new ArrayAdapter<String>(this, 711 android.R.layout.simple_spinner_item, sPhoneIndexLabels); 712 phoneIndexAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 713 mSelectPhoneIndex.setAdapter(phoneIndexAdapter); 714 715 mCellInfoRefreshRateSpinner = (Spinner) findViewById(R.id.cell_info_rate_select); 716 ArrayAdapter<String> cellInfoAdapter = new ArrayAdapter<String>(this, 717 android.R.layout.simple_spinner_item, CELL_INFO_REFRESH_RATE_LABELS); 718 cellInfoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 719 mCellInfoRefreshRateSpinner.setAdapter(cellInfoAdapter); 720 721 mImsVolteProvisionedSwitch = (Switch) findViewById(R.id.volte_provisioned_switch); 722 mImsVtProvisionedSwitch = (Switch) findViewById(R.id.vt_provisioned_switch); 723 mImsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch); 724 mEabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch); 725 726 if (!isImsSupportedOnDevice()) { 727 mImsVolteProvisionedSwitch.setVisibility(View.GONE); 728 mImsVtProvisionedSwitch.setVisibility(View.GONE); 729 mImsWfcProvisionedSwitch.setVisibility(View.GONE); 730 mEabProvisionedSwitch.setVisibility(View.GONE); 731 } 732 733 mCbrsDataSwitch = (Switch) findViewById(R.id.cbrs_data_switch); 734 mCbrsDataSwitch.setVisibility(isCbrsSupported() ? View.VISIBLE : View.GONE); 735 736 mDsdsSwitch = findViewById(R.id.dsds_switch); 737 if (isDsdsSupported() && !dsdsModeOnly()) { 738 mDsdsSwitch.setVisibility(View.VISIBLE); 739 mDsdsSwitch.setOnClickListener(v -> { 740 if (mTelephonyManager.doesSwitchMultiSimConfigTriggerReboot()) { 741 // Undo the click action until user clicks the confirm dialog. 742 mDsdsSwitch.toggle(); 743 showDsdsChangeDialog(); 744 } else { 745 performDsdsSwitch(); 746 } 747 }); 748 mDsdsSwitch.setChecked(isDsdsEnabled()); 749 } else { 750 mDsdsSwitch.setVisibility(View.GONE); 751 } 752 753 mRemovableEsimSwitch = (Switch) findViewById(R.id.removable_esim_switch); 754 if (!IS_USER_BUILD) { 755 mRemovableEsimSwitch.setEnabled(true); 756 mRemovableEsimSwitch.setChecked(mTelephonyManager.isRemovableEsimDefaultEuicc()); 757 mRemovableEsimSwitch.setOnCheckedChangeListener(mRemovableEsimChangeListener); 758 } 759 760 mRadioPowerOnSwitch = (Switch) findViewById(R.id.radio_power); 761 762 mSimulateOutOfServiceSwitch = (Switch) findViewById(R.id.simulate_out_of_service); 763 if (!Build.isDebuggable()) { 764 mSimulateOutOfServiceSwitch.setVisibility(View.GONE); 765 } 766 mMockSatellite = (Switch) findViewById(R.id.mock_carrier_roaming_satellite); 767 mMockSatelliteDataSwitch = (Switch) findViewById(R.id.satellite_data_controller_switch); 768 mMockSatelliteData = findViewById(R.id.satellite_data_controller); 769 mEnforceSatelliteChannel = (Switch) findViewById(R.id.enforce_satellite_channel); 770 if (!Build.isDebuggable()) { 771 mMockSatellite.setVisibility(View.GONE); 772 mMockSatelliteDataSwitch.setVisibility(View.GONE); 773 mMockSatelliteData.setVisibility(View.GONE); 774 mEnforceSatelliteChannel.setVisibility(View.GONE); 775 } 776 777 mDownlinkKbps = (TextView) findViewById(R.id.dl_kbps); 778 mUplinkKbps = (TextView) findViewById(R.id.ul_kbps); 779 updateBandwidths(0, 0); 780 781 mPingTestButton = (Button) findViewById(R.id.ping_test); 782 mPingTestButton.setOnClickListener(mPingButtonHandler); 783 mUpdateSmscButton = (Button) findViewById(R.id.update_smsc); 784 mUpdateSmscButton.setOnClickListener(mUpdateSmscButtonHandler); 785 mRefreshSmscButton = (Button) findViewById(R.id.refresh_smsc); 786 mRefreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler); 787 if (!mSystemUser) { 788 mSmsc.setVisibility(View.GONE); 789 mUpdateSmscButton.setVisibility(View.GONE); 790 mRefreshSmscButton.setVisibility(View.GONE); 791 findViewById(R.id.smsc_label).setVisibility(View.GONE); 792 } 793 mCarrierProvisioningButton = (Button) findViewById(R.id.carrier_provisioning); 794 if (!TextUtils.isEmpty(getCarrierProvisioningAppString())) { 795 mCarrierProvisioningButton.setOnClickListener(mCarrierProvisioningButtonHandler); 796 } else { 797 mCarrierProvisioningButton.setEnabled(false); 798 } 799 800 mTriggerCarrierProvisioningButton = (Button) findViewById( 801 R.id.trigger_carrier_provisioning); 802 if (!TextUtils.isEmpty(getCarrierProvisioningAppString())) { 803 mTriggerCarrierProvisioningButton.setOnClickListener( 804 mTriggerCarrierProvisioningButtonHandler); 805 } else { 806 mTriggerCarrierProvisioningButton.setEnabled(false); 807 } 808 809 mEsosButton = (Button) findViewById(R.id.esos_questionnaire); 810 mEsosDemoButton = (Button) findViewById(R.id.demo_esos_questionnaire); 811 mSatelliteEnableNonEmergencyModeButton = (Button) findViewById( 812 R.id.satellite_enable_non_emergency_mode); 813 mSatelliteConfigViewerButton = (Button) findViewById(R.id.satellite_config_viewer); 814 815 if (shouldHideButton(mActionEsos)) { 816 mEsosButton.setVisibility(View.GONE); 817 } else { 818 mEsosButton.setOnClickListener(v -> startActivityAsUser( 819 new Intent(mActionEsos).addFlags( 820 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK), 821 UserHandle.CURRENT) 822 ); 823 } 824 if (shouldHideButton(mActionEsosDemo)) { 825 mEsosDemoButton.setVisibility(View.GONE); 826 } else { 827 mEsosDemoButton.setOnClickListener(v -> startActivityAsUser( 828 new Intent(mActionEsosDemo).addFlags( 829 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK), 830 UserHandle.CURRENT) 831 ); 832 } 833 if (shouldHideNonEmergencyMode()) { 834 mSatelliteEnableNonEmergencyModeButton.setVisibility(View.GONE); 835 } else { 836 mSatelliteEnableNonEmergencyModeButton.setOnClickListener(v -> { 837 if (mNonEsosIntent != null) { 838 sendBroadcast(mNonEsosIntent); 839 } 840 }); 841 } 842 843 mSatelliteConfigViewerButton.setOnClickListener(v -> { 844 Intent intent = new Intent(Intent.ACTION_VIEW); 845 intent.putExtra("mSubId", mSubId); 846 intent.setClassName("com.android.phone", 847 "com.android.phone.settings.SatelliteConfigViewer"); 848 startActivityAsUser(intent, UserHandle.CURRENT); 849 }); 850 851 mOemInfoButton = (Button) findViewById(R.id.oem_info); 852 mOemInfoButton.setOnClickListener(mOemInfoButtonHandler); 853 PackageManager pm = getPackageManager(); 854 Intent oemInfoIntent = new Intent(OEM_RADIO_INFO_INTENT); 855 List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0); 856 if (oemInfoIntentList.size() == 0) { 857 mOemInfoButton.setEnabled(false); 858 } 859 860 mCellInfoRefreshRateIndex = 0; //disabled 861 mPreferredNetworkTypeResult = PREFERRED_NETWORK_LABELS.length - 1; //Unknown 862 863 new Thread(() -> { 864 int networkType = (int) mTelephonyManager.getPreferredNetworkTypeBitmask(); 865 runOnUiThread(() -> updatePreferredNetworkType( 866 RadioAccessFamily.getNetworkTypeFromRaf(networkType))); 867 }).start(); 868 restoreFromBundle(icicle); 869 } 870 shouldHideButton(String action)871 boolean shouldHideButton(String action) { 872 if (!Build.isDebuggable()) { 873 return true; 874 } 875 if (TextUtils.isEmpty(action)) { 876 return true; 877 } 878 PackageManager pm = getPackageManager(); 879 Intent intent = new Intent(action); 880 if (pm.resolveActivity(intent, 0) == null) { 881 return true; 882 } 883 return false; 884 } 885 886 @Override getParentActivityIntent()887 public Intent getParentActivityIntent() { 888 Intent parentActivity = super.getParentActivityIntent(); 889 if (parentActivity == null) { 890 parentActivity = (new Intent()).setClassName("com.android.settings", 891 "com.android.settings.Settings$TestingSettingsActivity"); 892 } 893 return parentActivity; 894 } 895 896 @Override onResume()897 protected void onResume() { 898 super.onResume(); 899 900 log("Started onResume"); 901 902 updateAllFields(); 903 } 904 updateAllFields()905 private void updateAllFields() { 906 updateMessageWaiting(); 907 updateCallRedirect(); 908 updateDataState(); 909 updateDataStats2(); 910 updateRadioPowerState(); 911 updateImsProvisionedState(); 912 updateProperties(); 913 updateNetworkType(); 914 updateNrStats(); 915 updateEuiccInfo(); 916 917 updateCellInfo(mCellInfoResult); 918 updateSubscriptionIds(); 919 920 mPingHostnameV4.setText(mPingHostnameResultV4); 921 mPingHostnameV6.setText(mPingHostnameResultV6); 922 mHttpClientTest.setText(mHttpClientTestResult); 923 924 mCellInfoRefreshRateSpinner.setOnItemSelectedListener(mCellInfoRefreshRateHandler); 925 //set selection after registering listener to force update 926 mCellInfoRefreshRateSpinner.setSelection(mCellInfoRefreshRateIndex); 927 // Request cell information update from RIL. 928 mTelephonyManager.setCellInfoListRate(CELL_INFO_REFRESH_RATES[mCellInfoRefreshRateIndex], 929 mSubId); 930 931 //set selection before registering to prevent update 932 mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true); 933 mPreferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler); 934 935 new Thread(() -> { 936 int networkType = (int) mTelephonyManager.getPreferredNetworkTypeBitmask(); 937 runOnUiThread(() -> updatePreferredNetworkType( 938 RadioAccessFamily.getNetworkTypeFromRaf(networkType))); 939 }).start(); 940 941 // mock signal strength 942 mMockSignalStrength.setSelection(mSelectedSignalStrengthIndex[mPhoneId]); 943 mMockSignalStrength.setOnItemSelectedListener(mOnMockSignalStrengthSelectedListener); 944 945 // mock data network type 946 mMockDataNetworkType.setSelection(mSelectedMockDataNetworkTypeIndex[mPhoneId]); 947 mMockDataNetworkType.setOnItemSelectedListener(mOnMockDataNetworkTypeSelectedListener); 948 949 // set phone index 950 mSelectPhoneIndex.setSelection(mPhoneId, true); 951 mSelectPhoneIndex.setOnItemSelectedListener(mSelectPhoneIndexHandler); 952 953 mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener); 954 mSimulateOutOfServiceSwitch.setChecked(mSimulateOos[mPhoneId]); 955 mSimulateOutOfServiceSwitch.setOnCheckedChangeListener(mSimulateOosOnChangeListener); 956 mMockSatellite.setChecked(mCarrierSatelliteOriginalBundle[mPhoneId] != null); 957 mMockSatellite.setOnCheckedChangeListener(mMockSatelliteListener); 958 mMockSatelliteDataSwitch.setChecked(mSatelliteDataOriginalBundle[mPhoneId] != null); 959 mMockSatelliteDataSwitch.setOnCheckedChangeListener(mMockSatelliteDataSwitchListener); 960 mMockSatelliteData.setOnCheckedChangeListener(mMockSatelliteDataListener); 961 962 updateSatelliteChannelDisplay(mPhoneId); 963 mEnforceSatelliteChannel.setOnCheckedChangeListener(mForceSatelliteChannelOnChangeListener); 964 mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener); 965 mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener); 966 mImsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener); 967 mEabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener); 968 969 if (isCbrsSupported()) { 970 mCbrsDataSwitch.setChecked(getCbrsDataState()); 971 mCbrsDataSwitch.setOnCheckedChangeListener(mCbrsDataSwitchChangeListener); 972 } 973 974 unregisterPhoneStateListener(); 975 registerPhoneStateListener(); 976 mConnectivityManager.registerNetworkCallback( 977 mDefaultNetworkRequest, mNetworkCallback, mHandler); 978 mSmsc.clearFocus(); 979 } 980 981 @Override onPause()982 protected void onPause() { 983 super.onPause(); 984 985 log("onPause: unregister phone & data intents"); 986 987 mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); 988 mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled, mSubId); 989 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); 990 991 } 992 restoreFromBundle(Bundle b)993 private void restoreFromBundle(Bundle b) { 994 if (b == null) { 995 return; 996 } 997 998 mPingHostnameResultV4 = b.getString("mPingHostnameResultV4", ""); 999 mPingHostnameResultV6 = b.getString("mPingHostnameResultV6", ""); 1000 mHttpClientTestResult = b.getString("mHttpClientTestResult", ""); 1001 1002 mPingHostnameV4.setText(mPingHostnameResultV4); 1003 mPingHostnameV6.setText(mPingHostnameResultV6); 1004 mHttpClientTest.setText(mHttpClientTestResult); 1005 1006 mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult", 1007 PREFERRED_NETWORK_LABELS.length - 1); 1008 1009 mPhoneId = b.getInt("mSelectedPhoneIndex", 0); 1010 mSubId = SubscriptionManager.getSubscriptionId(mPhoneId); 1011 1012 mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0); 1013 } 1014 1015 @SuppressWarnings("MissingSuperCall") // TODO: Fix me 1016 @Override onSaveInstanceState(Bundle outState)1017 protected void onSaveInstanceState(Bundle outState) { 1018 outState.putString("mPingHostnameResultV4", mPingHostnameResultV4); 1019 outState.putString("mPingHostnameResultV6", mPingHostnameResultV6); 1020 outState.putString("mHttpClientTestResult", mHttpClientTestResult); 1021 1022 outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult); 1023 outState.putInt("mSelectedPhoneIndex", mPhoneId); 1024 outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex); 1025 1026 } 1027 1028 @Override onCreateOptionsMenu(Menu menu)1029 public boolean onCreateOptionsMenu(Menu menu) { 1030 // Removed "select Radio band". If need it back, use setSystemSelectionChannels() 1031 menu.add(1, MENU_ITEM_VIEW_ADN, 0, 1032 R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback); 1033 menu.add(1, MENU_ITEM_VIEW_FDN, 0, 1034 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback); 1035 menu.add(1, MENU_ITEM_VIEW_SDN, 0, 1036 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback); 1037 if (isImsSupportedOnDevice()) { 1038 menu.add(1, MENU_ITEM_GET_IMS_STATUS, 1039 0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus); 1040 } 1041 menu.add(1, MENU_ITEM_TOGGLE_DATA, 1042 0, R.string.radio_info_data_connection_disable) 1043 .setOnMenuItemClickListener(mToggleData); 1044 return true; 1045 } 1046 1047 @Override onPrepareOptionsMenu(Menu menu)1048 public boolean onPrepareOptionsMenu(Menu menu) { 1049 // Get the TOGGLE DATA menu item in the right state. 1050 MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA); 1051 int state = mTelephonyManager.getDataState(); 1052 boolean visible = true; 1053 1054 switch (state) { 1055 case TelephonyManager.DATA_CONNECTED: 1056 case TelephonyManager.DATA_SUSPENDED: 1057 item.setTitle(R.string.radio_info_data_connection_disable); 1058 break; 1059 case TelephonyManager.DATA_DISCONNECTED: 1060 item.setTitle(R.string.radio_info_data_connection_enable); 1061 break; 1062 default: 1063 visible = false; 1064 break; 1065 } 1066 item.setVisible(visible); 1067 return true; 1068 } 1069 1070 @Override onDestroy()1071 protected void onDestroy() { 1072 log("onDestroy"); 1073 clearOverride(); 1074 super.onDestroy(); 1075 if (mQueuedWork != null) { 1076 mQueuedWork.shutdown(); 1077 } 1078 } 1079 clearOverride()1080 private void clearOverride() { 1081 for (int phoneId = 0; phoneId < sPhoneIndexLabels.length; phoneId++) { 1082 if (mSystemUser) { 1083 mPhone = PhoneFactory.getPhone(phoneId); 1084 } 1085 if (mSimulateOos[mPhoneId]) { 1086 mSimulateOosOnChangeListener.onCheckedChanged(mSimulateOutOfServiceSwitch, false); 1087 } 1088 if (mCarrierSatelliteOriginalBundle[mPhoneId] != null) { 1089 mMockSatelliteListener.onCheckedChanged(mMockSatellite, false); 1090 } 1091 if (mSatelliteDataOriginalBundle[mPhoneId] != null) { 1092 mMockSatelliteDataSwitchListener.onCheckedChanged(mMockSatelliteDataSwitch, false); 1093 mSatelliteDataOriginalBundle[mPhoneId] = null; 1094 } 1095 if (mSelectedSignalStrengthIndex[mPhoneId] > 0) { 1096 mOnMockSignalStrengthSelectedListener.onItemSelected(null, null, 0/*pos*/, 0); 1097 } 1098 if (mSelectedMockDataNetworkTypeIndex[mPhoneId] > 0) { 1099 mOnMockDataNetworkTypeSelectedListener.onItemSelected(null, null, 0/*pos*/, 0); 1100 } 1101 } 1102 } 1103 1104 // returns array of string labels for each phone index. The array index is equal to the phone 1105 // index. getPhoneIndexLabels(TelephonyManager tm)1106 private static String[] getPhoneIndexLabels(TelephonyManager tm) { 1107 int phones = tm.getPhoneCount(); 1108 String[] labels = new String[phones]; 1109 for (int i = 0; i < phones; i++) { 1110 labels[i] = "Phone " + i; 1111 } 1112 return labels; 1113 } 1114 unregisterPhoneStateListener()1115 private void unregisterPhoneStateListener() { 1116 mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); 1117 1118 // clear all fields so they are blank until the next listener event occurs 1119 mOperatorName.setText(""); 1120 mGprsState.setText(""); 1121 mDataNetwork.setText(""); 1122 mDataRawReg.setText(""); 1123 mOverrideNetwork.setText(""); 1124 mVoiceNetwork.setText(""); 1125 mVoiceRawReg.setText(""); 1126 mWlanDataRawReg.setText(""); 1127 mSent.setText(""); 1128 mReceived.setText(""); 1129 mCallState.setText(""); 1130 mMwiValue = false; 1131 mMwi.setText(""); 1132 mCfiValue = false; 1133 mCfi.setText(""); 1134 mCellInfo.setText(""); 1135 mDBm.setText(""); 1136 mGsmState.setText(""); 1137 mRoamingState.setText(""); 1138 mPhyChanConfig.setText(""); 1139 mDownlinkKbps.setText(""); 1140 mUplinkKbps.setText(""); 1141 } 1142 1143 // register mTelephonyCallback for relevant fields using the current TelephonyManager registerPhoneStateListener()1144 private void registerPhoneStateListener() { 1145 mTelephonyCallback = new RadioInfoTelephonyCallback(); 1146 mTelephonyManager.registerTelephonyCallback(new HandlerExecutor(mHandler), 1147 mTelephonyCallback); 1148 } 1149 setNrStatsVisibility(int visibility)1150 private void setNrStatsVisibility(int visibility) { 1151 ((TextView) findViewById(R.id.endc_available_label)).setVisibility(visibility); 1152 mEndcAvailable.setVisibility(visibility); 1153 ((TextView) findViewById(R.id.dcnr_restricted_label)).setVisibility(visibility); 1154 mDcnrRestricted.setVisibility(visibility); 1155 ((TextView) findViewById(R.id.nr_available_label)).setVisibility(visibility); 1156 mNrAvailable.setVisibility(visibility); 1157 ((TextView) findViewById(R.id.nr_state_label)).setVisibility(visibility); 1158 mNrState.setVisibility(visibility); 1159 ((TextView) findViewById(R.id.nr_frequency_label)).setVisibility(visibility); 1160 mNrFrequency.setVisibility(visibility); 1161 ((TextView) findViewById(R.id.network_slicing_config_label)).setVisibility(visibility); 1162 mNetworkSlicingConfig.setVisibility(visibility); 1163 } 1164 updateBandwidths(int dlbw, int ulbw)1165 private void updateBandwidths(int dlbw, int ulbw) { 1166 dlbw = (dlbw < 0 || dlbw == Integer.MAX_VALUE) ? -1 : dlbw; 1167 ulbw = (ulbw < 0 || ulbw == Integer.MAX_VALUE) ? -1 : ulbw; 1168 mDownlinkKbps.setText(String.format("%-5d", dlbw)); 1169 mUplinkKbps.setText(String.format("%-5d", ulbw)); 1170 } 1171 updateSignalStrength(SignalStrength signalStrength)1172 private void updateSignalStrength(SignalStrength signalStrength) { 1173 Resources r = getResources(); 1174 1175 int signalDbm = signalStrength.getDbm(); 1176 1177 int signalAsu = signalStrength.getAsuLevel(); 1178 1179 if (-1 == signalAsu) signalAsu = 0; 1180 1181 mDBm.setText(String.valueOf(signalDbm) + " " 1182 + r.getString(R.string.radioInfo_display_dbm) + " " 1183 + String.valueOf(signalAsu) + " " 1184 + r.getString(R.string.radioInfo_display_asu)); 1185 } 1186 getCellInfoDisplayString(int i)1187 private String getCellInfoDisplayString(int i) { 1188 return (i != Integer.MAX_VALUE) ? Integer.toString(i) : ""; 1189 } 1190 getCellInfoDisplayString(long i)1191 private String getCellInfoDisplayString(long i) { 1192 return (i != Long.MAX_VALUE) ? Long.toString(i) : ""; 1193 } 1194 getConnectionStatusString(CellInfo ci)1195 private String getConnectionStatusString(CellInfo ci) { 1196 String regStr = ""; 1197 String connStatStr = ""; 1198 String connector = ""; 1199 1200 if (ci.isRegistered()) { 1201 regStr = "R"; 1202 } 1203 switch (ci.getCellConnectionStatus()) { 1204 case CellInfo.CONNECTION_PRIMARY_SERVING: connStatStr = "P"; break; 1205 case CellInfo.CONNECTION_SECONDARY_SERVING: connStatStr = "S"; break; 1206 case CellInfo.CONNECTION_NONE: connStatStr = "N"; break; 1207 case CellInfo.CONNECTION_UNKNOWN: /* Field is unsupported */ break; 1208 default: break; 1209 } 1210 if (!TextUtils.isEmpty(regStr) && !TextUtils.isEmpty(connStatStr)) { 1211 connector = "+"; 1212 } 1213 1214 return regStr + connector + connStatStr; 1215 } 1216 buildCdmaInfoString(CellInfoCdma ci)1217 private String buildCdmaInfoString(CellInfoCdma ci) { 1218 CellIdentityCdma cidCdma = ci.getCellIdentity(); 1219 CellSignalStrengthCdma ssCdma = ci.getCellSignalStrength(); 1220 1221 return String.format("%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s", 1222 getConnectionStatusString(ci), 1223 getCellInfoDisplayString(cidCdma.getSystemId()), 1224 getCellInfoDisplayString(cidCdma.getNetworkId()), 1225 getCellInfoDisplayString(cidCdma.getBasestationId()), 1226 getCellInfoDisplayString(ssCdma.getCdmaDbm()), 1227 getCellInfoDisplayString(ssCdma.getCdmaEcio()), 1228 getCellInfoDisplayString(ssCdma.getEvdoDbm()), 1229 getCellInfoDisplayString(ssCdma.getEvdoEcio()), 1230 getCellInfoDisplayString(ssCdma.getEvdoSnr())); 1231 } 1232 buildGsmInfoString(CellInfoGsm ci)1233 private String buildGsmInfoString(CellInfoGsm ci) { 1234 CellIdentityGsm cidGsm = ci.getCellIdentity(); 1235 CellSignalStrengthGsm ssGsm = ci.getCellSignalStrength(); 1236 1237 return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n", 1238 getConnectionStatusString(ci), 1239 getCellInfoDisplayString(cidGsm.getMcc()), 1240 getCellInfoDisplayString(cidGsm.getMnc()), 1241 getCellInfoDisplayString(cidGsm.getLac()), 1242 getCellInfoDisplayString(cidGsm.getCid()), 1243 getCellInfoDisplayString(cidGsm.getArfcn()), 1244 getCellInfoDisplayString(cidGsm.getBsic()), 1245 getCellInfoDisplayString(ssGsm.getDbm())); 1246 } 1247 buildLteInfoString(CellInfoLte ci)1248 private String buildLteInfoString(CellInfoLte ci) { 1249 CellIdentityLte cidLte = ci.getCellIdentity(); 1250 CellSignalStrengthLte ssLte = ci.getCellSignalStrength(); 1251 1252 return String.format( 1253 "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n", 1254 getConnectionStatusString(ci), 1255 getCellInfoDisplayString(cidLte.getMcc()), 1256 getCellInfoDisplayString(cidLte.getMnc()), 1257 getCellInfoDisplayString(cidLte.getTac()), 1258 getCellInfoDisplayString(cidLte.getCi()), 1259 getCellInfoDisplayString(cidLte.getPci()), 1260 getCellInfoDisplayString(cidLte.getEarfcn()), 1261 getCellInfoDisplayString(cidLte.getBandwidth()), 1262 getCellInfoDisplayString(ssLte.getDbm()), 1263 getCellInfoDisplayString(ssLte.getRsrq()), 1264 getCellInfoDisplayString(ssLte.getTimingAdvance())); 1265 } 1266 buildNrInfoString(CellInfoNr ci)1267 private String buildNrInfoString(CellInfoNr ci) { 1268 CellIdentityNr cidNr = (CellIdentityNr) ci.getCellIdentity(); 1269 CellSignalStrengthNr ssNr = (CellSignalStrengthNr) ci.getCellSignalStrength(); 1270 1271 return String.format( 1272 "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s\n", 1273 getConnectionStatusString(ci), 1274 cidNr.getMccString(), 1275 cidNr.getMncString(), 1276 getCellInfoDisplayString(cidNr.getTac()), 1277 getCellInfoDisplayString(cidNr.getNci()), 1278 getCellInfoDisplayString(cidNr.getPci()), 1279 getCellInfoDisplayString(cidNr.getNrarfcn()), 1280 getCellInfoDisplayString(ssNr.getSsRsrp()), 1281 getCellInfoDisplayString(ssNr.getSsRsrq())); 1282 } 1283 buildWcdmaInfoString(CellInfoWcdma ci)1284 private String buildWcdmaInfoString(CellInfoWcdma ci) { 1285 CellIdentityWcdma cidWcdma = ci.getCellIdentity(); 1286 CellSignalStrengthWcdma ssWcdma = ci.getCellSignalStrength(); 1287 1288 return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n", 1289 getConnectionStatusString(ci), 1290 getCellInfoDisplayString(cidWcdma.getMcc()), 1291 getCellInfoDisplayString(cidWcdma.getMnc()), 1292 getCellInfoDisplayString(cidWcdma.getLac()), 1293 getCellInfoDisplayString(cidWcdma.getCid()), 1294 getCellInfoDisplayString(cidWcdma.getUarfcn()), 1295 getCellInfoDisplayString(cidWcdma.getPsc()), 1296 getCellInfoDisplayString(ssWcdma.getDbm())); 1297 } 1298 buildCellInfoString(List<CellInfo> arrayCi)1299 private String buildCellInfoString(List<CellInfo> arrayCi) { 1300 String value = new String(); 1301 StringBuilder cdmaCells = new StringBuilder(), 1302 gsmCells = new StringBuilder(), 1303 lteCells = new StringBuilder(), 1304 wcdmaCells = new StringBuilder(), 1305 nrCells = new StringBuilder(); 1306 1307 if (arrayCi != null) { 1308 for (CellInfo ci : arrayCi) { 1309 1310 if (ci instanceof CellInfoLte) { 1311 lteCells.append(buildLteInfoString((CellInfoLte) ci)); 1312 } else if (ci instanceof CellInfoWcdma) { 1313 wcdmaCells.append(buildWcdmaInfoString((CellInfoWcdma) ci)); 1314 } else if (ci instanceof CellInfoGsm) { 1315 gsmCells.append(buildGsmInfoString((CellInfoGsm) ci)); 1316 } else if (ci instanceof CellInfoCdma) { 1317 cdmaCells.append(buildCdmaInfoString((CellInfoCdma) ci)); 1318 } else if (ci instanceof CellInfoNr) { 1319 nrCells.append(buildNrInfoString((CellInfoNr) ci)); 1320 } 1321 } 1322 if (nrCells.length() != 0) { 1323 value += String.format( 1324 "NR\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s" 1325 + " %-6.6s %-4.4s %-4.4s\n", 1326 "SRV", "MCC", "MNC", "TAC", "NCI", "PCI", 1327 "NRARFCN", "SS-RSRP", "SS-RSRQ"); 1328 value += nrCells.toString(); 1329 } 1330 1331 if (lteCells.length() != 0) { 1332 value += String.format( 1333 "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s" 1334 + " %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n", 1335 "SRV", "MCC", "MNC", "TAC", "CID", "PCI", 1336 "EARFCN", "BW", "RSRP", "RSRQ", "TA"); 1337 value += lteCells.toString(); 1338 } 1339 if (wcdmaCells.length() != 0) { 1340 value += String.format( 1341 "WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n", 1342 "SRV", "MCC", "MNC", "LAC", "CID", "UARFCN", "PSC", "RSCP"); 1343 value += wcdmaCells.toString(); 1344 } 1345 if (gsmCells.length() != 0) { 1346 value += String.format( 1347 "GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n", 1348 "SRV", "MCC", "MNC", "LAC", "CID", "ARFCN", "BSIC", "RSSI"); 1349 value += gsmCells.toString(); 1350 } 1351 if (cdmaCells.length() != 0) { 1352 value += String.format( 1353 "CDMA/EVDO\n%-3.3s %-5.5s %-5.5s %-5.5s" 1354 + " %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s\n", 1355 "SRV", "SID", "NID", "BSID", 1356 "C-RSSI", "C-ECIO", "E-RSSI", "E-ECIO", "E-SNR"); 1357 value += cdmaCells.toString(); 1358 } 1359 } else { 1360 value = "unknown"; 1361 } 1362 1363 return value.toString(); 1364 } 1365 updateCellInfo(List<CellInfo> arrayCi)1366 private void updateCellInfo(List<CellInfo> arrayCi) { 1367 mCellInfo.setText(buildCellInfoString(arrayCi)); 1368 } 1369 updateSubscriptionIds()1370 private void updateSubscriptionIds() { 1371 mSubscriptionId.setText(String.format(Locale.ROOT, "%d", mSubId)); 1372 mDds.setText(Integer.toString(SubscriptionManager.getDefaultDataSubscriptionId())); 1373 } 1374 updateMessageWaiting()1375 private void updateMessageWaiting() { 1376 mMwi.setText(String.valueOf(mMwiValue)); 1377 } 1378 updateCallRedirect()1379 private void updateCallRedirect() { 1380 mCfi.setText(String.valueOf(mCfiValue)); 1381 } 1382 1383 updateServiceState(ServiceState serviceState)1384 private void updateServiceState(ServiceState serviceState) { 1385 if (!SubscriptionManager.isValidSubscriptionId(mSubId)) { 1386 // When SIM is absent, we can't listen service state change from absent slot. Need 1387 // explicitly get service state from the specific slot. 1388 serviceState = mTelephonyManager.getServiceStateForSlot(mPhoneId); 1389 } 1390 log("Update service state " + serviceState); 1391 int state = serviceState.getState(); 1392 Resources r = getResources(); 1393 String display = r.getString(R.string.radioInfo_unknown); 1394 1395 switch (state) { 1396 case ServiceState.STATE_IN_SERVICE: 1397 display = r.getString(R.string.radioInfo_service_in); 1398 break; 1399 case ServiceState.STATE_OUT_OF_SERVICE: 1400 display = r.getString(R.string.radioInfo_service_out); 1401 break; 1402 case ServiceState.STATE_EMERGENCY_ONLY: 1403 display = r.getString(R.string.radioInfo_service_emergency); 1404 break; 1405 case ServiceState.STATE_POWER_OFF: 1406 display = r.getString(R.string.radioInfo_service_off); 1407 break; 1408 } 1409 1410 mGsmState.setText(display); 1411 1412 if (serviceState.getRoaming()) { 1413 mRoamingState.setText(R.string.radioInfo_roaming_in); 1414 } else { 1415 mRoamingState.setText(R.string.radioInfo_roaming_not); 1416 } 1417 1418 mOperatorName.setText(serviceState.getOperatorAlphaLong()); 1419 } 1420 updatePhoneState(int state)1421 private void updatePhoneState(int state) { 1422 Resources r = getResources(); 1423 String display = r.getString(R.string.radioInfo_unknown); 1424 1425 switch (state) { 1426 case TelephonyManager.CALL_STATE_IDLE: 1427 display = r.getString(R.string.radioInfo_phone_idle); 1428 break; 1429 case TelephonyManager.CALL_STATE_RINGING: 1430 display = r.getString(R.string.radioInfo_phone_ringing); 1431 break; 1432 case TelephonyManager.CALL_STATE_OFFHOOK: 1433 display = r.getString(R.string.radioInfo_phone_offhook); 1434 break; 1435 } 1436 1437 mCallState.setText(display); 1438 } 1439 updateDataState()1440 private void updateDataState() { 1441 int state = mTelephonyManager.getDataState(); 1442 Resources r = getResources(); 1443 String display = r.getString(R.string.radioInfo_unknown); 1444 1445 if (SubscriptionManager.isValidSubscriptionId(mSubId)) { 1446 switch (state) { 1447 case TelephonyManager.DATA_CONNECTED: 1448 display = r.getString(R.string.radioInfo_data_connected); 1449 break; 1450 case TelephonyManager.DATA_CONNECTING: 1451 display = r.getString(R.string.radioInfo_data_connecting); 1452 break; 1453 case TelephonyManager.DATA_DISCONNECTED: 1454 display = r.getString(R.string.radioInfo_data_disconnected); 1455 break; 1456 case TelephonyManager.DATA_SUSPENDED: 1457 display = r.getString(R.string.radioInfo_data_suspended); 1458 break; 1459 } 1460 } else { 1461 display = r.getString(R.string.radioInfo_data_disconnected); 1462 } 1463 1464 mGprsState.setText(display); 1465 } 1466 updateNetworkType()1467 private void updateNetworkType() { 1468 SubscriptionManager mSm = getSystemService(SubscriptionManager.class); 1469 if (SubscriptionManager.isValidPhoneId(mPhoneId) 1470 && mSm.isActiveSubscriptionId(mSubId)) { 1471 mDataNetwork.setText(ServiceState.rilRadioTechnologyToString( 1472 mTelephonyManager.getServiceStateForSlot(mPhoneId) 1473 .getRilDataRadioTechnology())); 1474 mVoiceNetwork.setText(ServiceState.rilRadioTechnologyToString( 1475 mTelephonyManager.getServiceStateForSlot(mPhoneId) 1476 .getRilVoiceRadioTechnology())); 1477 int overrideNetwork = (mDisplayInfo != null 1478 && SubscriptionManager.isValidSubscriptionId(mSubId)) 1479 ? mDisplayInfo.getOverrideNetworkType() 1480 : TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 1481 mOverrideNetwork.setText( 1482 TelephonyDisplayInfo.overrideNetworkTypeToString(overrideNetwork)); 1483 } 1484 } 1485 getRawRegistrationStateText(ServiceState ss, int domain, int transportType)1486 private String getRawRegistrationStateText(ServiceState ss, int domain, int transportType) { 1487 if (ss != null) { 1488 NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(domain, transportType); 1489 if (nri != null) { 1490 return NetworkRegistrationInfo.registrationStateToString( 1491 nri.getNetworkRegistrationState()) 1492 + (nri.isEmergencyEnabled() ? "_EM" : ""); 1493 } 1494 } 1495 return ""; 1496 } 1497 updateRawRegistrationState(ServiceState serviceState)1498 private void updateRawRegistrationState(ServiceState serviceState) { 1499 ServiceState ss = serviceState; 1500 ss = mTelephonyManager.getServiceStateForSlot(mPhoneId); 1501 1502 mVoiceRawReg.setText(getRawRegistrationStateText(ss, NetworkRegistrationInfo.DOMAIN_CS, 1503 AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); 1504 mDataRawReg.setText(getRawRegistrationStateText(ss, NetworkRegistrationInfo.DOMAIN_PS, 1505 AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); 1506 mWlanDataRawReg.setText(getRawRegistrationStateText(ss, NetworkRegistrationInfo.DOMAIN_PS, 1507 AccessNetworkConstants.TRANSPORT_TYPE_WLAN)); 1508 } 1509 updateNrStats()1510 private void updateNrStats() { 1511 if ((mTelephonyManager.getSupportedRadioAccessFamily() 1512 & TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) { 1513 return; 1514 } 1515 ServiceState ss = mTelephonyManager.getServiceStateForSlot(mPhoneId); 1516 if (ss != null) { 1517 NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo( 1518 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1519 if (nri != null) { 1520 DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); 1521 if (dsri != null) { 1522 mEndcAvailable.setText(String.valueOf(dsri.isEnDcAvailable)); 1523 mDcnrRestricted.setText(String.valueOf(dsri.isDcNrRestricted)); 1524 mNrAvailable.setText(String.valueOf(dsri.isNrAvailable)); 1525 } 1526 } 1527 mNrState.setText(NetworkRegistrationInfo.nrStateToString(ss.getNrState())); 1528 mNrFrequency.setText(ServiceState.frequencyRangeToString(ss.getNrFrequencyRange())); 1529 } else { 1530 Log.e(TAG, "Clear Nr stats by null service state"); 1531 mEndcAvailable.setText(""); 1532 mDcnrRestricted.setText(""); 1533 mNrAvailable.setText(""); 1534 mNrState.setText(""); 1535 mNrFrequency.setText(""); 1536 } 1537 1538 CompletableFuture<NetworkSlicingConfig> resultFuture = new CompletableFuture<>(); 1539 mTelephonyManager.getNetworkSlicingConfiguration(Runnable::run, resultFuture::complete); 1540 try { 1541 NetworkSlicingConfig networkSlicingConfig = 1542 resultFuture.get(DEFAULT_TIMEOUT_MS, MILLISECONDS); 1543 mNetworkSlicingConfig.setText(networkSlicingConfig.toString()); 1544 } catch (ExecutionException | InterruptedException | TimeoutException e) { 1545 loge("Unable to get slicing config: " + e); 1546 mNetworkSlicingConfig.setText("Unable to get slicing config."); 1547 } 1548 1549 } 1550 updateProperties()1551 private void updateProperties() { 1552 String s; 1553 Resources r = getResources(); 1554 1555 s = mTelephonyManager.getImei(mPhoneId); 1556 mDeviceId.setText(s); 1557 1558 s = mTelephonyManager.getSubscriberId(); 1559 if (s == null || !SubscriptionManager.isValidSubscriptionId(mSubId)) { 1560 s = r.getString(R.string.radioInfo_unknown); 1561 } 1562 1563 mSubscriberId.setText(s); 1564 1565 SubscriptionManager subMgr = getSystemService(SubscriptionManager.class); 1566 int subId = mSubId; 1567 s = subMgr.getPhoneNumber(subId) 1568 + " { CARRIER:" 1569 + subMgr.getPhoneNumber(subId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER) 1570 + ", UICC:" 1571 + subMgr.getPhoneNumber(subId, SubscriptionManager.PHONE_NUMBER_SOURCE_UICC) 1572 + ", IMS:" 1573 + subMgr.getPhoneNumber(subId, SubscriptionManager.PHONE_NUMBER_SOURCE_IMS) 1574 + " }"; 1575 mLine1Number.setText(s); 1576 } 1577 updateDataStats2()1578 private void updateDataStats2() { 1579 Resources r = getResources(); 1580 1581 long txPackets = TrafficStats.getMobileTxPackets(); 1582 long rxPackets = TrafficStats.getMobileRxPackets(); 1583 long txBytes = TrafficStats.getMobileTxBytes(); 1584 long rxBytes = TrafficStats.getMobileRxBytes(); 1585 1586 String packets = r.getString(R.string.radioInfo_display_packets); 1587 String bytes = r.getString(R.string.radioInfo_display_bytes); 1588 1589 mSent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes); 1590 mReceived.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes); 1591 } 1592 updateEuiccInfo()1593 private void updateEuiccInfo() { 1594 final Runnable setEuiccInfo = new Runnable() { 1595 public void run() { 1596 mEuiccInfo.setText(mEuiccInfoResult); 1597 } 1598 }; 1599 1600 mQueuedWork.execute(new Runnable() { 1601 @Override 1602 public void run() { 1603 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_EUICC)) { 1604 mEuiccInfoResult = "Euicc Feature is disabled"; 1605 } else if (mEuiccManager == null || !mEuiccManager.isEnabled()) { 1606 mEuiccInfoResult = "EuiccManager is not enabled"; 1607 } else { 1608 try { 1609 mEuiccInfoResult = " { Available memory in bytes:" 1610 + mEuiccManager.getAvailableMemoryInBytes() 1611 + " }"; 1612 } catch (Exception e) { 1613 mEuiccInfoResult = e.getMessage(); 1614 } 1615 } 1616 mHandler.post(setEuiccInfo); 1617 } 1618 }); 1619 } 1620 1621 /** 1622 * Ping a host name 1623 */ pingHostname()1624 private void pingHostname() { 1625 try { 1626 try { 1627 Process p4 = Runtime.getRuntime().exec("ping -c 1 www.google.com"); 1628 int status4 = p4.waitFor(); 1629 if (status4 == 0) { 1630 mPingHostnameResultV4 = "Pass"; 1631 } else { 1632 mPingHostnameResultV4 = String.format("Fail(%d)", status4); 1633 } 1634 } catch (IOException e) { 1635 mPingHostnameResultV4 = "Fail: IOException"; 1636 } 1637 try { 1638 Process p6 = Runtime.getRuntime().exec("ping6 -c 1 www.google.com"); 1639 int status6 = p6.waitFor(); 1640 if (status6 == 0) { 1641 mPingHostnameResultV6 = "Pass"; 1642 } else { 1643 mPingHostnameResultV6 = String.format("Fail(%d)", status6); 1644 } 1645 } catch (IOException e) { 1646 mPingHostnameResultV6 = "Fail: IOException"; 1647 } 1648 } catch (InterruptedException e) { 1649 mPingHostnameResultV4 = mPingHostnameResultV6 = "Fail: InterruptedException"; 1650 } 1651 } 1652 1653 /** 1654 * This function checks for basic functionality of HTTP Client. 1655 */ httpClientTest()1656 private void httpClientTest() { 1657 HttpURLConnection urlConnection = null; 1658 try { 1659 // TODO: Hardcoded for now, make it UI configurable 1660 URL url = new URL("https://www.google.com"); 1661 urlConnection = (HttpURLConnection) url.openConnection(); 1662 if (urlConnection.getResponseCode() == 200) { 1663 mHttpClientTestResult = "Pass"; 1664 } else { 1665 mHttpClientTestResult = "Fail: Code: " + urlConnection.getResponseMessage(); 1666 } 1667 } catch (IOException e) { 1668 mHttpClientTestResult = "Fail: IOException"; 1669 } finally { 1670 if (urlConnection != null) { 1671 urlConnection.disconnect(); 1672 } 1673 } 1674 } 1675 refreshSmsc()1676 private void refreshSmsc() { 1677 mQueuedWork.execute(() -> { 1678 if (mSystemUser) { 1679 mPhone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE)); 1680 } 1681 }); 1682 } 1683 updateAllCellInfo()1684 private void updateAllCellInfo() { 1685 1686 mCellInfo.setText(""); 1687 1688 final Runnable updateAllCellInfoResults = new Runnable() { 1689 public void run() { 1690 updateCellInfo(mCellInfoResult); 1691 } 1692 }; 1693 1694 mQueuedWork.execute(new Runnable() { 1695 @Override 1696 public void run() { 1697 mCellInfoResult = mTelephonyManager.getAllCellInfo(); 1698 1699 mHandler.post(updateAllCellInfoResults); 1700 } 1701 }); 1702 } 1703 updatePingState()1704 private void updatePingState() { 1705 // Set all to unknown since the threads will take a few secs to update. 1706 mPingHostnameResultV4 = getResources().getString(R.string.radioInfo_unknown); 1707 mPingHostnameResultV6 = getResources().getString(R.string.radioInfo_unknown); 1708 mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown); 1709 1710 mPingHostnameV4.setText(mPingHostnameResultV4); 1711 mPingHostnameV6.setText(mPingHostnameResultV6); 1712 mHttpClientTest.setText(mHttpClientTestResult); 1713 1714 final Runnable updatePingResults = new Runnable() { 1715 public void run() { 1716 mPingHostnameV4.setText(mPingHostnameResultV4); 1717 mPingHostnameV6.setText(mPingHostnameResultV6); 1718 mHttpClientTest.setText(mHttpClientTestResult); 1719 } 1720 }; 1721 1722 Thread hostname = new Thread() { 1723 @Override 1724 public void run() { 1725 pingHostname(); 1726 mHandler.post(updatePingResults); 1727 } 1728 }; 1729 hostname.start(); 1730 1731 Thread httpClient = new Thread() { 1732 @Override 1733 public void run() { 1734 httpClientTest(); 1735 mHandler.post(updatePingResults); 1736 } 1737 }; 1738 httpClient.start(); 1739 } 1740 1741 private MenuItem.OnMenuItemClickListener mViewADNCallback = 1742 new MenuItem.OnMenuItemClickListener() { 1743 public boolean onMenuItemClick(MenuItem item) { 1744 Intent intent = new Intent(Intent.ACTION_VIEW); 1745 // XXX We need to specify the component here because if we don't 1746 // the activity manager will try to resolve the type by calling 1747 // the content provider, which causes it to be loaded in a process 1748 // other than the Dialer process, which causes a lot of stuff to 1749 // break. 1750 intent.setClassName("com.android.phone", "com.android.phone.SimContacts"); 1751 startActivityAsUser(intent, UserHandle.CURRENT); 1752 return true; 1753 } 1754 }; 1755 1756 private MenuItem.OnMenuItemClickListener mViewFDNCallback = 1757 new MenuItem.OnMenuItemClickListener() { 1758 public boolean onMenuItemClick(MenuItem item) { 1759 Intent intent = new Intent(Intent.ACTION_VIEW); 1760 // XXX We need to specify the component here because if we don't 1761 // the activity manager will try to resolve the type by calling 1762 // the content provider, which causes it to be loaded in a process 1763 // other than the Dialer process, which causes a lot of stuff to 1764 // break. 1765 intent.setClassName("com.android.phone", 1766 "com.android.phone.settings.fdn.FdnList"); 1767 startActivityAsUser(intent, UserHandle.CURRENT); 1768 return true; 1769 } 1770 }; 1771 1772 private MenuItem.OnMenuItemClickListener mViewSDNCallback = 1773 new MenuItem.OnMenuItemClickListener() { 1774 public boolean onMenuItemClick(MenuItem item) { 1775 Intent intent = new Intent( 1776 Intent.ACTION_VIEW, Uri.parse("content://icc/sdn")); 1777 // XXX We need to specify the component here because if we don't 1778 // the activity manager will try to resolve the type by calling 1779 // the content provider, which causes it to be loaded in a process 1780 // other than the Dialer process, which causes a lot of stuff to 1781 // break. 1782 intent.setClassName("com.android.phone", "com.android.phone.ADNList"); 1783 startActivityAsUser(intent, UserHandle.CURRENT); 1784 return true; 1785 } 1786 }; 1787 1788 private MenuItem.OnMenuItemClickListener mGetImsStatus = 1789 new MenuItem.OnMenuItemClickListener() { 1790 public boolean onMenuItemClick(MenuItem item) { 1791 boolean isSimValid = SubscriptionManager.isValidSubscriptionId(mSubId); 1792 boolean isImsRegistered = isSimValid && mTelephonyManager.isImsRegistered(); 1793 boolean availableVolte = false; 1794 boolean availableWfc = false; 1795 boolean availableVt = false; 1796 AtomicBoolean availableUt = new AtomicBoolean(false); 1797 1798 if (isSimValid) { 1799 ImsMmTelManager imsMmTelManager = mImsManager.getImsMmTelManager(mSubId); 1800 availableVolte = isVoiceServiceAvailable(imsMmTelManager); 1801 availableVt = isVideoServiceAvailable(imsMmTelManager); 1802 availableWfc = isWfcServiceAvailable(imsMmTelManager); 1803 CountDownLatch latch = new CountDownLatch(1); 1804 try { 1805 HandlerThread handlerThread = new HandlerThread("RadioInfo"); 1806 handlerThread.start(); 1807 imsMmTelManager.isSupported( 1808 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT, 1809 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 1810 handlerThread.getThreadExecutor(), (result) -> { 1811 latch.countDown(); 1812 availableUt.set(result); 1813 }); 1814 latch.await(2, TimeUnit.SECONDS); 1815 handlerThread.quit(); 1816 } catch (Exception e) { 1817 loge("Failed to get UT state."); 1818 } 1819 } 1820 1821 final String imsRegString = isImsRegistered 1822 ? getString(R.string.radio_info_ims_reg_status_registered) 1823 : getString(R.string.radio_info_ims_reg_status_not_registered); 1824 1825 final String available = getString( 1826 R.string.radio_info_ims_feature_status_available); 1827 final String unavailable = getString( 1828 R.string.radio_info_ims_feature_status_unavailable); 1829 1830 String imsStatus = getString(R.string.radio_info_ims_reg_status, 1831 imsRegString, 1832 availableVolte ? available : unavailable, 1833 availableWfc ? available : unavailable, 1834 availableVt ? available : unavailable, 1835 availableUt.get() ? available : unavailable); 1836 1837 AlertDialog imsDialog = new AlertDialog.Builder(RadioInfo.this) 1838 .setMessage(imsStatus) 1839 .setTitle(getString(R.string.radio_info_ims_reg_status_title)) 1840 .create(); 1841 1842 imsDialog.show(); 1843 1844 return true; 1845 } 1846 }; 1847 1848 private MenuItem.OnMenuItemClickListener mToggleData = 1849 new MenuItem.OnMenuItemClickListener() { 1850 public boolean onMenuItemClick(MenuItem item) { 1851 int state = mTelephonyManager.getDataState(); 1852 switch (state) { 1853 case TelephonyManager.DATA_CONNECTED: 1854 mTelephonyManager.setDataEnabled(false); 1855 break; 1856 case TelephonyManager.DATA_DISCONNECTED: 1857 mTelephonyManager.setDataEnabled(true); 1858 break; 1859 default: 1860 // do nothing 1861 break; 1862 } 1863 return true; 1864 } 1865 }; 1866 isRadioOn()1867 private boolean isRadioOn() { 1868 return mTelephonyManager.getRadioPowerState() == TelephonyManager.RADIO_POWER_ON; 1869 } 1870 updateRadioPowerState()1871 private void updateRadioPowerState() { 1872 //delightful hack to prevent on-checked-changed calls from 1873 //actually forcing the radio preference to its transient/current value. 1874 mRadioPowerOnSwitch.setOnCheckedChangeListener(null); 1875 mRadioPowerOnSwitch.setChecked(isRadioOn()); 1876 mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener); 1877 } 1878 setImsVolteProvisionedState(boolean state)1879 private void setImsVolteProvisionedState(boolean state) { 1880 Log.d(TAG, "setImsVolteProvisioned state: " + ((state) ? "on" : "off")); 1881 setImsConfigProvisionedState(CAPABILITY_TYPE_VOICE, 1882 REGISTRATION_TECH_LTE, state); 1883 } 1884 setImsVtProvisionedState(boolean state)1885 private void setImsVtProvisionedState(boolean state) { 1886 Log.d(TAG, "setImsVtProvisioned() state: " + ((state) ? "on" : "off")); 1887 setImsConfigProvisionedState(CAPABILITY_TYPE_VIDEO, 1888 REGISTRATION_TECH_LTE, state); 1889 } 1890 setImsWfcProvisionedState(boolean state)1891 private void setImsWfcProvisionedState(boolean state) { 1892 Log.d(TAG, "setImsWfcProvisioned() state: " + ((state) ? "on" : "off")); 1893 setImsConfigProvisionedState(CAPABILITY_TYPE_VOICE, 1894 REGISTRATION_TECH_IWLAN, state); 1895 } 1896 setEabProvisionedState(boolean state)1897 private void setEabProvisionedState(boolean state) { 1898 Log.d(TAG, "setEabProvisioned() state: " + ((state) ? "on" : "off")); 1899 setRcsConfigProvisionedState(ImsRcsManager.CAPABILITY_TYPE_PRESENCE_UCE, 1900 REGISTRATION_TECH_LTE, state); 1901 } 1902 setImsConfigProvisionedState(int capability, int tech, boolean state)1903 private void setImsConfigProvisionedState(int capability, int tech, boolean state) { 1904 if (mProvisioningManager != null) { 1905 mQueuedWork.execute(new Runnable() { 1906 public void run() { 1907 try { 1908 mProvisioningManager.setProvisioningStatusForCapability( 1909 capability, tech, state); 1910 } catch (RuntimeException e) { 1911 Log.e(TAG, "setImsConfigProvisioned() exception:", e); 1912 } 1913 } 1914 }); 1915 } 1916 } 1917 setRcsConfigProvisionedState(int capability, int tech, boolean state)1918 private void setRcsConfigProvisionedState(int capability, int tech, boolean state) { 1919 if (mProvisioningManager != null) { 1920 mQueuedWork.execute(new Runnable() { 1921 public void run() { 1922 try { 1923 mProvisioningManager.setRcsProvisioningStatusForCapability( 1924 capability, tech, state); 1925 } catch (RuntimeException e) { 1926 Log.e(TAG, "setRcsConfigProvisioned() exception:", e); 1927 } 1928 } 1929 }); 1930 } 1931 } 1932 isImsVolteProvisioningRequired()1933 private boolean isImsVolteProvisioningRequired() { 1934 return isImsConfigProvisioningRequired( 1935 CAPABILITY_TYPE_VOICE, 1936 REGISTRATION_TECH_LTE); 1937 } 1938 isImsVtProvisioningRequired()1939 private boolean isImsVtProvisioningRequired() { 1940 return isImsConfigProvisioningRequired( 1941 CAPABILITY_TYPE_VIDEO, 1942 REGISTRATION_TECH_LTE); 1943 } 1944 isImsWfcProvisioningRequired()1945 private boolean isImsWfcProvisioningRequired() { 1946 return isImsConfigProvisioningRequired( 1947 CAPABILITY_TYPE_VOICE, 1948 REGISTRATION_TECH_IWLAN); 1949 } 1950 isEabProvisioningRequired()1951 private boolean isEabProvisioningRequired() { 1952 return isRcsConfigProvisioningRequired( 1953 ImsRcsManager.CAPABILITY_TYPE_PRESENCE_UCE, 1954 REGISTRATION_TECH_LTE); 1955 } 1956 isImsConfigProvisioningRequired(int capability, int tech)1957 private boolean isImsConfigProvisioningRequired(int capability, int tech) { 1958 if (mProvisioningManager != null) { 1959 try { 1960 return mProvisioningManager.isProvisioningRequiredForCapability( 1961 capability, tech); 1962 } catch (RuntimeException e) { 1963 Log.e(TAG, "isImsConfigProvisioningRequired() exception:", e); 1964 } 1965 } 1966 1967 return false; 1968 } 1969 isRcsConfigProvisioningRequired(int capability, int tech)1970 private boolean isRcsConfigProvisioningRequired(int capability, int tech) { 1971 if (mProvisioningManager != null) { 1972 try { 1973 return mProvisioningManager.isRcsProvisioningRequiredForCapability( 1974 capability, tech); 1975 } catch (RuntimeException e) { 1976 Log.e(TAG, "isRcsConfigProvisioningRequired() exception:", e); 1977 } 1978 } 1979 1980 return false; 1981 } 1982 1983 OnCheckedChangeListener mRadioPowerOnChangeListener = new OnCheckedChangeListener() { 1984 @Override 1985 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 1986 // TODO: b/145681511. Within current design, radio power on all of the phones need 1987 // to be controlled at the same time. 1988 Phone[] phones = PhoneFactory.getPhones(); 1989 if (phones == null) { 1990 return; 1991 } 1992 log("toggle radio power: phone*" + phones.length + " " + (isRadioOn() ? "on" : "off")); 1993 for (int phoneIndex = 0; phoneIndex < phones.length; phoneIndex++) { 1994 if (phones[phoneIndex] != null) { 1995 phones[phoneIndex].setRadioPower(isChecked); 1996 } 1997 } 1998 } 1999 }; 2000 2001 private final OnCheckedChangeListener mSimulateOosOnChangeListener = (bv, isChecked) -> { 2002 Intent intent = new Intent("com.android.internal.telephony.TestServiceState"); 2003 if (isChecked) { 2004 log("Send OOS override broadcast intent."); 2005 intent.putExtra("data_reg_state", 1); 2006 mSimulateOos[mPhoneId] = true; 2007 } else { 2008 log("Remove OOS override."); 2009 intent.putExtra("action", "reset"); 2010 mSimulateOos[mPhoneId] = false; 2011 } 2012 mPhone.getTelephonyTester().setServiceStateTestIntent(intent); 2013 }; 2014 2015 private static final int SATELLITE_CHANNEL = 8665; 2016 private final OnCheckedChangeListener mForceSatelliteChannelOnChangeListener = 2017 (buttonView, isChecked) -> { 2018 2019 if (!isValidSubscription(mSubId)) { 2020 loge("Force satellite channel invalid subId " + mSubId); 2021 return; 2022 } 2023 if (getCarrierConfig() == null) { 2024 loge("Force satellite channel cm == null"); 2025 return; 2026 } 2027 TelephonyManager tm = mTelephonyManager.createForSubscriptionId(mSubId); 2028 // To be used in thread in case mPhone changes. 2029 int subId = mSubId; 2030 int phoneId = mPhoneId; 2031 if (isChecked) { 2032 (new Thread(() -> { 2033 // Override carrier config 2034 PersistableBundle originalBundle = getCarrierConfig().getConfigForSubId( 2035 subId, 2036 KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, 2037 KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, 2038 CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL 2039 ); 2040 PersistableBundle overrideBundle = new PersistableBundle(); 2041 overrideBundle.putBoolean( 2042 KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); 2043 overrideBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true); 2044 overrideBundle.putBoolean(CarrierConfigManager 2045 .KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, true); 2046 2047 // Set only allow LTE network type 2048 try { 2049 tm.setAllowedNetworkTypesForReason( 2050 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_TEST, 2051 RadioAccessFamily.getRafFromNetworkType( 2052 RILConstants.NETWORK_MODE_LTE_ONLY)); 2053 log("Force satellite channel set to LTE only"); 2054 } catch (Exception e) { 2055 loge("Force satellite channel failed to set network type to LTE " + e); 2056 return; 2057 } 2058 2059 // Set force channel selection 2060 List<RadioAccessSpecifier> mock = List.of( 2061 new RadioAccessSpecifier( 2062 AccessNetworkConstants.AccessNetworkType.EUTRAN, 2063 new int[]{AccessNetworkConstants.EutranBand.BAND_25}, 2064 new int[]{SATELLITE_CHANNEL})); 2065 try { 2066 log("Force satellite channel new channels " + mock); 2067 tm.setSystemSelectionChannels(mock); 2068 } catch (Exception e) { 2069 loge("Force satellite channel failed to set channels " + e); 2070 return; 2071 } 2072 log("Force satellite channel new config " + overrideBundle); 2073 getCarrierConfig().overrideConfig(subId, overrideBundle, false); 2074 2075 mOriginalSystemChannels[phoneId] = originalBundle; 2076 log("Force satellite channel old " + mock + originalBundle); 2077 })).start(); 2078 } else { 2079 (new Thread(() -> { 2080 try { 2081 tm.setSystemSelectionChannels( 2082 Collections.emptyList() /* isSpecifyChannels false */); 2083 log("Force satellite channel successfully cleared channels "); 2084 tm.setAllowedNetworkTypesForReason( 2085 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_TEST, 2086 TelephonyManager.getAllNetworkTypesBitmask()); 2087 log("Force satellite channel successfully reset network type to " 2088 + TelephonyManager.getAllNetworkTypesBitmask()); 2089 PersistableBundle original = mOriginalSystemChannels[phoneId]; 2090 if (original != null) { 2091 getCarrierConfig().overrideConfig(subId, original, false); 2092 log("Force satellite channel successfully restored config to " 2093 + original); 2094 mOriginalSystemChannels[phoneId] = null; 2095 } 2096 } catch (Exception e) { 2097 loge("Force satellite channel: Can't clear mock " + e); 2098 } 2099 })).start(); 2100 } 2101 }; 2102 updateSatelliteChannelDisplay(int phoneId)2103 private void updateSatelliteChannelDisplay(int phoneId) { 2104 if (mEnforceSatelliteChannel.isChecked()) return; 2105 // Assume in testing mode 2106 (new Thread(() -> { 2107 TelephonyManager tm = mTelephonyManager.createForSubscriptionId( 2108 SubscriptionManager.getSubscriptionId(phoneId)); 2109 try { 2110 List<RadioAccessSpecifier> channels = tm.getSystemSelectionChannels(); 2111 long networkTypeBitMask = tm.getAllowedNetworkTypesForReason( 2112 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_TEST); 2113 long lteNetworkBitMask = RadioAccessFamily.getRafFromNetworkType( 2114 RILConstants.NETWORK_MODE_LTE_ONLY); 2115 mHandler.post(() -> { 2116 log("Force satellite get channel " + channels 2117 + " get networkTypeBitMask " + networkTypeBitMask 2118 + " lte " + lteNetworkBitMask); 2119 // if SATELLITE_CHANNEL is the current channel 2120 mEnforceSatelliteChannel.setChecked(channels.stream().filter(specifier -> 2121 specifier.getRadioAccessNetwork() 2122 == AccessNetworkConstants.AccessNetworkType.EUTRAN) 2123 .flatMapToInt(specifier -> Arrays.stream(specifier.getChannels())) 2124 .anyMatch(channel -> channel == SATELLITE_CHANNEL) 2125 // OR ALLOWED_NETWORK_TYPES_REASON_TEST is LTE only. 2126 || (networkTypeBitMask & lteNetworkBitMask) == networkTypeBitMask); 2127 }); 2128 } catch (Exception e) { 2129 loge("updateSatelliteChannelDisplay " + e); 2130 } 2131 })).start(); 2132 } 2133 2134 /** 2135 * Method will create the PersistableBundle and pack the satellite services like 2136 * SMS, MMS, EMERGENCY CALL, DATA in it. 2137 * 2138 * @return PersistableBundle 2139 */ getSatelliteServicesBundleForOperatorPlmn( PersistableBundle originalBundle)2140 public PersistableBundle getSatelliteServicesBundleForOperatorPlmn( 2141 PersistableBundle originalBundle) { 2142 String plmn = mTelephonyManager.getNetworkOperatorForPhone(mPhoneId); 2143 if (TextUtils.isEmpty(plmn)) { 2144 loge("satData: NetworkOperator PLMN is empty"); 2145 plmn = mTelephonyManager.getSimOperatorNumeric(mSubId); 2146 loge("satData: SimOperator PLMN = " + plmn); 2147 } 2148 int[] supportedServicesArray = {NetworkRegistrationInfo.SERVICE_TYPE_DATA, 2149 NetworkRegistrationInfo.SERVICE_TYPE_SMS, 2150 NetworkRegistrationInfo.SERVICE_TYPE_EMERGENCY, 2151 NetworkRegistrationInfo.SERVICE_TYPE_MMS}; 2152 2153 PersistableBundle satServicesPerBundle = originalBundle.getPersistableBundle( 2154 KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE); 2155 // New bundle is required, as existed one will throw `ArrayMap is immutable` when we try 2156 // to modify. 2157 PersistableBundle newSatServicesPerBundle = new PersistableBundle(); 2158 //Copy the values from the old bundle into the new bundle. 2159 boolean hasPlmnKey = false; 2160 if (satServicesPerBundle != null) { 2161 for (String key : satServicesPerBundle.keySet()) { 2162 if (!TextUtils.isEmpty(key) && key.equalsIgnoreCase(plmn)) { 2163 newSatServicesPerBundle.putIntArray(plmn, supportedServicesArray); 2164 hasPlmnKey = true; 2165 } else { 2166 newSatServicesPerBundle.putIntArray(key, satServicesPerBundle.getIntArray(key)); 2167 } 2168 } 2169 } 2170 if (!hasPlmnKey) { 2171 newSatServicesPerBundle.putIntArray(plmn, supportedServicesArray); 2172 } 2173 log("satData: New SatelliteServicesBundle = " + newSatServicesPerBundle); 2174 return newSatServicesPerBundle; 2175 } 2176 2177 /** 2178 * This method will check the required carrier config keys which plays role in enabling / 2179 * supporting satellite data and update the keys accordingly. 2180 * @param bundleToModify : PersistableBundle 2181 */ updateCarrierConfigToSupportData(PersistableBundle bundleToModify)2182 private void updateCarrierConfigToSupportData(PersistableBundle bundleToModify) { 2183 // KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY key info update 2184 int[] availableServices = bundleToModify.getIntArray( 2185 KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY); 2186 int[] newServices; 2187 if (availableServices != null && availableServices.length > 0) { 2188 if (Arrays.stream(availableServices).anyMatch( 2189 element -> element == NetworkRegistrationInfo.SERVICE_TYPE_DATA)) { 2190 newServices = new int[availableServices.length]; 2191 System.arraycopy(availableServices, 0, newServices, 0, availableServices.length); 2192 } else { 2193 newServices = new int[availableServices.length + 1]; 2194 System.arraycopy(availableServices, 0, newServices, 0, availableServices.length); 2195 newServices[newServices.length - 1] = NetworkRegistrationInfo.SERVICE_TYPE_DATA; 2196 } 2197 } else { 2198 newServices = new int[1]; 2199 newServices[0] = NetworkRegistrationInfo.SERVICE_TYPE_DATA; 2200 } 2201 bundleToModify.putIntArray(KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY, 2202 newServices); 2203 // KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL setting to false. 2204 bundleToModify.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false); 2205 // Below one not required to update as we are not changing this value. 2206 bundleToModify.remove(KEY_SATELLITE_DATA_SUPPORT_MODE_INT); 2207 log("satData: changing carrierConfig to : " + bundleToModify); 2208 getCarrierConfig().overrideConfig(mSubId, bundleToModify, false); 2209 } 2210 2211 /** 2212 * Method that restore the previous satellite data mode selection. 2213 */ updateSatelliteDataButton()2214 private void updateSatelliteDataButton() { 2215 if (mSatelliteDataOriginalBundle[mPhoneId] == null) { 2216 // It executes only at first time 2217 PersistableBundle originalBundle = getCarrierConfig().getConfigForSubId(mSubId, 2218 KEY_SATELLITE_DATA_SUPPORT_MODE_INT, 2219 KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, 2220 KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY, 2221 KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE); 2222 mSatelliteDataOriginalBundle[mPhoneId] = originalBundle; 2223 log("satData: OriginalConfig = " + originalBundle); 2224 } 2225 PersistableBundle currentBundle = getCarrierConfig().getConfigForSubId(mSubId, 2226 KEY_SATELLITE_DATA_SUPPORT_MODE_INT, 2227 KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY, 2228 KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE); 2229 int dataMode = currentBundle.getInt( 2230 KEY_SATELLITE_DATA_SUPPORT_MODE_INT, -1); 2231 log("satData: present dataMode = " + dataMode); 2232 if (dataMode != -1) { 2233 int checkedId = 0; 2234 switch (dataMode) { 2235 case CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED: 2236 checkedId = R.id.satellite_data_restricted; 2237 break; 2238 case CarrierConfigManager.SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED: 2239 checkedId = R.id.satellite_data_constrained; 2240 break; 2241 case CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL: 2242 checkedId = R.id.satellite_data_unConstrained; 2243 break; 2244 } 2245 mMockSatelliteData.check(checkedId); 2246 } 2247 updateCarrierConfigToSupportData(currentBundle); 2248 } 2249 2250 private final RadioGroup.OnCheckedChangeListener mMockSatelliteDataListener = 2251 (group, checkedId) -> { 2252 int dataMode = CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED; 2253 switch (checkedId) { 2254 case R.id.satellite_data_restricted: 2255 dataMode = CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED; 2256 break; 2257 case R.id.satellite_data_constrained: 2258 dataMode = 2259 CarrierConfigManager.SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED; 2260 break; 2261 case R.id.satellite_data_unConstrained: 2262 dataMode = CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL; 2263 break; 2264 } 2265 log("satData: OnCheckedChangeListener setting dataMode = " + dataMode); 2266 if (getCarrierConfig() == null) return; 2267 PersistableBundle overrideBundle = new PersistableBundle(); 2268 overrideBundle.putInt(KEY_SATELLITE_DATA_SUPPORT_MODE_INT, dataMode); 2269 overrideBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false); 2270 if (isValidSubscription(mSubId)) { 2271 getCarrierConfig().overrideConfig(mSubId, overrideBundle, false); 2272 log("satData: mMockSatelliteDataListener: Updated new config" + overrideBundle); 2273 } 2274 }; 2275 2276 private final OnCheckedChangeListener mMockSatelliteDataSwitchListener = 2277 (buttonView, isChecked) -> { 2278 log("satData: ServiceData enabling = " + isChecked); 2279 if (isChecked) { 2280 if (isValidOperator(mSubId)) { 2281 updateSatelliteDataButton(); 2282 } else { 2283 log("satData: Not a valid Operator"); 2284 mMockSatelliteDataSwitch.setChecked(false); 2285 return; 2286 } 2287 } else { 2288 reloadCarrierConfigDefaults(); 2289 } 2290 setDataModeChangeVisibility(isChecked); 2291 }; 2292 setDataModeChangeVisibility(boolean isChecked)2293 private void setDataModeChangeVisibility(boolean isChecked) { 2294 if (isChecked) { 2295 mMockSatelliteData.setVisibility(View.VISIBLE); 2296 } else { 2297 mMockSatelliteData.setVisibility(View.GONE); 2298 } 2299 } 2300 reloadCarrierConfigDefaults()2301 private void reloadCarrierConfigDefaults() { 2302 if (mSatelliteDataOriginalBundle[mPhoneId] != null) { 2303 log("satData: Setting originalCarrierConfig = " 2304 + mSatelliteDataOriginalBundle[mPhoneId]); 2305 getCarrierConfig().overrideConfig(mSubId, mSatelliteDataOriginalBundle[mPhoneId], 2306 false); 2307 mSatelliteDataOriginalBundle[mPhoneId] = null; 2308 } 2309 } 2310 isValidOperator(int subId)2311 private boolean isValidOperator(int subId) { 2312 String operatorNumeric = null; 2313 if (isValidSubscription(subId)) { 2314 operatorNumeric = mTelephonyManager.getNetworkOperatorForPhone(mPhoneId); 2315 TelephonyManager tm; 2316 if (TextUtils.isEmpty(operatorNumeric) && (tm = getSystemService( 2317 TelephonyManager.class)) != null) { 2318 operatorNumeric = tm.getSimOperatorNumericForPhone(mPhoneId); 2319 } 2320 } 2321 return !TextUtils.isEmpty(operatorNumeric); 2322 } 2323 2324 /** 2325 * This method will do extra check to validate the subId. 2326 * <p> 2327 * In case user opens the radioInfo when sim is active and enable some checks and go to the 2328 * SIM settings screen and disabled the screen. Upon return to radioInfo screen subId is still 2329 * valid but not in active state any more. 2330 */ isValidSubscription(int subId)2331 private boolean isValidSubscription(int subId) { 2332 boolean isValidSubId = false; 2333 if (SubscriptionManager.isValidSubscriptionId(subId)) { 2334 SubscriptionManager mSm = getSystemService(SubscriptionManager.class); 2335 isValidSubId = mSm.isActiveSubscriptionId(subId); 2336 } 2337 log("isValidSubscription, subId [ " + subId + " ] = " + isValidSubId); 2338 return isValidSubId; 2339 } 2340 2341 private final OnCheckedChangeListener mMockSatelliteListener = 2342 (buttonView, isChecked) -> { 2343 int subId = mSubId; 2344 int phoneId = mPhoneId; 2345 if (SubscriptionManager.isValidPhoneId(phoneId) && isValidSubscription(subId)) { 2346 if (getCarrierConfig() == null) return; 2347 if (isChecked) { 2348 if (!isValidOperator(subId)) { 2349 mMockSatellite.setChecked(false); 2350 loge("mMockSatelliteListener: Can't mock because no operator for phone " 2351 + phoneId); 2352 return; 2353 } 2354 PersistableBundle originalBundle = getCarrierConfig().getConfigForSubId( 2355 subId, KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, 2356 KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, 2357 KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE); 2358 mCarrierSatelliteOriginalBundle[phoneId] = originalBundle; 2359 2360 PersistableBundle overrideBundle = new PersistableBundle(); 2361 overrideBundle.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); 2362 // NOTE: In case of TMO setting KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL 2363 // to false will result in SIM Settings not to show few items, which is 2364 // expected. 2365 overrideBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false); 2366 overrideBundle.putPersistableBundle( 2367 KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE, 2368 getSatelliteServicesBundleForOperatorPlmn(originalBundle)); 2369 log("mMockSatelliteListener: old " + originalBundle); 2370 log("mMockSatelliteListener: new " + overrideBundle); 2371 getCarrierConfig().overrideConfig(subId, overrideBundle, false); 2372 } else { 2373 try { 2374 getCarrierConfig().overrideConfig(subId, 2375 mCarrierSatelliteOriginalBundle[phoneId], false); 2376 mCarrierSatelliteOriginalBundle[phoneId] = null; 2377 log("mMockSatelliteListener: Successfully cleared mock for phone " 2378 + phoneId); 2379 } catch (Exception e) { 2380 loge("mMockSatelliteListener: Can't clear mock because invalid sub Id " 2381 + subId 2382 + ", insert SIM and use adb shell cmd phone cc clear-values"); 2383 // Keep show toggle ON if the view is not destroyed. If destroyed, must 2384 // use cmd to reset, because upon creation the view doesn't remember the 2385 // last toggle state while override mock is still in place. 2386 mMockSatellite.setChecked(true); 2387 } 2388 } 2389 } 2390 }; 2391 shouldHideNonEmergencyMode()2392 private boolean shouldHideNonEmergencyMode() { 2393 if (!Build.isDebuggable()) { 2394 return true; 2395 } 2396 String action = SatelliteManager.ACTION_SATELLITE_START_NON_EMERGENCY_SESSION; 2397 if (TextUtils.isEmpty(action)) { 2398 return true; 2399 } 2400 if (mNonEsosIntent != null) { 2401 mNonEsosIntent = null; 2402 } 2403 if (getCarrierConfig() == null) { 2404 loge("shouldHideNonEmergencyMode: cm is null"); 2405 return true; 2406 } 2407 PersistableBundle bundle = getCarrierConfig().getConfigForSubId(mSubId, 2408 KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, 2409 CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL); 2410 if (!bundle.getBoolean( 2411 CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL, false)) { 2412 log("shouldHideNonEmergencyMode: esos_supported false"); 2413 return true; 2414 } 2415 if (!bundle.getBoolean( 2416 KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false)) { 2417 log("shouldHideNonEmergencyMode: attach_supported false"); 2418 return true; 2419 } 2420 2421 String packageName = getStringFromOverlayConfig( 2422 com.android.internal.R.string.config_satellite_gateway_service_package); 2423 2424 String className = getStringFromOverlayConfig(com.android.internal.R.string 2425 .config_satellite_carrier_roaming_non_emergency_session_class); 2426 if (packageName == null || className == null 2427 || packageName.isEmpty() || className.isEmpty()) { 2428 Log.d(TAG, "shouldHideNonEmergencyMode:" 2429 + " packageName or className is null or empty."); 2430 return true; 2431 } 2432 PackageManager pm = getPackageManager(); 2433 Intent intent = new Intent(action); 2434 intent.setComponent(new ComponentName(packageName, className)); 2435 if (pm.queryBroadcastReceivers(intent, 0).isEmpty()) { 2436 Log.d(TAG, "shouldHideNonEmergencyMode: Broadcast receiver not found for intent: " 2437 + intent); 2438 return true; 2439 } 2440 mNonEsosIntent = intent; 2441 return false; 2442 } 2443 getStringFromOverlayConfig(int resourceId)2444 private String getStringFromOverlayConfig(int resourceId) { 2445 String name; 2446 try { 2447 name = getResources().getString(resourceId); 2448 } catch (Resources.NotFoundException ex) { 2449 loge("getStringFromOverlayConfig: ex=" + ex); 2450 name = null; 2451 } 2452 return name; 2453 } 2454 isImsVolteProvisioned()2455 private boolean isImsVolteProvisioned() { 2456 return getImsConfigProvisionedState(CAPABILITY_TYPE_VOICE, 2457 REGISTRATION_TECH_LTE); 2458 } 2459 2460 OnCheckedChangeListener mImsVolteCheckedChangeListener = new OnCheckedChangeListener() { 2461 @Override 2462 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2463 setImsVolteProvisionedState(isChecked); 2464 } 2465 }; 2466 isImsVtProvisioned()2467 private boolean isImsVtProvisioned() { 2468 return getImsConfigProvisionedState(CAPABILITY_TYPE_VIDEO, 2469 REGISTRATION_TECH_LTE); 2470 } 2471 2472 OnCheckedChangeListener mImsVtCheckedChangeListener = new OnCheckedChangeListener() { 2473 @Override 2474 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2475 setImsVtProvisionedState(isChecked); 2476 } 2477 }; 2478 isImsWfcProvisioned()2479 private boolean isImsWfcProvisioned() { 2480 return getImsConfigProvisionedState(CAPABILITY_TYPE_VOICE, 2481 REGISTRATION_TECH_IWLAN); 2482 } 2483 2484 OnCheckedChangeListener mImsWfcCheckedChangeListener = new OnCheckedChangeListener() { 2485 @Override 2486 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2487 setImsWfcProvisionedState(isChecked); 2488 } 2489 }; 2490 isEabProvisioned()2491 private boolean isEabProvisioned() { 2492 return getRcsConfigProvisionedState(ImsRcsManager.CAPABILITY_TYPE_PRESENCE_UCE, 2493 REGISTRATION_TECH_LTE); 2494 } 2495 2496 OnCheckedChangeListener mEabCheckedChangeListener = new OnCheckedChangeListener() { 2497 @Override 2498 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2499 setEabProvisionedState(isChecked); 2500 } 2501 }; 2502 getImsConfigProvisionedState(int capability, int tech)2503 private boolean getImsConfigProvisionedState(int capability, int tech) { 2504 if (mProvisioningManager != null) { 2505 try { 2506 return mProvisioningManager.getProvisioningStatusForCapability( 2507 capability, tech); 2508 } catch (RuntimeException e) { 2509 Log.e(TAG, "getImsConfigProvisionedState() exception:", e); 2510 } 2511 } 2512 2513 return false; 2514 } 2515 getRcsConfigProvisionedState(int capability, int tech)2516 private boolean getRcsConfigProvisionedState(int capability, int tech) { 2517 if (mProvisioningManager != null) { 2518 try { 2519 return mProvisioningManager.getRcsProvisioningStatusForCapability( 2520 capability, tech); 2521 } catch (RuntimeException e) { 2522 Log.e(TAG, "getRcsConfigProvisionedState() exception:", e); 2523 } 2524 } 2525 2526 return false; 2527 } 2528 isEabEnabledByPlatform()2529 private boolean isEabEnabledByPlatform() { 2530 if (SubscriptionManager.isValidPhoneId(mPhoneId)) { 2531 PersistableBundle b = getCarrierConfig().getConfigForSubId(mSubId); 2532 if (b != null) { 2533 return b.getBoolean( 2534 CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, false) || b.getBoolean( 2535 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, 2536 false); 2537 } 2538 } 2539 return false; 2540 } 2541 updateImsProvisionedState()2542 private void updateImsProvisionedState() { 2543 if (!isImsSupportedOnDevice()) { 2544 return; 2545 } 2546 2547 updateServiceEnabledByPlatform(); 2548 2549 updateEabProvisionedSwitch(isEabEnabledByPlatform()); 2550 } 2551 updateVolteProvisionedSwitch(boolean isEnabledByPlatform)2552 private void updateVolteProvisionedSwitch(boolean isEnabledByPlatform) { 2553 boolean isProvisioned = isEnabledByPlatform && isImsVolteProvisioned(); 2554 log("updateVolteProvisionedSwitch isProvisioned" + isProvisioned); 2555 2556 mImsVolteProvisionedSwitch.setOnCheckedChangeListener(null); 2557 mImsVolteProvisionedSwitch.setChecked(isProvisioned); 2558 mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener); 2559 mImsVolteProvisionedSwitch.setEnabled(!IS_USER_BUILD 2560 && isEnabledByPlatform && isImsVolteProvisioningRequired()); 2561 } 2562 updateVtProvisionedSwitch(boolean isEnabledByPlatform)2563 private void updateVtProvisionedSwitch(boolean isEnabledByPlatform) { 2564 boolean isProvisioned = isEnabledByPlatform && isImsVtProvisioned(); 2565 log("updateVtProvisionedSwitch isProvisioned" + isProvisioned); 2566 2567 mImsVtProvisionedSwitch.setOnCheckedChangeListener(null); 2568 mImsVtProvisionedSwitch.setChecked(isProvisioned); 2569 mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener); 2570 mImsVtProvisionedSwitch.setEnabled(!IS_USER_BUILD 2571 && isEnabledByPlatform && isImsVtProvisioningRequired()); 2572 } 2573 updateWfcProvisionedSwitch(boolean isEnabledByPlatform)2574 private void updateWfcProvisionedSwitch(boolean isEnabledByPlatform) { 2575 boolean isProvisioned = isEnabledByPlatform && isImsWfcProvisioned(); 2576 log("updateWfcProvisionedSwitch isProvisioned" + isProvisioned); 2577 2578 mImsWfcProvisionedSwitch.setOnCheckedChangeListener(null); 2579 mImsWfcProvisionedSwitch.setChecked(isProvisioned); 2580 mImsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener); 2581 mImsWfcProvisionedSwitch.setEnabled(!IS_USER_BUILD 2582 && isEnabledByPlatform && isImsWfcProvisioningRequired()); 2583 } 2584 updateEabProvisionedSwitch(boolean isEnabledByPlatform)2585 private void updateEabProvisionedSwitch(boolean isEnabledByPlatform) { 2586 log("updateEabProvisionedSwitch isEabWfcProvisioned()=" + isEabProvisioned()); 2587 2588 mEabProvisionedSwitch.setOnCheckedChangeListener(null); 2589 mEabProvisionedSwitch.setChecked(isEabProvisioned()); 2590 mEabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener); 2591 mEabProvisionedSwitch.setEnabled(!IS_USER_BUILD 2592 && isEnabledByPlatform && isEabProvisioningRequired()); 2593 } 2594 2595 OnClickListener mOemInfoButtonHandler = new OnClickListener() { 2596 public void onClick(View v) { 2597 Intent intent = new Intent(OEM_RADIO_INFO_INTENT); 2598 try { 2599 startActivityAsUser(intent, UserHandle.CURRENT); 2600 } catch (ActivityNotFoundException ex) { 2601 log("OEM-specific Info/Settings Activity Not Found : " + ex); 2602 // If the activity does not exist, there are no OEM 2603 // settings, and so we can just do nothing... 2604 } 2605 } 2606 }; 2607 2608 OnClickListener mPingButtonHandler = new OnClickListener() { 2609 public void onClick(View v) { 2610 updatePingState(); 2611 } 2612 }; 2613 2614 OnClickListener mUpdateSmscButtonHandler = new OnClickListener() { 2615 public void onClick(View v) { 2616 mUpdateSmscButton.setEnabled(false); 2617 mQueuedWork.execute(() -> { 2618 if (mSystemUser) { 2619 mPhone.setSmscAddress(mSmsc.getText().toString(), 2620 mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE)); 2621 } 2622 }); 2623 } 2624 }; 2625 2626 OnClickListener mRefreshSmscButtonHandler = v -> refreshSmsc(); 2627 2628 OnClickListener mCarrierProvisioningButtonHandler = v -> { 2629 String carrierProvisioningApp = getCarrierProvisioningAppString(); 2630 if (!TextUtils.isEmpty(carrierProvisioningApp)) { 2631 final Intent intent = new Intent(CARRIER_PROVISIONING_ACTION); 2632 final ComponentName serviceComponent = 2633 ComponentName.unflattenFromString(carrierProvisioningApp); 2634 intent.setComponent(serviceComponent); 2635 sendBroadcast(intent); 2636 } 2637 }; 2638 2639 OnClickListener mTriggerCarrierProvisioningButtonHandler = v -> { 2640 String carrierProvisioningApp = getCarrierProvisioningAppString(); 2641 if (!TextUtils.isEmpty(carrierProvisioningApp)) { 2642 final Intent intent = new Intent(TRIGGER_CARRIER_PROVISIONING_ACTION); 2643 final ComponentName serviceComponent = 2644 ComponentName.unflattenFromString(carrierProvisioningApp); 2645 intent.setComponent(serviceComponent); 2646 sendBroadcast(intent); 2647 } 2648 }; 2649 2650 AdapterView.OnItemSelectedListener mPreferredNetworkHandler = 2651 new AdapterView.OnItemSelectedListener() { 2652 2653 public void onItemSelected(AdapterView parent, View v, int pos, long id) { 2654 if (mPreferredNetworkTypeResult != pos && pos >= 0 2655 && pos <= PREFERRED_NETWORK_LABELS.length - 2) { 2656 mPreferredNetworkTypeResult = pos; 2657 new Thread(() -> { 2658 mTelephonyManager.setAllowedNetworkTypesForReason( 2659 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, 2660 RadioAccessFamily.getRafFromNetworkType(mPreferredNetworkTypeResult)); 2661 }).start(); 2662 } 2663 } 2664 2665 public void onNothingSelected(AdapterView parent) { 2666 } 2667 }; 2668 2669 AdapterView.OnItemSelectedListener mOnMockSignalStrengthSelectedListener = 2670 new AdapterView.OnItemSelectedListener() { 2671 2672 public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) { 2673 log("mOnSignalStrengthSelectedListener: " + pos); 2674 mSelectedSignalStrengthIndex[mPhoneId] = pos; 2675 if (mSystemUser) { 2676 mPhone.getTelephonyTester().setSignalStrength(SIGNAL_STRENGTH_LEVEL[pos]); 2677 } 2678 } 2679 2680 public void onNothingSelected(AdapterView<?> parent) {} 2681 }; 2682 2683 2684 AdapterView.OnItemSelectedListener mOnMockDataNetworkTypeSelectedListener = 2685 new AdapterView.OnItemSelectedListener() { 2686 2687 public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) { 2688 log("mOnMockDataNetworkTypeSelectedListener: " + pos); 2689 mSelectedMockDataNetworkTypeIndex[mPhoneId] = pos; 2690 Intent intent = new Intent("com.android.internal.telephony.TestServiceState"); 2691 if (pos > 0) { 2692 log("mOnMockDataNetworkTypeSelectedListener: Override RAT: " 2693 + ServiceState.rilRadioTechnologyToString( 2694 MOCK_DATA_NETWORK_TYPE[pos])); 2695 intent.putExtra("data_reg_state", ServiceState.STATE_IN_SERVICE); 2696 intent.putExtra("data_rat", MOCK_DATA_NETWORK_TYPE[pos]); 2697 } else { 2698 log("mOnMockDataNetworkTypeSelectedListener: Remove RAT override."); 2699 intent.putExtra("action", "reset"); 2700 } 2701 2702 if (mSystemUser) { 2703 mPhone.getTelephonyTester().setServiceStateTestIntent(intent); 2704 } 2705 } 2706 2707 public void onNothingSelected(AdapterView<?> parent) {} 2708 }; 2709 2710 AdapterView.OnItemSelectedListener mSelectPhoneIndexHandler = 2711 new AdapterView.OnItemSelectedListener() { 2712 2713 public void onItemSelected(AdapterView parent, View v, int pos, long id) { 2714 if (pos >= 0 && pos <= sPhoneIndexLabels.length - 1) { 2715 if (mTelephonyManager.getActiveModemCount() <= pos) { 2716 return; 2717 } 2718 2719 mPhoneId = pos; 2720 mSubId = SubscriptionManager.getSubscriptionId(mPhoneId); 2721 log("Updated phone id to " + mPhoneId + ", sub id to " + mSubId); 2722 updatePhoneIndex(); 2723 } 2724 } 2725 2726 public void onNothingSelected(AdapterView parent) { 2727 } 2728 }; 2729 2730 AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler = 2731 new AdapterView.OnItemSelectedListener() { 2732 2733 public void onItemSelected(AdapterView parent, View v, int pos, long id) { 2734 mCellInfoRefreshRateIndex = pos; 2735 mTelephonyManager.setCellInfoListRate(CELL_INFO_REFRESH_RATES[pos], mPhoneId); 2736 updateAllCellInfo(); 2737 } 2738 2739 public void onNothingSelected(AdapterView parent) { 2740 } 2741 }; 2742 getCarrierProvisioningAppString()2743 private String getCarrierProvisioningAppString() { 2744 if (SubscriptionManager.isValidPhoneId(mPhoneId)) { 2745 PersistableBundle b = getCarrierConfig().getConfigForSubId(mSubId); 2746 if (b != null) { 2747 return b.getString( 2748 CarrierConfigManager.KEY_CARRIER_PROVISIONING_APP_STRING, ""); 2749 } 2750 } 2751 return ""; 2752 } 2753 isCbrsSupported()2754 boolean isCbrsSupported() { 2755 return getResources().getBoolean( 2756 com.android.internal.R.bool.config_cbrs_supported); 2757 } 2758 updateCbrsDataState(boolean state)2759 void updateCbrsDataState(boolean state) { 2760 Log.d(TAG, "setCbrsDataSwitchState() state:" + ((state) ? "on" : "off")); 2761 if (mTelephonyManager != null) { 2762 mQueuedWork.execute(new Runnable() { 2763 public void run() { 2764 mTelephonyManager.setOpportunisticNetworkState(state); 2765 mHandler.post(() -> mCbrsDataSwitch.setChecked(getCbrsDataState())); 2766 } 2767 }); 2768 } 2769 } 2770 getCbrsDataState()2771 boolean getCbrsDataState() { 2772 boolean state = false; 2773 if (mTelephonyManager != null) { 2774 state = mTelephonyManager.isOpportunisticNetworkEnabled(); 2775 } 2776 Log.d(TAG, "getCbrsDataState() state:" + ((state) ? "on" : "off")); 2777 return state; 2778 } 2779 2780 OnCheckedChangeListener mCbrsDataSwitchChangeListener = new OnCheckedChangeListener() { 2781 @Override 2782 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2783 updateCbrsDataState(isChecked); 2784 } 2785 }; 2786 showDsdsChangeDialog()2787 private void showDsdsChangeDialog() { 2788 final AlertDialog confirmDialog = new Builder(RadioInfo.this) 2789 .setTitle(R.string.dsds_dialog_title) 2790 .setMessage(R.string.dsds_dialog_message) 2791 .setPositiveButton(R.string.dsds_dialog_confirm, mOnDsdsDialogConfirmedListener) 2792 .setNegativeButton(R.string.dsds_dialog_cancel, mOnDsdsDialogConfirmedListener) 2793 .create(); 2794 confirmDialog.show(); 2795 } 2796 isDsdsSupported()2797 private static boolean isDsdsSupported() { 2798 return (TelephonyManager.getDefault().isMultiSimSupported() 2799 == TelephonyManager.MULTISIM_ALLOWED); 2800 } 2801 isDsdsEnabled()2802 private static boolean isDsdsEnabled() { 2803 return TelephonyManager.getDefault().getPhoneCount() > 1; 2804 } 2805 performDsdsSwitch()2806 private void performDsdsSwitch() { 2807 mTelephonyManager.switchMultiSimConfig(mDsdsSwitch.isChecked() ? 2 : 1); 2808 } 2809 2810 /** 2811 * @return {@code True} if the device is only supported dsds mode. 2812 */ dsdsModeOnly()2813 private boolean dsdsModeOnly() { 2814 String dsdsMode = SystemProperties.get(DSDS_MODE_PROPERTY); 2815 return !TextUtils.isEmpty(dsdsMode) && Integer.parseInt(dsdsMode) == ALWAYS_ON_DSDS_MODE; 2816 } 2817 2818 DialogInterface.OnClickListener mOnDsdsDialogConfirmedListener = 2819 new DialogInterface.OnClickListener() { 2820 @Override 2821 public void onClick(DialogInterface dialog, int which) { 2822 if (which == DialogInterface.BUTTON_POSITIVE) { 2823 mDsdsSwitch.toggle(); 2824 performDsdsSwitch(); 2825 } 2826 } 2827 }; 2828 2829 OnCheckedChangeListener mRemovableEsimChangeListener = new OnCheckedChangeListener() { 2830 @Override 2831 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2832 setRemovableEsimAsDefaultEuicc(isChecked); 2833 } 2834 }; 2835 setRemovableEsimAsDefaultEuicc(boolean isChecked)2836 private void setRemovableEsimAsDefaultEuicc(boolean isChecked) { 2837 Log.d(TAG, "setRemovableEsimAsDefaultEuicc isChecked: " + isChecked); 2838 mTelephonyManager.setRemovableEsimAsDefaultEuicc(isChecked); 2839 // TODO(b/232528117): Instead of sending intent, add new APIs in platform, 2840 // LPA can directly use the API. 2841 ComponentInfo componentInfo = EuiccConnector.findBestComponent(getPackageManager()); 2842 if (componentInfo == null) { 2843 Log.d(TAG, "setRemovableEsimAsDefaultEuicc: unable to find suitable component info"); 2844 return; 2845 } 2846 final Intent intent = new Intent(ACTION_REMOVABLE_ESIM_AS_DEFAULT); 2847 intent.setPackage(componentInfo.packageName); 2848 intent.putExtra("isDefault", isChecked); 2849 sendBroadcast(intent); 2850 } 2851 isImsSupportedOnDevice()2852 private boolean isImsSupportedOnDevice() { 2853 return getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS); 2854 } 2855 updateServiceEnabledByPlatform()2856 private void updateServiceEnabledByPlatform() { 2857 if (!SubscriptionManager.isValidSubscriptionId(mSubId)) { 2858 log("updateServiceEnabledByPlatform subscription ID is invalid"); 2859 return; 2860 } 2861 2862 ImsMmTelManager imsMmTelManager = mImsManager.getImsMmTelManager(mSubId); 2863 try { 2864 imsMmTelManager.isSupported(CAPABILITY_TYPE_VOICE, 2865 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getMainExecutor(), (result) -> { 2866 updateVolteProvisionedSwitch(result); 2867 }); 2868 imsMmTelManager.isSupported(CAPABILITY_TYPE_VIDEO, 2869 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getMainExecutor(), (result) -> { 2870 updateVtProvisionedSwitch(result); 2871 }); 2872 imsMmTelManager.isSupported(CAPABILITY_TYPE_VOICE, 2873 AccessNetworkConstants.TRANSPORT_TYPE_WLAN, getMainExecutor(), (result) -> { 2874 updateWfcProvisionedSwitch(result); 2875 }); 2876 } catch (ImsException e) { 2877 e.printStackTrace(); 2878 } 2879 } 2880 getPhone(int subId)2881 private Phone getPhone(int subId) { 2882 log("getPhone subId = " + subId); 2883 Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId)); 2884 if (phone == null) { 2885 log("return the default phone"); 2886 return PhoneFactory.getDefaultPhone(); 2887 } 2888 2889 return phone; 2890 } 2891 isVoiceServiceAvailable(ImsMmTelManager imsMmTelManager)2892 private boolean isVoiceServiceAvailable(ImsMmTelManager imsMmTelManager) { 2893 if (imsMmTelManager == null) { 2894 log("isVoiceServiceAvailable: ImsMmTelManager is null"); 2895 return false; 2896 } 2897 2898 final int[] radioTechs = { 2899 REGISTRATION_TECH_LTE, 2900 REGISTRATION_TECH_CROSS_SIM, 2901 REGISTRATION_TECH_NR, 2902 REGISTRATION_TECH_3G 2903 }; 2904 2905 boolean isAvailable = false; 2906 for (int tech : radioTechs) { 2907 try { 2908 isAvailable |= imsMmTelManager.isAvailable(CAPABILITY_TYPE_VOICE, tech); 2909 if (isAvailable) { 2910 break; 2911 } 2912 } catch (Exception e) { 2913 log("isVoiceServiceAvailable: exception " + e.getMessage()); 2914 } 2915 } 2916 2917 log("isVoiceServiceAvailable: " + isAvailable); 2918 return isAvailable; 2919 } 2920 isVideoServiceAvailable(ImsMmTelManager imsMmTelManager)2921 private boolean isVideoServiceAvailable(ImsMmTelManager imsMmTelManager) { 2922 if (imsMmTelManager == null) { 2923 log("isVideoServiceAvailable: ImsMmTelManager is null"); 2924 return false; 2925 } 2926 2927 final int[] radioTechs = { 2928 REGISTRATION_TECH_LTE, 2929 REGISTRATION_TECH_IWLAN, 2930 REGISTRATION_TECH_CROSS_SIM, 2931 REGISTRATION_TECH_NR, 2932 REGISTRATION_TECH_3G 2933 }; 2934 2935 boolean isAvailable = false; 2936 for (int tech : radioTechs) { 2937 try { 2938 isAvailable |= imsMmTelManager.isAvailable(CAPABILITY_TYPE_VIDEO, tech); 2939 if (isAvailable) { 2940 break; 2941 } 2942 } catch (Exception e) { 2943 log("isVideoServiceAvailable: exception " + e.getMessage()); 2944 } 2945 } 2946 2947 log("isVideoServiceAvailable: " + isAvailable); 2948 return isAvailable; 2949 } 2950 isWfcServiceAvailable(ImsMmTelManager imsMmTelManager)2951 private boolean isWfcServiceAvailable(ImsMmTelManager imsMmTelManager) { 2952 if (imsMmTelManager == null) { 2953 log("isWfcServiceAvailable: ImsMmTelManager is null"); 2954 return false; 2955 } 2956 2957 boolean isAvailable = false; 2958 try { 2959 isAvailable = imsMmTelManager.isAvailable(CAPABILITY_TYPE_VOICE, 2960 REGISTRATION_TECH_IWLAN); 2961 } catch (Exception e) { 2962 log("isWfcServiceAvailable: exception " + e.getMessage()); 2963 } 2964 2965 log("isWfcServiceAvailable: " + isAvailable); 2966 return isAvailable; 2967 } 2968 getCarrierConfig()2969 private CarrierConfigManager getCarrierConfig() { 2970 if (mCarrierConfigManager == null) { 2971 mCarrierConfigManager = getSystemService(CarrierConfigManager.class); 2972 } 2973 return mCarrierConfigManager; 2974 } 2975 } 2976