1 /* 2 * Copyright (C) 2017 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.settings.deviceinfo.simstatus; 18 19 import android.annotation.Nullable; 20 import android.content.BroadcastReceiver; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.content.ServiceConnection; 26 import android.content.res.Resources; 27 import android.os.IBinder; 28 import android.os.PersistableBundle; 29 import android.os.RemoteException; 30 import android.telephony.AccessNetworkConstants; 31 import android.telephony.Annotation; 32 import android.telephony.CarrierConfigManager; 33 import android.telephony.CellBroadcastIntents; 34 import android.telephony.CellBroadcastService; 35 import android.telephony.CellSignalStrength; 36 import android.telephony.ICellBroadcastService; 37 import android.telephony.PhoneStateListener; 38 import android.telephony.ServiceState; 39 import android.telephony.SignalStrength; 40 import android.telephony.SubscriptionInfo; 41 import android.telephony.SubscriptionManager; 42 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; 43 import android.telephony.TelephonyDisplayInfo; 44 import android.telephony.TelephonyManager; 45 import android.telephony.UiccCardInfo; 46 import android.telephony.euicc.EuiccManager; 47 import android.telephony.ims.ImsException; 48 import android.telephony.ims.ImsMmTelManager; 49 import android.telephony.ims.ImsReasonInfo; 50 import android.text.TextUtils; 51 import android.util.Log; 52 53 import androidx.annotation.NonNull; 54 import androidx.annotation.VisibleForTesting; 55 56 import com.android.settings.R; 57 import com.android.settingslib.DeviceInfoUtils; 58 import com.android.settingslib.Utils; 59 import com.android.settingslib.core.lifecycle.Lifecycle; 60 import com.android.settingslib.core.lifecycle.LifecycleObserver; 61 import com.android.settingslib.core.lifecycle.events.OnPause; 62 import com.android.settingslib.core.lifecycle.events.OnResume; 63 64 import java.util.List; 65 import java.util.Map; 66 67 public class SimStatusDialogController implements LifecycleObserver, OnResume, OnPause { 68 69 private final static String TAG = "SimStatusDialogCtrl"; 70 71 private static final String CELL_BROADCAST_SERVICE_PACKAGE = "com.android.cellbroadcastservice"; 72 73 @VisibleForTesting 74 final static int NETWORK_PROVIDER_VALUE_ID = R.id.operator_name_value; 75 @VisibleForTesting 76 final static int PHONE_NUMBER_VALUE_ID = R.id.number_value; 77 @VisibleForTesting 78 final static int CELLULAR_NETWORK_STATE = R.id.data_state_value; 79 @VisibleForTesting 80 final static int OPERATOR_INFO_LABEL_ID = R.id.latest_area_info_label; 81 @VisibleForTesting 82 final static int OPERATOR_INFO_VALUE_ID = R.id.latest_area_info_value; 83 @VisibleForTesting 84 final static int SERVICE_STATE_VALUE_ID = R.id.service_state_value; 85 @VisibleForTesting 86 final static int SIGNAL_STRENGTH_LABEL_ID = R.id.signal_strength_label; 87 @VisibleForTesting 88 final static int SIGNAL_STRENGTH_VALUE_ID = R.id.signal_strength_value; 89 @VisibleForTesting 90 final static int CELL_VOICE_NETWORK_TYPE_VALUE_ID = R.id.voice_network_type_value; 91 @VisibleForTesting 92 final static int CELL_DATA_NETWORK_TYPE_VALUE_ID = R.id.data_network_type_value; 93 @VisibleForTesting 94 final static int ROAMING_INFO_VALUE_ID = R.id.roaming_state_value; 95 @VisibleForTesting 96 final static int ICCID_INFO_LABEL_ID = R.id.icc_id_label; 97 @VisibleForTesting 98 final static int ICCID_INFO_VALUE_ID = R.id.icc_id_value; 99 @VisibleForTesting 100 final static int EID_INFO_LABEL_ID = R.id.esim_id_label; 101 @VisibleForTesting 102 final static int EID_INFO_VALUE_ID = R.id.esim_id_value; 103 @VisibleForTesting 104 final static int IMS_REGISTRATION_STATE_LABEL_ID = R.id.ims_reg_state_label; 105 @VisibleForTesting 106 final static int IMS_REGISTRATION_STATE_VALUE_ID = R.id.ims_reg_state_value; 107 108 @VisibleForTesting 109 static final int MAX_PHONE_COUNT_SINGLE_SIM = 1; 110 111 private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener = 112 new OnSubscriptionsChangedListener() { 113 @Override 114 public void onSubscriptionsChanged() { 115 final int prevSubId = (mSubscriptionInfo != null) 116 ? mSubscriptionInfo.getSubscriptionId() 117 : SubscriptionManager.INVALID_SUBSCRIPTION_ID; 118 119 mSubscriptionInfo = getPhoneSubscriptionInfo(mSlotIndex); 120 121 final int nextSubId = (mSubscriptionInfo != null) 122 ? mSubscriptionInfo.getSubscriptionId() 123 : SubscriptionManager.INVALID_SUBSCRIPTION_ID; 124 125 if (prevSubId != nextSubId) { 126 if (SubscriptionManager.isValidSubscriptionId(prevSubId)) { 127 unregisterImsRegistrationCallback(prevSubId); 128 } 129 if (SubscriptionManager.isValidSubscriptionId(nextSubId)) { 130 mTelephonyManager = 131 mTelephonyManager.createForSubscriptionId(nextSubId); 132 registerImsRegistrationCallback(nextSubId); 133 } 134 } 135 updateSubscriptionStatus(); 136 } 137 }; 138 139 private SubscriptionInfo mSubscriptionInfo; 140 private TelephonyDisplayInfo mTelephonyDisplayInfo; 141 142 private final int mSlotIndex; 143 private TelephonyManager mTelephonyManager; 144 145 private final SimStatusDialogFragment mDialog; 146 private final SubscriptionManager mSubscriptionManager; 147 private final CarrierConfigManager mCarrierConfigManager; 148 private final EuiccManager mEuiccManager; 149 private final Resources mRes; 150 private final Context mContext; 151 152 private boolean mShowLatestAreaInfo; 153 154 private final BroadcastReceiver mAreaInfoReceiver = new BroadcastReceiver() { 155 @Override 156 public void onReceive(Context context, Intent intent) { 157 if (CellBroadcastIntents.ACTION_AREA_INFO_UPDATED.equals(intent.getAction()) 158 && intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0) 159 == mSlotIndex) { 160 updateAreaInfoText(); 161 } 162 } 163 }; 164 165 private PhoneStateListener mPhoneStateListener; 166 167 private CellBroadcastServiceConnection mCellBroadcastServiceConnection; 168 169 private class CellBroadcastServiceConnection implements ServiceConnection { 170 private IBinder mService; 171 172 @Nullable getService()173 public IBinder getService() { 174 return mService; 175 } 176 177 @Override onServiceConnected(ComponentName className, IBinder service)178 public void onServiceConnected(ComponentName className, IBinder service) { 179 Log.d(TAG, "connected to CellBroadcastService"); 180 this.mService = service; 181 updateAreaInfoText(); 182 } 183 184 @Override onServiceDisconnected(ComponentName className)185 public void onServiceDisconnected(ComponentName className) { 186 this.mService = null; 187 Log.d(TAG, "mICellBroadcastService has disconnected unexpectedly"); 188 } 189 190 @Override onBindingDied(ComponentName name)191 public void onBindingDied(ComponentName name) { 192 this.mService = null; 193 Log.d(TAG, "Binding died"); 194 } 195 196 @Override onNullBinding(ComponentName name)197 public void onNullBinding(ComponentName name) { 198 this.mService = null; 199 Log.d(TAG, "Null binding"); 200 } 201 } 202 SimStatusDialogController(@onNull SimStatusDialogFragment dialog, Lifecycle lifecycle, int slotId)203 public SimStatusDialogController(@NonNull SimStatusDialogFragment dialog, Lifecycle lifecycle, 204 int slotId) { 205 mDialog = dialog; 206 mContext = dialog.getContext(); 207 mSlotIndex = slotId; 208 mSubscriptionInfo = getPhoneSubscriptionInfo(slotId); 209 210 mTelephonyManager = mContext.getSystemService(TelephonyManager.class); 211 mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class); 212 mEuiccManager = mContext.getSystemService(EuiccManager.class); 213 mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class); 214 215 mRes = mContext.getResources(); 216 217 if (lifecycle != null) { 218 lifecycle.addObserver(this); 219 } 220 } 221 initialize()222 public void initialize() { 223 updateEid(); 224 225 if (mSubscriptionInfo == null) { 226 return; 227 } 228 229 mPhoneStateListener = getPhoneStateListener(); 230 updateLatestAreaInfo(); 231 updateSubscriptionStatus(); 232 } 233 updateSubscriptionStatus()234 private void updateSubscriptionStatus() { 235 updateNetworkProvider(); 236 237 final ServiceState serviceState = mTelephonyManager.getServiceState(); 238 final SignalStrength signalStrength = mTelephonyManager.getSignalStrength(); 239 240 updatePhoneNumber(); 241 updateServiceState(serviceState); 242 updateSignalStrength(signalStrength); 243 updateNetworkType(); 244 updateRoamingStatus(serviceState); 245 updateIccidNumber(); 246 updateImsRegistrationState(); 247 } 248 249 /** 250 * Deinitialization works 251 */ deinitialize()252 public void deinitialize() { 253 if (mShowLatestAreaInfo) { 254 if (mCellBroadcastServiceConnection != null 255 && mCellBroadcastServiceConnection.getService() != null) { 256 mContext.unbindService(mCellBroadcastServiceConnection); 257 } 258 mCellBroadcastServiceConnection = null; 259 } 260 } 261 262 @Override onResume()263 public void onResume() { 264 if (mSubscriptionInfo == null) { 265 return; 266 } 267 mTelephonyManager = mTelephonyManager.createForSubscriptionId( 268 mSubscriptionInfo.getSubscriptionId()); 269 mTelephonyManager.listen(mPhoneStateListener, 270 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE 271 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS 272 | PhoneStateListener.LISTEN_SERVICE_STATE 273 | PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED); 274 mSubscriptionManager.addOnSubscriptionsChangedListener( 275 mContext.getMainExecutor(), mOnSubscriptionsChangedListener); 276 registerImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId()); 277 278 if (mShowLatestAreaInfo) { 279 updateAreaInfoText(); 280 mContext.registerReceiver(mAreaInfoReceiver, 281 new IntentFilter(CellBroadcastIntents.ACTION_AREA_INFO_UPDATED)); 282 } 283 } 284 285 @Override onPause()286 public void onPause() { 287 if (mSubscriptionInfo == null) { 288 return; 289 } 290 291 unregisterImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId()); 292 mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); 293 mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); 294 295 if (mShowLatestAreaInfo) { 296 mContext.unregisterReceiver(mAreaInfoReceiver); 297 } 298 } 299 updateNetworkProvider()300 private void updateNetworkProvider() { 301 final CharSequence carrierName = 302 mSubscriptionInfo != null ? mSubscriptionInfo.getCarrierName() : null; 303 mDialog.setText(NETWORK_PROVIDER_VALUE_ID, carrierName); 304 } 305 updatePhoneNumber()306 private void updatePhoneNumber() { 307 // If formattedNumber is null or empty, it'll display as "Unknown". 308 mDialog.setText(PHONE_NUMBER_VALUE_ID, 309 DeviceInfoUtils.getBidiFormattedPhoneNumber(mContext, mSubscriptionInfo)); 310 } 311 updateDataState(int state)312 private void updateDataState(int state) { 313 String networkStateValue; 314 315 switch (state) { 316 case TelephonyManager.DATA_CONNECTED: 317 networkStateValue = mRes.getString(R.string.radioInfo_data_connected); 318 break; 319 case TelephonyManager.DATA_SUSPENDED: 320 networkStateValue = mRes.getString(R.string.radioInfo_data_suspended); 321 break; 322 case TelephonyManager.DATA_CONNECTING: 323 networkStateValue = mRes.getString(R.string.radioInfo_data_connecting); 324 break; 325 case TelephonyManager.DATA_DISCONNECTED: 326 networkStateValue = mRes.getString(R.string.radioInfo_data_disconnected); 327 break; 328 default: 329 networkStateValue = mRes.getString(R.string.radioInfo_unknown); 330 break; 331 } 332 333 mDialog.setText(CELLULAR_NETWORK_STATE, networkStateValue); 334 } 335 336 /** 337 * Update area info text retrieved from 338 * {@link CellBroadcastService#getCellBroadcastAreaInfo(int)} 339 */ updateAreaInfoText()340 private void updateAreaInfoText() { 341 if (!mShowLatestAreaInfo || mCellBroadcastServiceConnection == null) return; 342 ICellBroadcastService cellBroadcastService = 343 ICellBroadcastService.Stub.asInterface( 344 mCellBroadcastServiceConnection.getService()); 345 if (cellBroadcastService == null) return; 346 try { 347 mDialog.setText(OPERATOR_INFO_VALUE_ID, 348 cellBroadcastService.getCellBroadcastAreaInfo(mSlotIndex)); 349 350 } catch (RemoteException e) { 351 Log.d(TAG, "Can't get area info. e=" + e); 352 } 353 } 354 355 /** 356 * Bind cell broadcast service. 357 */ bindCellBroadcastService()358 private void bindCellBroadcastService() { 359 mCellBroadcastServiceConnection = new CellBroadcastServiceConnection(); 360 Intent intent = new Intent(CellBroadcastService.CELL_BROADCAST_SERVICE_INTERFACE); 361 intent.setPackage(CELL_BROADCAST_SERVICE_PACKAGE); 362 if (mCellBroadcastServiceConnection != null 363 && mCellBroadcastServiceConnection.getService() == null) { 364 if (!mContext.bindService(intent, mCellBroadcastServiceConnection, 365 Context.BIND_AUTO_CREATE)) { 366 Log.e(TAG, "Unable to bind to service"); 367 } 368 } else { 369 Log.d(TAG, "skipping bindService because connection already exists"); 370 } 371 } 372 updateLatestAreaInfo()373 private void updateLatestAreaInfo() { 374 mShowLatestAreaInfo = Resources.getSystem().getBoolean( 375 com.android.internal.R.bool.config_showAreaUpdateInfoSettings) 376 && mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA; 377 378 if (mShowLatestAreaInfo) { 379 // Bind cell broadcast service to get the area info. The info will be updated once 380 // the service is connected. 381 bindCellBroadcastService(); 382 } else { 383 mDialog.removeSettingFromScreen(OPERATOR_INFO_LABEL_ID); 384 mDialog.removeSettingFromScreen(OPERATOR_INFO_VALUE_ID); 385 } 386 } 387 updateServiceState(ServiceState serviceState)388 private void updateServiceState(ServiceState serviceState) { 389 final int state = Utils.getCombinedServiceState(serviceState); 390 if (!Utils.isInService(serviceState)) { 391 resetSignalStrength(); 392 } 393 394 String serviceStateValue; 395 396 switch (state) { 397 case ServiceState.STATE_IN_SERVICE: 398 serviceStateValue = mRes.getString(R.string.radioInfo_service_in); 399 break; 400 case ServiceState.STATE_OUT_OF_SERVICE: 401 case ServiceState.STATE_EMERGENCY_ONLY: 402 // Set summary string of service state to radioInfo_service_out when 403 // service state is both STATE_OUT_OF_SERVICE & STATE_EMERGENCY_ONLY 404 serviceStateValue = mRes.getString(R.string.radioInfo_service_out); 405 break; 406 case ServiceState.STATE_POWER_OFF: 407 serviceStateValue = mRes.getString(R.string.radioInfo_service_off); 408 break; 409 default: 410 serviceStateValue = mRes.getString(R.string.radioInfo_unknown); 411 break; 412 } 413 414 mDialog.setText(SERVICE_STATE_VALUE_ID, serviceStateValue); 415 } 416 updateSignalStrength(SignalStrength signalStrength)417 private void updateSignalStrength(SignalStrength signalStrength) { 418 if (signalStrength == null) { 419 return; 420 } 421 // by default we show the signal strength 422 boolean showSignalStrength = true; 423 if (mSubscriptionInfo != null) { 424 final int subscriptionId = mSubscriptionInfo.getSubscriptionId(); 425 final PersistableBundle carrierConfig = 426 mCarrierConfigManager.getConfigForSubId(subscriptionId); 427 if (carrierConfig != null) { 428 showSignalStrength = carrierConfig.getBoolean( 429 CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL); 430 } 431 } 432 if (!showSignalStrength) { 433 mDialog.removeSettingFromScreen(SIGNAL_STRENGTH_LABEL_ID); 434 mDialog.removeSettingFromScreen(SIGNAL_STRENGTH_VALUE_ID); 435 return; 436 } 437 438 ServiceState serviceState = mTelephonyManager.getServiceState(); 439 if (serviceState == null || !Utils.isInService(serviceState)) { 440 return; 441 } 442 443 int signalDbm = getDbm(signalStrength); 444 int signalAsu = getAsuLevel(signalStrength); 445 446 if (signalDbm == -1) { 447 signalDbm = 0; 448 } 449 450 if (signalAsu == -1) { 451 signalAsu = 0; 452 } 453 454 mDialog.setText(SIGNAL_STRENGTH_VALUE_ID, mRes.getString(R.string.sim_signal_strength, 455 signalDbm, signalAsu)); 456 } 457 resetSignalStrength()458 private void resetSignalStrength() { 459 mDialog.setText(SIGNAL_STRENGTH_VALUE_ID, "0"); 460 } 461 updateNetworkType()462 private void updateNetworkType() { 463 // TODO: all of this should be based on TelephonyDisplayInfo instead of just the 5G logic 464 if (mSubscriptionInfo == null) { 465 final String unknownNetworkType = 466 getNetworkTypeName(TelephonyManager.NETWORK_TYPE_UNKNOWN); 467 mDialog.setText(CELL_VOICE_NETWORK_TYPE_VALUE_ID, unknownNetworkType); 468 mDialog.setText(CELL_DATA_NETWORK_TYPE_VALUE_ID, unknownNetworkType); 469 return; 470 } 471 472 // Whether EDGE, UMTS, etc... 473 String dataNetworkTypeName = null; 474 String voiceNetworkTypeName = null; 475 final int subId = mSubscriptionInfo.getSubscriptionId(); 476 final int actualDataNetworkType = mTelephonyManager.getDataNetworkType(); 477 final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType(); 478 final int overrideNetworkType = mTelephonyDisplayInfo == null 479 ? TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE 480 : mTelephonyDisplayInfo.getOverrideNetworkType(); 481 482 if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualDataNetworkType) { 483 dataNetworkTypeName = getNetworkTypeName(actualDataNetworkType); 484 } 485 if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualVoiceNetworkType) { 486 voiceNetworkTypeName = getNetworkTypeName(actualVoiceNetworkType); 487 } 488 489 if (overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE 490 || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA) { 491 dataNetworkTypeName = "NR NSA"; 492 } 493 494 boolean show4GForLTE = false; 495 final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId); 496 if (carrierConfig != null) { 497 show4GForLTE = carrierConfig.getBoolean( 498 CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL); 499 } 500 501 if (show4GForLTE) { 502 if ("LTE".equals(dataNetworkTypeName)) { 503 dataNetworkTypeName = "4G"; 504 } 505 if ("LTE".equals(voiceNetworkTypeName)) { 506 voiceNetworkTypeName = "4G"; 507 } 508 } 509 510 mDialog.setText(CELL_VOICE_NETWORK_TYPE_VALUE_ID, voiceNetworkTypeName); 511 mDialog.setText(CELL_DATA_NETWORK_TYPE_VALUE_ID, dataNetworkTypeName); 512 } 513 updateRoamingStatus(ServiceState serviceState)514 private void updateRoamingStatus(ServiceState serviceState) { 515 if (serviceState.getRoaming()) { 516 mDialog.setText(ROAMING_INFO_VALUE_ID, mRes.getString(R.string.radioInfo_roaming_in)); 517 } else { 518 mDialog.setText(ROAMING_INFO_VALUE_ID, mRes.getString(R.string.radioInfo_roaming_not)); 519 } 520 } 521 updateIccidNumber()522 private void updateIccidNumber() { 523 // do not show iccid by default 524 boolean showIccId = false; 525 if (mSubscriptionInfo != null) { 526 final int subscriptionId = mSubscriptionInfo.getSubscriptionId(); 527 final PersistableBundle carrierConfig = 528 mCarrierConfigManager.getConfigForSubId(subscriptionId); 529 if (carrierConfig != null) { 530 showIccId = carrierConfig.getBoolean( 531 CarrierConfigManager.KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL); 532 } 533 } 534 if (!showIccId) { 535 mDialog.removeSettingFromScreen(ICCID_INFO_LABEL_ID); 536 mDialog.removeSettingFromScreen(ICCID_INFO_VALUE_ID); 537 } else { 538 mDialog.setText(ICCID_INFO_VALUE_ID, mTelephonyManager.getSimSerialNumber()); 539 } 540 } 541 updateEid()542 private void updateEid() { 543 boolean shouldHaveEid = false; 544 String eid = null; 545 546 if (mTelephonyManager.getActiveModemCount() > MAX_PHONE_COUNT_SINGLE_SIM) { 547 // Get EID per-SIM in multi-SIM mode 548 Map<Integer, Integer> mapping = mTelephonyManager.getLogicalToPhysicalSlotMapping(); 549 int pSlotId = mapping.getOrDefault(mSlotIndex, 550 SubscriptionManager.INVALID_SIM_SLOT_INDEX); 551 552 if (pSlotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { 553 List<UiccCardInfo> infos = mTelephonyManager.getUiccCardsInfo(); 554 555 for (UiccCardInfo info : infos) { 556 if (info.getSlotIndex() == pSlotId) { 557 if (info.isEuicc()) { 558 shouldHaveEid = true; 559 eid = info.getEid(); 560 561 if (TextUtils.isEmpty(eid)) { 562 eid = mEuiccManager.createForCardId(info.getCardId()).getEid(); 563 } 564 } 565 break; 566 } 567 } 568 } 569 } else if (mEuiccManager.isEnabled()) { 570 // Get EID of default eSIM in single-SIM mode 571 shouldHaveEid = true; 572 eid = mEuiccManager.getEid(); 573 } 574 575 if (!shouldHaveEid) { 576 mDialog.removeSettingFromScreen(EID_INFO_LABEL_ID); 577 mDialog.removeSettingFromScreen(EID_INFO_VALUE_ID); 578 } else if (!TextUtils.isEmpty(eid)) { 579 mDialog.setText(EID_INFO_VALUE_ID, eid); 580 } 581 } 582 isImsRegistrationStateShowUp()583 private boolean isImsRegistrationStateShowUp() { 584 if (mSubscriptionInfo == null) { 585 return false; 586 } 587 final int subscriptionId = mSubscriptionInfo.getSubscriptionId(); 588 final PersistableBundle carrierConfig = 589 mCarrierConfigManager.getConfigForSubId(subscriptionId); 590 return carrierConfig == null ? false : 591 carrierConfig.getBoolean( 592 CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL); 593 } 594 updateImsRegistrationState()595 private void updateImsRegistrationState() { 596 if (isImsRegistrationStateShowUp()) { 597 return; 598 } 599 mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_LABEL_ID); 600 mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID); 601 } 602 603 private ImsMmTelManager.RegistrationCallback mImsRegStateCallback = 604 new ImsMmTelManager.RegistrationCallback() { 605 @Override 606 public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) { 607 mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString( 608 R.string.ims_reg_status_registered)); 609 } 610 @Override 611 public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) { 612 mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString( 613 R.string.ims_reg_status_not_registered)); 614 } 615 @Override 616 public void onUnregistered(@Nullable ImsReasonInfo info) { 617 mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString( 618 R.string.ims_reg_status_not_registered)); 619 } 620 @Override 621 public void onTechnologyChangeFailed( 622 @AccessNetworkConstants.TransportType int imsTransportType, 623 @Nullable ImsReasonInfo info) { 624 mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString( 625 R.string.ims_reg_status_not_registered)); 626 } 627 }; 628 registerImsRegistrationCallback(int subId)629 private void registerImsRegistrationCallback(int subId) { 630 if (!isImsRegistrationStateShowUp()) { 631 return; 632 } 633 try { 634 final ImsMmTelManager imsMmTelMgr = ImsMmTelManager.createForSubscriptionId(subId); 635 imsMmTelMgr.registerImsRegistrationCallback(mDialog.getContext().getMainExecutor(), 636 mImsRegStateCallback); 637 } catch (ImsException exception) { 638 Log.w(TAG, "fail to register IMS status for subId=" + subId, exception); 639 } 640 } 641 unregisterImsRegistrationCallback(int subId)642 private void unregisterImsRegistrationCallback(int subId) { 643 if (!isImsRegistrationStateShowUp()) { 644 return; 645 } 646 final ImsMmTelManager imsMmTelMgr = ImsMmTelManager.createForSubscriptionId(subId); 647 imsMmTelMgr.unregisterImsRegistrationCallback(mImsRegStateCallback); 648 } 649 getPhoneSubscriptionInfo(int slotId)650 private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) { 651 return SubscriptionManager.from(mContext).getActiveSubscriptionInfoForSimSlotIndex(slotId); 652 } 653 getDbm(SignalStrength signalStrength)654 private int getDbm(SignalStrength signalStrength) { 655 List<CellSignalStrength> cellSignalStrengthList = signalStrength.getCellSignalStrengths(); 656 int dbm = -1; 657 if (cellSignalStrengthList == null) { 658 return dbm; 659 } 660 661 for (CellSignalStrength cell : cellSignalStrengthList) { 662 if (cell.getDbm() != -1) { 663 dbm = cell.getDbm(); 664 break; 665 } 666 } 667 668 return dbm; 669 } 670 getAsuLevel(SignalStrength signalStrength)671 private int getAsuLevel(SignalStrength signalStrength) { 672 List<CellSignalStrength> cellSignalStrengthList = signalStrength.getCellSignalStrengths(); 673 int asu = -1; 674 if (cellSignalStrengthList == null) { 675 return asu; 676 } 677 678 for (CellSignalStrength cell : cellSignalStrengthList) { 679 if (cell.getAsuLevel() != -1) { 680 asu = cell.getAsuLevel(); 681 break; 682 } 683 } 684 685 return asu; 686 } 687 688 @VisibleForTesting getPhoneStateListener()689 PhoneStateListener getPhoneStateListener() { 690 return new PhoneStateListener() { 691 @Override 692 public void onDataConnectionStateChanged(int state) { 693 updateDataState(state); 694 updateNetworkType(); 695 } 696 697 @Override 698 public void onSignalStrengthsChanged(SignalStrength signalStrength) { 699 updateSignalStrength(signalStrength); 700 } 701 702 @Override 703 public void onServiceStateChanged(ServiceState serviceState) { 704 updateNetworkProvider(); 705 updateServiceState(serviceState); 706 updateRoamingStatus(serviceState); 707 } 708 709 @Override 710 public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo displayInfo) { 711 mTelephonyDisplayInfo = displayInfo; 712 updateNetworkType(); 713 } 714 }; 715 } 716 717 @VisibleForTesting 718 static String getNetworkTypeName(@Annotation.NetworkType int type) { 719 switch (type) { 720 case TelephonyManager.NETWORK_TYPE_GPRS: 721 return "GPRS"; 722 case TelephonyManager.NETWORK_TYPE_EDGE: 723 return "EDGE"; 724 case TelephonyManager.NETWORK_TYPE_UMTS: 725 return "UMTS"; 726 case TelephonyManager.NETWORK_TYPE_HSDPA: 727 return "HSDPA"; 728 case TelephonyManager.NETWORK_TYPE_HSUPA: 729 return "HSUPA"; 730 case TelephonyManager.NETWORK_TYPE_HSPA: 731 return "HSPA"; 732 case TelephonyManager.NETWORK_TYPE_CDMA: 733 return "CDMA"; 734 case TelephonyManager.NETWORK_TYPE_EVDO_0: 735 return "CDMA - EvDo rev. 0"; 736 case TelephonyManager.NETWORK_TYPE_EVDO_A: 737 return "CDMA - EvDo rev. A"; 738 case TelephonyManager.NETWORK_TYPE_EVDO_B: 739 return "CDMA - EvDo rev. B"; 740 case TelephonyManager.NETWORK_TYPE_1xRTT: 741 return "CDMA - 1xRTT"; 742 case TelephonyManager.NETWORK_TYPE_LTE: 743 return "LTE"; 744 case TelephonyManager.NETWORK_TYPE_EHRPD: 745 return "CDMA - eHRPD"; 746 case TelephonyManager.NETWORK_TYPE_IDEN: 747 return "iDEN"; 748 case TelephonyManager.NETWORK_TYPE_HSPAP: 749 return "HSPA+"; 750 case TelephonyManager.NETWORK_TYPE_GSM: 751 return "GSM"; 752 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: 753 return "TD_SCDMA"; 754 case TelephonyManager.NETWORK_TYPE_IWLAN: 755 return "IWLAN"; 756 // case TelephonyManager.NETWORK_TYPE_LTE_CA: 757 // return "LTE_CA"; 758 case TelephonyManager.NETWORK_TYPE_NR: 759 return "NR SA"; 760 default: 761 return "UNKNOWN"; 762 } 763 } 764 } 765