1 /* 2 * Copyright (C) 2020 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.internal.telephony; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.os.AsyncResult; 24 import android.os.Message; 25 import android.os.PersistableBundle; 26 import android.telephony.AccessNetworkConstants; 27 import android.telephony.Annotation; 28 import android.telephony.CarrierConfigManager; 29 import android.telephony.NetworkRegistrationInfo; 30 import android.telephony.PcoData; 31 import android.telephony.PhysicalChannelConfig; 32 import android.telephony.ServiceState; 33 import android.telephony.SubscriptionManager; 34 import android.telephony.TelephonyDisplayInfo; 35 import android.telephony.TelephonyManager; 36 import android.telephony.data.ApnSetting; 37 import android.text.TextUtils; 38 39 import com.android.internal.telephony.dataconnection.DataConnection; 40 import com.android.internal.telephony.dataconnection.DcController; 41 import com.android.internal.telephony.dataconnection.DcController.PhysicalLinkState; 42 import com.android.internal.telephony.dataconnection.DcTracker; 43 import com.android.internal.telephony.util.ArrayUtils; 44 import com.android.internal.util.IState; 45 import com.android.internal.util.IndentingPrintWriter; 46 import com.android.internal.util.State; 47 import com.android.internal.util.StateMachine; 48 import com.android.telephony.Rlog; 49 50 import java.io.FileDescriptor; 51 import java.io.PrintWriter; 52 import java.util.ArrayList; 53 import java.util.Arrays; 54 import java.util.HashMap; 55 import java.util.List; 56 import java.util.Map; 57 import java.util.regex.Matcher; 58 import java.util.regex.Pattern; 59 import java.util.stream.IntStream; 60 61 /** 62 * The NetworkTypeController evaluates the override network type of {@link TelephonyDisplayInfo} 63 * and sends it to {@link DisplayInfoController}. The override network type can replace the signal 64 * icon displayed on the status bar. It is affected by changes in data RAT, NR state, NR frequency, 65 * data activity, physical channel config, and carrier configurations. Based on carrier configs, 66 * NetworkTypeController also allows timers between various 5G states to prevent flickering. 67 */ 68 public class NetworkTypeController extends StateMachine { 69 private static final boolean DBG = true; 70 private static final String TAG = "NetworkTypeController"; 71 private static final String ICON_5G = "5g"; 72 private static final String ICON_5G_PLUS = "5g_plus"; 73 private static final String STATE_CONNECTED_NR_ADVANCED = "connected_mmwave"; 74 private static final String STATE_CONNECTED = "connected"; 75 private static final String STATE_NOT_RESTRICTED_RRC_IDLE = "not_restricted_rrc_idle"; 76 private static final String STATE_NOT_RESTRICTED_RRC_CON = "not_restricted_rrc_con"; 77 private static final String STATE_RESTRICTED = "restricted"; 78 private static final String STATE_ANY = "any"; 79 private static final String STATE_LEGACY = "legacy"; 80 private static final String[] ALL_STATES = {STATE_CONNECTED_NR_ADVANCED, STATE_CONNECTED, 81 STATE_NOT_RESTRICTED_RRC_IDLE, STATE_NOT_RESTRICTED_RRC_CON, STATE_RESTRICTED, 82 STATE_LEGACY }; 83 84 /** Stop all timers and go to current state. */ 85 public static final int EVENT_UPDATE = 0; 86 /** Quit after processing all existing messages. */ 87 public static final int EVENT_QUIT = 1; 88 private static final int EVENT_DATA_RAT_CHANGED = 2; 89 private static final int EVENT_NR_STATE_CHANGED = 3; 90 private static final int EVENT_NR_FREQUENCY_CHANGED = 4; 91 private static final int EVENT_PHYSICAL_LINK_STATE_CHANGED = 5; 92 private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED = 6; 93 private static final int EVENT_CARRIER_CONFIG_CHANGED = 7; 94 private static final int EVENT_PRIMARY_TIMER_EXPIRED = 8; 95 private static final int EVENT_SECONDARY_TIMER_EXPIRED = 9; 96 private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10; 97 private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 11; 98 private static final int EVENT_INITIALIZE = 12; 99 private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13; 100 private static final int EVENT_PCO_DATA_CHANGED = 14; 101 102 private static final String[] sEvents = new String[EVENT_PCO_DATA_CHANGED + 1]; 103 static { 104 sEvents[EVENT_UPDATE] = "EVENT_UPDATE"; 105 sEvents[EVENT_QUIT] = "EVENT_QUIT"; 106 sEvents[EVENT_DATA_RAT_CHANGED] = "EVENT_DATA_RAT_CHANGED"; 107 sEvents[EVENT_NR_STATE_CHANGED] = "EVENT_NR_STATE_CHANGED"; 108 sEvents[EVENT_NR_FREQUENCY_CHANGED] = "EVENT_NR_FREQUENCY_CHANGED"; 109 sEvents[EVENT_PHYSICAL_LINK_STATE_CHANGED] = "EVENT_PHYSICAL_LINK_STATE_CHANGED"; 110 sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED] = 111 "EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED"; 112 sEvents[EVENT_CARRIER_CONFIG_CHANGED] = "EVENT_CARRIER_CONFIG_CHANGED"; 113 sEvents[EVENT_PRIMARY_TIMER_EXPIRED] = "EVENT_PRIMARY_TIMER_EXPIRED"; 114 sEvents[EVENT_SECONDARY_TIMER_EXPIRED] = "EVENT_SECONDARY_TIMER_EXPIRED"; 115 sEvents[EVENT_RADIO_OFF_OR_UNAVAILABLE] = "EVENT_RADIO_OFF_OR_UNAVAILABLE"; 116 sEvents[EVENT_PREFERRED_NETWORK_MODE_CHANGED] = "EVENT_PREFERRED_NETWORK_MODE_CHANGED"; 117 sEvents[EVENT_INITIALIZE] = "EVENT_INITIALIZE"; 118 sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED] = "EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED"; 119 sEvents[EVENT_PCO_DATA_CHANGED] = "EVENT_PCO_DATA_CHANGED"; 120 } 121 122 private final Phone mPhone; 123 private final DisplayInfoController mDisplayInfoController; 124 private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 125 @Override 126 public void onReceive(Context context, Intent intent) { 127 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED) 128 && intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 129 SubscriptionManager.INVALID_PHONE_INDEX) == mPhone.getPhoneId() 130 && !intent.getBooleanExtra(CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK, 131 false)) { 132 sendMessage(EVENT_CARRIER_CONFIG_CHANGED); 133 } 134 } 135 }; 136 137 private Map<String, OverrideTimerRule> mOverrideTimerRules = new HashMap<>(); 138 private String mLteEnhancedPattern = ""; 139 private int mOverrideNetworkType; 140 private boolean mIsPhysicalChannelConfigOn; 141 private boolean mIsPrimaryTimerActive; 142 private boolean mIsSecondaryTimerActive; 143 private boolean mIsTimerResetEnabledForLegacyStateRRCIdle; 144 private int mLtePlusThresholdBandwidth; 145 private int[] mAdditionalNrAdvancedBandsList; 146 private String mPrimaryTimerState; 147 private String mSecondaryTimerState; 148 private String mPreviousState; 149 private @PhysicalLinkState int mPhysicalLinkState; 150 private boolean mIsPhysicalChannelConfig16Supported; 151 private Boolean mIsNrAdvancedAllowedByPco = false; 152 private int mNrAdvancedCapablePcoId = 0; 153 private boolean mIsUsingUserDataForRrcDetection = false; 154 155 /** 156 * NetworkTypeController constructor. 157 * 158 * @param phone Phone object. 159 * @param displayInfoController DisplayInfoController to send override network types to. 160 */ NetworkTypeController(Phone phone, DisplayInfoController displayInfoController)161 public NetworkTypeController(Phone phone, DisplayInfoController displayInfoController) { 162 super(TAG, displayInfoController); 163 mPhone = phone; 164 mDisplayInfoController = displayInfoController; 165 mOverrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 166 mIsPhysicalChannelConfigOn = true; 167 addState(mDefaultState); 168 addState(mLegacyState, mDefaultState); 169 addState(mIdleState, mDefaultState); 170 addState(mLteConnectedState, mDefaultState); 171 addState(mNrConnectedState, mDefaultState); 172 setInitialState(mDefaultState); 173 start(); 174 sendMessage(EVENT_INITIALIZE); 175 } 176 177 /** 178 * @return The current override network type, used to create TelephonyDisplayInfo in 179 * DisplayInfoController. 180 */ getOverrideNetworkType()181 public @Annotation.OverrideNetworkType int getOverrideNetworkType() { 182 return mOverrideNetworkType; 183 } 184 185 /** 186 * @return True if either the primary or secondary 5G hysteresis timer is active, 187 * and false if neither are. 188 */ is5GHysteresisActive()189 public boolean is5GHysteresisActive() { 190 return mIsPrimaryTimerActive || mIsSecondaryTimerActive; 191 } 192 registerForAllEvents()193 private void registerForAllEvents() { 194 mPhone.registerForRadioOffOrNotAvailable(getHandler(), 195 EVENT_RADIO_OFF_OR_UNAVAILABLE, null); 196 mPhone.registerForPreferredNetworkTypeChanged(getHandler(), 197 EVENT_PREFERRED_NETWORK_MODE_CHANGED, null); 198 mPhone.registerForPhysicalChannelConfig(getHandler(), 199 EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, null); 200 mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged( 201 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler(), 202 EVENT_DATA_RAT_CHANGED, null); 203 mIsPhysicalChannelConfig16Supported = mPhone.getContext().getSystemService( 204 TelephonyManager.class).isRadioInterfaceCapabilitySupported( 205 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED); 206 if (!mIsPhysicalChannelConfig16Supported) { 207 mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 208 .registerForPhysicalLinkStateChanged(getHandler(), 209 EVENT_PHYSICAL_LINK_STATE_CHANGED); 210 } 211 mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(), 212 EVENT_NR_STATE_CHANGED, null); 213 mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(), 214 EVENT_NR_FREQUENCY_CHANGED, null); 215 mPhone.getDeviceStateMonitor().registerForPhysicalChannelConfigNotifChanged(getHandler(), 216 EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED, null); 217 IntentFilter filter = new IntentFilter(); 218 filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 219 mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 220 mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null); 221 } 222 unRegisterForAllEvents()223 private void unRegisterForAllEvents() { 224 mPhone.unregisterForRadioOffOrNotAvailable(getHandler()); 225 mPhone.unregisterForPreferredNetworkTypeChanged(getHandler()); 226 mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged( 227 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler()); 228 mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler()); 229 mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler()); 230 mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler()); 231 mPhone.getContext().unregisterReceiver(mIntentReceiver); 232 mPhone.mCi.unregisterForPcoData(getHandler()); 233 } 234 parseCarrierConfigs()235 private void parseCarrierConfigs() { 236 String nrIconConfiguration = CarrierConfigManager.getDefaultConfig().getString( 237 CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING); 238 String overrideTimerRule = CarrierConfigManager.getDefaultConfig().getString( 239 CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING); 240 String overrideSecondaryTimerRule = CarrierConfigManager.getDefaultConfig().getString( 241 CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING); 242 mLteEnhancedPattern = CarrierConfigManager.getDefaultConfig().getString( 243 CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING); 244 mIsTimerResetEnabledForLegacyStateRRCIdle = 245 CarrierConfigManager.getDefaultConfig().getBoolean( 246 CarrierConfigManager.KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL); 247 mLtePlusThresholdBandwidth = CarrierConfigManager.getDefaultConfig().getInt( 248 CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT); 249 250 CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext() 251 .getSystemService(Context.CARRIER_CONFIG_SERVICE); 252 if (configManager != null) { 253 PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId()); 254 if (b != null) { 255 if (b.getString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING) != null) { 256 nrIconConfiguration = b.getString( 257 CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING); 258 } 259 if (b.getString(CarrierConfigManager 260 .KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING) != null) { 261 overrideTimerRule = b.getString( 262 CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING); 263 } 264 if (b.getString(CarrierConfigManager 265 .KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING) != null) { 266 overrideSecondaryTimerRule = b.getString( 267 CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING); 268 } 269 if (b.getString(CarrierConfigManager 270 .KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING) != null) { 271 mLteEnhancedPattern = b.getString( 272 CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING); 273 } 274 mIsTimerResetEnabledForLegacyStateRRCIdle = b.getBoolean( 275 CarrierConfigManager.KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL); 276 mLtePlusThresholdBandwidth = b.getInt( 277 CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 278 mLtePlusThresholdBandwidth); 279 mAdditionalNrAdvancedBandsList = b.getIntArray( 280 CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY); 281 mNrAdvancedCapablePcoId = b.getInt( 282 CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT); 283 mIsUsingUserDataForRrcDetection = b.getBoolean( 284 CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL); 285 if (mIsPhysicalChannelConfig16Supported && mIsUsingUserDataForRrcDetection) { 286 mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 287 .registerForPhysicalLinkStateChanged(getHandler(), 288 EVENT_PHYSICAL_LINK_STATE_CHANGED); 289 } 290 } 291 } 292 createTimerRules(nrIconConfiguration, overrideTimerRule, overrideSecondaryTimerRule); 293 } 294 createTimerRules(String icons, String timers, String secondaryTimers)295 private void createTimerRules(String icons, String timers, String secondaryTimers) { 296 Map<String, OverrideTimerRule> tempRules = new HashMap<>(); 297 if (!TextUtils.isEmpty(icons)) { 298 // Format: "STATE:ICON,STATE2:ICON2" 299 for (String pair : icons.trim().split(",")) { 300 String[] kv = (pair.trim().toLowerCase()).split(":"); 301 if (kv.length != 2) { 302 if (DBG) loge("Invalid 5G icon configuration, config = " + pair); 303 continue; 304 } 305 int icon = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 306 if (kv[1].equals(ICON_5G)) { 307 icon = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA; 308 } else if (kv[1].equals(ICON_5G_PLUS)) { 309 icon = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED; 310 } else { 311 if (DBG) loge("Invalid 5G icon = " + kv[1]); 312 } 313 tempRules.put(kv[0], new OverrideTimerRule(kv[0], icon)); 314 } 315 } 316 // Ensure all states have an associated OverrideTimerRule and icon 317 for (String state : ALL_STATES) { 318 if (!tempRules.containsKey(state)) { 319 tempRules.put(state, new OverrideTimerRule( 320 state, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE)); 321 } 322 } 323 324 if (!TextUtils.isEmpty(timers)) { 325 // Format: "FROM_STATE,TO_STATE,DURATION;FROM_STATE_2,TO_STATE_2,DURATION_2" 326 for (String triple : timers.trim().split(";")) { 327 String[] kv = (triple.trim().toLowerCase()).split(","); 328 if (kv.length != 3) { 329 if (DBG) loge("Invalid 5G icon timer configuration, config = " + triple); 330 continue; 331 } 332 int duration; 333 try { 334 duration = Integer.parseInt(kv[2]); 335 } catch (NumberFormatException e) { 336 continue; 337 } 338 if (kv[0].equals(STATE_ANY)) { 339 for (String state : ALL_STATES) { 340 OverrideTimerRule node = tempRules.get(state); 341 node.addTimer(kv[1], duration); 342 } 343 } else { 344 OverrideTimerRule node = tempRules.get(kv[0]); 345 node.addTimer(kv[1], duration); 346 } 347 } 348 } 349 350 if (!TextUtils.isEmpty(secondaryTimers)) { 351 // Format: "PRIMARY_STATE,TO_STATE,DURATION;PRIMARY_STATE_2,TO_STATE_2,DURATION_2" 352 for (String triple : secondaryTimers.trim().split(";")) { 353 String[] kv = (triple.trim().toLowerCase()).split(","); 354 if (kv.length != 3) { 355 if (DBG) { 356 loge("Invalid 5G icon secondary timer configuration, config = " + triple); 357 } 358 continue; 359 } 360 int duration; 361 try { 362 duration = Integer.parseInt(kv[2]); 363 } catch (NumberFormatException e) { 364 continue; 365 } 366 if (kv[0].equals(STATE_ANY)) { 367 for (String state : ALL_STATES) { 368 OverrideTimerRule node = tempRules.get(state); 369 node.addSecondaryTimer(kv[1], duration); 370 } 371 } else { 372 OverrideTimerRule node = tempRules.get(kv[0]); 373 node.addSecondaryTimer(kv[1], duration); 374 } 375 } 376 } 377 378 mOverrideTimerRules = tempRules; 379 if (DBG) log("mOverrideTimerRules: " + mOverrideTimerRules); 380 } 381 updateOverrideNetworkType()382 private void updateOverrideNetworkType() { 383 if (mIsPrimaryTimerActive || mIsSecondaryTimerActive) { 384 if (DBG) log("Skip updating override network type since timer is active."); 385 return; 386 } 387 mOverrideNetworkType = getCurrentOverrideNetworkType(); 388 mDisplayInfoController.updateTelephonyDisplayInfo(); 389 } 390 getCurrentOverrideNetworkType()391 private @Annotation.OverrideNetworkType int getCurrentOverrideNetworkType() { 392 int displayNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 393 int dataNetworkType = getDataNetworkType(); 394 boolean nrNsa = isLte(dataNetworkType) 395 && mPhone.getServiceState().getNrState() != NetworkRegistrationInfo.NR_STATE_NONE; 396 boolean nrSa = dataNetworkType == TelephonyManager.NETWORK_TYPE_NR; 397 398 // NR display is not accurate when physical channel config notifications are off 399 if (mIsPhysicalChannelConfigOn && (nrNsa || nrSa)) { 400 // Process NR display network type 401 displayNetworkType = getNrDisplayType(nrSa); 402 if (displayNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) { 403 // Use LTE values if 5G values aren't defined 404 displayNetworkType = getLteDisplayType(); 405 } 406 } else if (isLte(dataNetworkType)) { 407 // Process LTE display network type 408 displayNetworkType = getLteDisplayType(); 409 } 410 return displayNetworkType; 411 } 412 getNrDisplayType(boolean isNrSa)413 private @Annotation.OverrideNetworkType int getNrDisplayType(boolean isNrSa) { 414 // Don't show 5G icon if preferred network type does not include 5G 415 if ((mPhone.getCachedAllowedNetworkTypesBitmask() 416 & TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) { 417 return TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 418 } 419 // Icon display keys in order of priority 420 List<String> keys = new ArrayList<>(); 421 if (isNrSa && isNrAdvanced()) { 422 keys.add(STATE_CONNECTED_NR_ADVANCED); 423 } else { 424 switch (mPhone.getServiceState().getNrState()) { 425 case NetworkRegistrationInfo.NR_STATE_CONNECTED: 426 if (isNrAdvanced()) { 427 keys.add(STATE_CONNECTED_NR_ADVANCED); 428 } 429 keys.add(STATE_CONNECTED); 430 break; 431 case NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED: 432 keys.add(isPhysicalLinkActive() ? STATE_NOT_RESTRICTED_RRC_CON 433 : STATE_NOT_RESTRICTED_RRC_IDLE); 434 break; 435 case NetworkRegistrationInfo.NR_STATE_RESTRICTED: 436 keys.add(STATE_RESTRICTED); 437 break; 438 } 439 } 440 441 for (String key : keys) { 442 OverrideTimerRule rule = mOverrideTimerRules.get(key); 443 if (rule != null && rule.mOverrideType 444 != TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) { 445 return rule.mOverrideType; 446 } 447 } 448 return TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 449 } 450 getLteDisplayType()451 private @Annotation.OverrideNetworkType int getLteDisplayType() { 452 int value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 453 if ((getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA 454 || mPhone.getServiceState().isUsingCarrierAggregation()) 455 && (IntStream.of(mPhone.getServiceState().getCellBandwidths()).sum() 456 > mLtePlusThresholdBandwidth)) { 457 value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA; 458 } 459 if (isLteEnhancedAvailable()) { 460 value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO; 461 } 462 return value; 463 } 464 isLteEnhancedAvailable()465 private boolean isLteEnhancedAvailable() { 466 if (TextUtils.isEmpty(mLteEnhancedPattern)) { 467 return false; 468 } 469 Pattern stringPattern = Pattern.compile(mLteEnhancedPattern); 470 for (String opName : new String[] {mPhone.getServiceState().getOperatorAlphaLongRaw(), 471 mPhone.getServiceState().getOperatorAlphaShortRaw()}) { 472 if (!TextUtils.isEmpty(opName)) { 473 Matcher matcher = stringPattern.matcher(opName); 474 if (matcher.find()) { 475 return true; 476 } 477 } 478 } 479 return false; 480 } 481 482 /** 483 * The parent state for all other states. 484 */ 485 private final class DefaultState extends State { 486 @Override processMessage(Message msg)487 public boolean processMessage(Message msg) { 488 if (DBG) log("DefaultState: process " + getEventName(msg.what)); 489 switch (msg.what) { 490 case EVENT_UPDATE: 491 case EVENT_PREFERRED_NETWORK_MODE_CHANGED: 492 resetAllTimers(); 493 transitionToCurrentState(); 494 break; 495 case EVENT_QUIT: 496 resetAllTimers(); 497 unRegisterForAllEvents(); 498 quit(); 499 break; 500 case EVENT_INITIALIZE: 501 // The reason that we do it here is because some of the works below requires 502 // other modules (e.g. DcTracker, ServiceStateTracker), which is not created 503 // yet when NetworkTypeController is created. 504 registerForAllEvents(); 505 parseCarrierConfigs(); 506 break; 507 case EVENT_DATA_RAT_CHANGED: 508 case EVENT_NR_STATE_CHANGED: 509 case EVENT_NR_FREQUENCY_CHANGED: 510 case EVENT_PCO_DATA_CHANGED: 511 // ignored 512 break; 513 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: 514 if (isUsingPhysicalChannelConfigForRrcDetection()) { 515 mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig(); 516 } 517 break; 518 case EVENT_PHYSICAL_LINK_STATE_CHANGED: 519 AsyncResult ar = (AsyncResult) msg.obj; 520 mPhysicalLinkState = (int) ar.result; 521 break; 522 case EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED: 523 AsyncResult result = (AsyncResult) msg.obj; 524 mIsPhysicalChannelConfigOn = (boolean) result.result; 525 if (DBG) { 526 log("mIsPhysicalChannelConfigOn changed to: " + mIsPhysicalChannelConfigOn); 527 } 528 if (!mIsPhysicalChannelConfigOn) { 529 resetAllTimers(); 530 } 531 transitionToCurrentState(); 532 break; 533 case EVENT_CARRIER_CONFIG_CHANGED: 534 parseCarrierConfigs(); 535 resetAllTimers(); 536 transitionToCurrentState(); 537 break; 538 case EVENT_PRIMARY_TIMER_EXPIRED: 539 transitionWithSecondaryTimerTo((IState) msg.obj); 540 break; 541 case EVENT_SECONDARY_TIMER_EXPIRED: 542 mIsSecondaryTimerActive = false; 543 mSecondaryTimerState = ""; 544 updateTimers(); 545 updateOverrideNetworkType(); 546 break; 547 case EVENT_RADIO_OFF_OR_UNAVAILABLE: 548 resetAllTimers(); 549 transitionTo(mLegacyState); 550 break; 551 default: 552 throw new RuntimeException("Received invalid event: " + msg.what); 553 } 554 return HANDLED; 555 } 556 } 557 558 private final DefaultState mDefaultState = new DefaultState(); 559 560 /** 561 * Device does not have NR available, due to any of the below reasons: 562 * <ul> 563 * <li> LTE cell does not support EN-DC 564 * <li> LTE cell supports EN-DC, but the use of NR is restricted 565 * <li> Data network type is not LTE, NR NSA, or NR SA 566 * </ul> 567 * This is the initial state. 568 */ 569 private final class LegacyState extends State { 570 private Boolean mIsNrRestricted = false; 571 572 @Override enter()573 public void enter() { 574 if (DBG) log("Entering LegacyState"); 575 updateTimers(); 576 updateOverrideNetworkType(); 577 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 578 mIsNrRestricted = isNrRestricted(); 579 mPreviousState = getName(); 580 } 581 } 582 583 @Override processMessage(Message msg)584 public boolean processMessage(Message msg) { 585 if (DBG) log("LegacyState: process " + getEventName(msg.what)); 586 updateTimers(); 587 int rat = getDataNetworkType(); 588 switch (msg.what) { 589 case EVENT_DATA_RAT_CHANGED: 590 if (rat == TelephonyManager.NETWORK_TYPE_NR || isLte(rat) && isNrConnected()) { 591 transitionTo(mNrConnectedState); 592 } else if (isLte(rat) && isNrNotRestricted()) { 593 transitionWithTimerTo(isPhysicalLinkActive() 594 ? mLteConnectedState : mIdleState); 595 } else { 596 if (!isLte(rat)) { 597 // Rat is 3G or 2G, and it doesn't need NR timer. 598 resetAllTimers(); 599 } 600 updateOverrideNetworkType(); 601 } 602 mIsNrRestricted = isNrRestricted(); 603 break; 604 case EVENT_NR_STATE_CHANGED: 605 if (isNrConnected()) { 606 transitionTo(mNrConnectedState); 607 } else if (isLte(rat) && isNrNotRestricted()) { 608 transitionWithTimerTo(isPhysicalLinkActive() 609 ? mLteConnectedState : mIdleState); 610 } else if (isLte(rat) && isNrRestricted()) { 611 updateOverrideNetworkType(); 612 } 613 mIsNrRestricted = isNrRestricted(); 614 break; 615 case EVENT_NR_FREQUENCY_CHANGED: 616 // ignored 617 break; 618 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: 619 if (isUsingPhysicalChannelConfigForRrcDetection()) { 620 mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig(); 621 if (mIsTimerResetEnabledForLegacyStateRRCIdle && !isPhysicalLinkActive()) { 622 resetAllTimers(); 623 } 624 } 625 // Update in case of LTE/LTE+ switch 626 updateOverrideNetworkType(); 627 break; 628 case EVENT_PHYSICAL_LINK_STATE_CHANGED: 629 AsyncResult ar = (AsyncResult) msg.obj; 630 mPhysicalLinkState = (int) ar.result; 631 if (mIsTimerResetEnabledForLegacyStateRRCIdle && !isPhysicalLinkActive()) { 632 resetAllTimers(); 633 updateOverrideNetworkType(); 634 } 635 break; 636 default: 637 return NOT_HANDLED; 638 } 639 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 640 mPreviousState = getName(); 641 } 642 return HANDLED; 643 } 644 645 @Override getName()646 public String getName() { 647 return mIsNrRestricted ? STATE_RESTRICTED : STATE_LEGACY; 648 } 649 } 650 651 private final LegacyState mLegacyState = new LegacyState(); 652 653 /** 654 * Device does not have any physical connection with the cell (RRC idle). 655 */ 656 private final class IdleState extends State { 657 @Override enter()658 public void enter() { 659 if (DBG) log("Entering IdleState"); 660 updateTimers(); 661 updateOverrideNetworkType(); 662 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 663 mPreviousState = getName(); 664 } 665 } 666 667 @Override processMessage(Message msg)668 public boolean processMessage(Message msg) { 669 if (DBG) log("IdleState: process " + getEventName(msg.what)); 670 updateTimers(); 671 switch (msg.what) { 672 case EVENT_DATA_RAT_CHANGED: 673 int rat = getDataNetworkType(); 674 if (rat == TelephonyManager.NETWORK_TYPE_NR) { 675 transitionTo(mNrConnectedState); 676 } else if (!isLte(rat) || !isNrNotRestricted()) { 677 transitionWithTimerTo(mLegacyState); 678 } 679 break; 680 case EVENT_NR_STATE_CHANGED: 681 if (isNrConnected()) { 682 transitionTo(mNrConnectedState); 683 } else if (!isNrNotRestricted()) { 684 transitionWithTimerTo(mLegacyState); 685 } 686 break; 687 case EVENT_NR_FREQUENCY_CHANGED: 688 // ignore 689 break; 690 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: 691 if (isUsingPhysicalChannelConfigForRrcDetection()) { 692 mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig(); 693 if (isNrNotRestricted()) { 694 // NOT_RESTRICTED_RRC_IDLE -> NOT_RESTRICTED_RRC_CON 695 if (isPhysicalLinkActive()) { 696 transitionWithTimerTo(mLteConnectedState); 697 break; 698 } 699 } else { 700 log("NR state changed. Sending EVENT_NR_STATE_CHANGED"); 701 sendMessage(EVENT_NR_STATE_CHANGED); 702 } 703 } 704 // Update in case of LTE/LTE+ switch 705 updateOverrideNetworkType(); 706 break; 707 case EVENT_PHYSICAL_LINK_STATE_CHANGED: 708 AsyncResult ar = (AsyncResult) msg.obj; 709 mPhysicalLinkState = (int) ar.result; 710 if (isNrNotRestricted()) { 711 // NOT_RESTRICTED_RRC_IDLE -> NOT_RESTRICTED_RRC_CON 712 if (isPhysicalLinkActive()) { 713 transitionWithTimerTo(mLteConnectedState); 714 } 715 } else { 716 log("NR state changed. Sending EVENT_NR_STATE_CHANGED"); 717 sendMessage(EVENT_NR_STATE_CHANGED); 718 } 719 break; 720 default: 721 return NOT_HANDLED; 722 } 723 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 724 mPreviousState = getName(); 725 } 726 return HANDLED; 727 } 728 729 @Override getName()730 public String getName() { 731 return STATE_NOT_RESTRICTED_RRC_IDLE; 732 } 733 } 734 735 private final IdleState mIdleState = new IdleState(); 736 737 /** 738 * Device is connected to LTE as the primary cell (RRC connected). 739 */ 740 private final class LteConnectedState extends State { 741 @Override enter()742 public void enter() { 743 if (DBG) log("Entering LteConnectedState"); 744 updateTimers(); 745 updateOverrideNetworkType(); 746 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 747 mPreviousState = getName(); 748 } 749 } 750 751 @Override processMessage(Message msg)752 public boolean processMessage(Message msg) { 753 if (DBG) log("LteConnectedState: process " + getEventName(msg.what)); 754 updateTimers(); 755 switch (msg.what) { 756 case EVENT_DATA_RAT_CHANGED: 757 int rat = getDataNetworkType(); 758 if (rat == TelephonyManager.NETWORK_TYPE_NR) { 759 transitionTo(mNrConnectedState); 760 } else if (!isLte(rat) || !isNrNotRestricted()) { 761 transitionWithTimerTo(mLegacyState); 762 } 763 break; 764 case EVENT_NR_STATE_CHANGED: 765 if (isNrConnected()) { 766 transitionTo(mNrConnectedState); 767 } else if (!isNrNotRestricted()) { 768 transitionWithTimerTo(mLegacyState); 769 } 770 break; 771 case EVENT_NR_FREQUENCY_CHANGED: 772 // ignore 773 break; 774 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: 775 if (isUsingPhysicalChannelConfigForRrcDetection()) { 776 mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig(); 777 if (isNrNotRestricted()) { 778 // NOT_RESTRICTED_RRC_CON -> NOT_RESTRICTED_RRC_IDLE 779 if (!isPhysicalLinkActive()) { 780 transitionWithTimerTo(mIdleState); 781 break; 782 } 783 } else { 784 log("NR state changed. Sending EVENT_NR_STATE_CHANGED"); 785 sendMessage(EVENT_NR_STATE_CHANGED); 786 } 787 } 788 // Update in case of LTE/LTE+ switch 789 updateOverrideNetworkType(); 790 break; 791 case EVENT_PHYSICAL_LINK_STATE_CHANGED: 792 AsyncResult ar = (AsyncResult) msg.obj; 793 mPhysicalLinkState = (int) ar.result; 794 if (isNrNotRestricted()) { 795 // NOT_RESTRICTED_RRC_CON -> NOT_RESTRICTED_RRC_IDLE 796 if (!isPhysicalLinkActive()) { 797 transitionWithTimerTo(mIdleState); 798 } 799 } else { 800 log("NR state changed. Sending EVENT_NR_STATE_CHANGED"); 801 sendMessage(EVENT_NR_STATE_CHANGED); 802 } 803 break; 804 default: 805 return NOT_HANDLED; 806 } 807 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 808 mPreviousState = getName(); 809 } 810 return HANDLED; 811 } 812 813 @Override getName()814 public String getName() { 815 return STATE_NOT_RESTRICTED_RRC_CON; 816 } 817 } 818 819 private final LteConnectedState mLteConnectedState = new LteConnectedState(); 820 821 /** 822 * Device is connected to 5G NR as the secondary cell. 823 */ 824 private final class NrConnectedState extends State { 825 private Boolean mIsNrAdvanced = false; 826 827 @Override enter()828 public void enter() { 829 if (DBG) log("Entering NrConnectedState"); 830 updateTimers(); 831 updateOverrideNetworkType(); 832 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 833 mIsNrAdvanced = isNrAdvanced(); 834 mPreviousState = getName(); 835 } 836 } 837 838 @Override processMessage(Message msg)839 public boolean processMessage(Message msg) { 840 if (DBG) log("NrConnectedState: process " + getEventName(msg.what)); 841 updateTimers(); 842 int rat = getDataNetworkType(); 843 switch (msg.what) { 844 case EVENT_DATA_RAT_CHANGED: 845 if (rat == TelephonyManager.NETWORK_TYPE_NR || isLte(rat) && isNrConnected()) { 846 updateOverrideNetworkType(); 847 } else if (isLte(rat) && isNrNotRestricted()) { 848 transitionWithTimerTo(isPhysicalLinkActive() 849 ? mLteConnectedState : mIdleState); 850 } else { 851 transitionWithTimerTo(mLegacyState); 852 } 853 break; 854 case EVENT_NR_STATE_CHANGED: 855 if (isLte(rat) && isNrNotRestricted()) { 856 transitionWithTimerTo(isPhysicalLinkActive() 857 ? mLteConnectedState : mIdleState); 858 } else if (rat != TelephonyManager.NETWORK_TYPE_NR && !isNrConnected()) { 859 transitionWithTimerTo(mLegacyState); 860 } 861 break; 862 case EVENT_PCO_DATA_CHANGED: 863 handlePcoData((AsyncResult) msg.obj); 864 break; 865 case EVENT_NR_FREQUENCY_CHANGED: 866 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: 867 if (isUsingPhysicalChannelConfigForRrcDetection()) { 868 mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig(); 869 } 870 updateNrAdvancedState(); 871 break; 872 case EVENT_PHYSICAL_LINK_STATE_CHANGED: 873 AsyncResult ar = (AsyncResult) msg.obj; 874 mPhysicalLinkState = (int) ar.result; 875 if (!isNrConnected()) { 876 log("NR state changed. Sending EVENT_NR_STATE_CHANGED"); 877 sendMessage(EVENT_NR_STATE_CHANGED); 878 } 879 break; 880 default: 881 return NOT_HANDLED; 882 } 883 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 884 mPreviousState = getName(); 885 } 886 return HANDLED; 887 } 888 889 @Override getName()890 public String getName() { 891 return mIsNrAdvanced ? STATE_CONNECTED_NR_ADVANCED : STATE_CONNECTED; 892 } 893 updateNrAdvancedState()894 private void updateNrAdvancedState() { 895 if (!isNrConnected()) { 896 log("NR state changed. Sending EVENT_NR_STATE_CHANGED"); 897 sendMessage(EVENT_NR_STATE_CHANGED); 898 return; 899 } 900 if (!isNrAdvanced()) { 901 // STATE_CONNECTED_NR_ADVANCED -> STATE_CONNECTED 902 transitionWithTimerTo(mNrConnectedState); 903 } else { 904 // STATE_CONNECTED -> STATE_CONNECTED_NR_ADVANCED 905 transitionTo(mNrConnectedState); 906 } 907 mIsNrAdvanced = isNrAdvanced(); 908 } 909 handlePcoData(AsyncResult ar)910 private void handlePcoData(AsyncResult ar) { 911 if (ar.exception != null) { 912 loge("PCO_DATA exception: " + ar.exception); 913 return; 914 } 915 PcoData pcodata = (PcoData) ar.result; 916 if (pcodata == null) { 917 return; 918 } 919 log("EVENT_PCO_DATA_CHANGED: pco data: " + pcodata); 920 DcTracker dcTracker = mPhone.getDcTracker( 921 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 922 DataConnection dc = 923 dcTracker != null ? dcTracker.getDataConnectionByContextId(pcodata.cid) : null; 924 ApnSetting apnSettings = dc != null ? dc.getApnSetting() : null; 925 if (apnSettings != null && apnSettings.canHandleType(ApnSetting.TYPE_DEFAULT) 926 && mNrAdvancedCapablePcoId > 0 927 && pcodata.pcoId == mNrAdvancedCapablePcoId 928 ) { 929 log("EVENT_PCO_DATA_CHANGED: Nr Advanced is allowed by PCO."); 930 mIsNrAdvancedAllowedByPco = pcodata.contents[0] == 1; 931 updateNrAdvancedState(); 932 } 933 } 934 } 935 936 private final NrConnectedState mNrConnectedState = new NrConnectedState(); 937 transitionWithTimerTo(IState destState)938 private void transitionWithTimerTo(IState destState) { 939 String destName = destState.getName(); 940 OverrideTimerRule rule = mOverrideTimerRules.get(mPreviousState); 941 if (rule != null && rule.getTimer(destName) > 0) { 942 if (DBG) log("Primary timer started for state: " + mPreviousState); 943 mPrimaryTimerState = mPreviousState; 944 mPreviousState = getCurrentState().getName(); 945 mIsPrimaryTimerActive = true; 946 sendMessageDelayed(EVENT_PRIMARY_TIMER_EXPIRED, destState, 947 rule.getTimer(destName) * 1000); 948 } 949 transitionTo(destState); 950 } 951 transitionWithSecondaryTimerTo(IState destState)952 private void transitionWithSecondaryTimerTo(IState destState) { 953 String currentName = getCurrentState().getName(); 954 OverrideTimerRule rule = mOverrideTimerRules.get(mPrimaryTimerState); 955 if (rule != null && rule.getSecondaryTimer(currentName) > 0) { 956 if (DBG) log("Secondary timer started for state: " + currentName); 957 mSecondaryTimerState = currentName; 958 mPreviousState = currentName; 959 mIsSecondaryTimerActive = true; 960 sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState, 961 rule.getSecondaryTimer(currentName) * 1000); 962 } 963 mIsPrimaryTimerActive = false; 964 transitionTo(getCurrentState()); 965 } 966 transitionToCurrentState()967 private void transitionToCurrentState() { 968 int dataRat = getDataNetworkType(); 969 IState transitionState; 970 if (dataRat == TelephonyManager.NETWORK_TYPE_NR || isNrConnected()) { 971 transitionState = mNrConnectedState; 972 mPreviousState = isNrAdvanced() ? STATE_CONNECTED_NR_ADVANCED : STATE_CONNECTED; 973 } else if (isLte(dataRat) && isNrNotRestricted()) { 974 if (isPhysicalLinkActive()) { 975 transitionState = mLteConnectedState; 976 mPreviousState = STATE_NOT_RESTRICTED_RRC_CON; 977 } else { 978 transitionState = mIdleState; 979 mPreviousState = STATE_NOT_RESTRICTED_RRC_IDLE; 980 } 981 } else { 982 transitionState = mLegacyState; 983 mPreviousState = isNrRestricted() ? STATE_RESTRICTED : STATE_LEGACY; 984 } 985 if (!transitionState.equals(getCurrentState())) { 986 transitionTo(transitionState); 987 } else { 988 updateOverrideNetworkType(); 989 } 990 } 991 updateTimers()992 private void updateTimers() { 993 String currentState = getCurrentState().getName(); 994 995 if (mIsPrimaryTimerActive && getOverrideNetworkType() == getCurrentOverrideNetworkType()) { 996 // remove primary timer if device goes back to the original icon 997 if (DBG) { 998 log("Remove primary timer since icon of primary state and current icon equal: " 999 + mPrimaryTimerState); 1000 } 1001 removeMessages(EVENT_PRIMARY_TIMER_EXPIRED); 1002 mIsPrimaryTimerActive = false; 1003 mPrimaryTimerState = ""; 1004 } 1005 1006 if (mIsSecondaryTimerActive && !mSecondaryTimerState.equals(currentState)) { 1007 // remove secondary timer if devices is no longer in secondary timer state 1008 if (DBG) { 1009 log("Remove secondary timer since current state (" + currentState 1010 + ") is no longer secondary timer state (" + mSecondaryTimerState + ")."); 1011 } 1012 removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); 1013 mIsSecondaryTimerActive = false; 1014 mSecondaryTimerState = ""; 1015 } 1016 1017 if (currentState.equals(STATE_CONNECTED_NR_ADVANCED)) { 1018 resetAllTimers(); 1019 } 1020 1021 int rat = getDataNetworkType(); 1022 if (!isLte(rat) && rat != TelephonyManager.NETWORK_TYPE_NR) { 1023 // Rat is 3G or 2G, and it doesn't need NR timer. 1024 resetAllTimers(); 1025 } 1026 } 1027 resetAllTimers()1028 private void resetAllTimers() { 1029 if (DBG) { 1030 log("Remove all timers"); 1031 } 1032 removeMessages(EVENT_PRIMARY_TIMER_EXPIRED); 1033 removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); 1034 mIsPrimaryTimerActive = false; 1035 mIsSecondaryTimerActive = false; 1036 mPrimaryTimerState = ""; 1037 mSecondaryTimerState = ""; 1038 } 1039 1040 /** 1041 * Private class defining timer rules between states to prevent flickering. These rules are 1042 * created in {@link #parseCarrierConfigs()} based on various carrier configs. 1043 */ 1044 private class OverrideTimerRule { 1045 /** The 5G state this timer rule applies for. See {@link #ALL_STATES}. */ 1046 final String mState; 1047 1048 /** 1049 * The override network type associated with this 5G state. This is the icon that will be 1050 * displayed on the status bar. An override type of NONE will display the LTE value instead. 1051 */ 1052 final int mOverrideType; 1053 1054 /** 1055 * A map of destination states and associated timers. If the 5G state changes from mState 1056 * to the destination state, keep the override type until either the primary timer expires 1057 * or mState is regained. 1058 */ 1059 final Map<String, Integer> mPrimaryTimers; 1060 1061 /** 1062 * A map of secondary states and associated timers. After the primary timer expires, keep 1063 * the override type until either the secondary timer expires or the device is no longer in 1064 * the secondary state. 1065 */ 1066 final Map<String, Integer> mSecondaryTimers; 1067 OverrideTimerRule(String state, int overrideType)1068 OverrideTimerRule(String state, int overrideType) { 1069 mState = state; 1070 mOverrideType = overrideType; 1071 mPrimaryTimers = new HashMap<>(); 1072 mSecondaryTimers = new HashMap<>(); 1073 } 1074 1075 /** 1076 * Add a primary timer. 1077 * @param destination Transitions from mState to the destination state. 1078 * @param duration How long to keep the override type after transition to destination state. 1079 */ addTimer(String destination, int duration)1080 public void addTimer(String destination, int duration) { 1081 mPrimaryTimers.put(destination, duration); 1082 } 1083 1084 /** 1085 * Add a secondary timer 1086 * @param secondaryState Stays in secondaryState after primary timer expires. 1087 * @param duration How long to keep the override type while in secondaryState. 1088 */ addSecondaryTimer(String secondaryState, int duration)1089 public void addSecondaryTimer(String secondaryState, int duration) { 1090 mSecondaryTimers.put(secondaryState, duration); 1091 } 1092 1093 /** 1094 * @return Primary timer duration from mState to destination state, or 0 if not defined. 1095 */ getTimer(String destination)1096 public int getTimer(String destination) { 1097 Integer timer = mPrimaryTimers.get(destination); 1098 timer = timer == null ? mPrimaryTimers.get(STATE_ANY) : timer; 1099 return timer == null ? 0 : timer; 1100 } 1101 1102 /** 1103 * @return Secondary timer duration for secondaryState, or 0 if not defined. 1104 */ getSecondaryTimer(String secondaryState)1105 public int getSecondaryTimer(String secondaryState) { 1106 Integer secondaryTimer = mSecondaryTimers.get(secondaryState); 1107 secondaryTimer = secondaryTimer == null 1108 ? mSecondaryTimers.get(STATE_ANY) : secondaryTimer; 1109 return secondaryTimer == null ? 0 : secondaryTimer; 1110 } 1111 1112 @Override toString()1113 public String toString() { 1114 return "{mState=" + mState 1115 + ", mOverrideType=" 1116 + TelephonyDisplayInfo.overrideNetworkTypeToString(mOverrideType) 1117 + ", mPrimaryTimers=" + mPrimaryTimers 1118 + ", mSecondaryTimers=" + mSecondaryTimers + "}"; 1119 } 1120 } 1121 isNrConnected()1122 private boolean isNrConnected() { 1123 return mPhone.getServiceState().getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED; 1124 } 1125 isNrNotRestricted()1126 private boolean isNrNotRestricted() { 1127 return mPhone.getServiceState().getNrState() 1128 == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED; 1129 } 1130 isNrRestricted()1131 private boolean isNrRestricted() { 1132 return mPhone.getServiceState().getNrState() 1133 == NetworkRegistrationInfo.NR_STATE_RESTRICTED; 1134 } 1135 isNrAdvanced()1136 private boolean isNrAdvanced() { 1137 return isNrAdvancedCapable() && (isNrMmwave() || isAdditionalNrAdvancedBand()); 1138 } 1139 isNrMmwave()1140 private boolean isNrMmwave() { 1141 return mPhone.getServiceState().getNrFrequencyRange() 1142 == ServiceState.FREQUENCY_RANGE_MMWAVE; 1143 } 1144 isAdditionalNrAdvancedBand()1145 private boolean isAdditionalNrAdvancedBand() { 1146 List<PhysicalChannelConfig> physicalChannelConfigList = 1147 mPhone.getServiceStateTracker().getPhysicalChannelConfigList(); 1148 if (ArrayUtils.isEmpty(mAdditionalNrAdvancedBandsList) 1149 || physicalChannelConfigList == null) { 1150 return false; 1151 } 1152 for (PhysicalChannelConfig item : physicalChannelConfigList) { 1153 if (item.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR 1154 && ArrayUtils.contains(mAdditionalNrAdvancedBandsList, item.getBand())) { 1155 return true; 1156 } 1157 } 1158 return false; 1159 } 1160 isNrAdvancedCapable()1161 private boolean isNrAdvancedCapable() { 1162 if (mNrAdvancedCapablePcoId > 0) { 1163 return mIsNrAdvancedAllowedByPco; 1164 } 1165 return true; 1166 } 1167 isLte(int rat)1168 private boolean isLte(int rat) { 1169 return rat == TelephonyManager.NETWORK_TYPE_LTE 1170 || rat == TelephonyManager.NETWORK_TYPE_LTE_CA; 1171 } 1172 isPhysicalLinkActive()1173 private boolean isPhysicalLinkActive() { 1174 return mPhysicalLinkState == DcController.PHYSICAL_LINK_ACTIVE; 1175 } 1176 getPhysicalLinkStateFromPhysicalChannelConfig()1177 private int getPhysicalLinkStateFromPhysicalChannelConfig() { 1178 List<PhysicalChannelConfig> physicalChannelConfigList = 1179 mPhone.getServiceStateTracker().getPhysicalChannelConfigList(); 1180 return (physicalChannelConfigList == null || physicalChannelConfigList.isEmpty()) 1181 ? DcController.PHYSICAL_LINK_NOT_ACTIVE : DcController.PHYSICAL_LINK_ACTIVE; 1182 } 1183 getDataNetworkType()1184 private int getDataNetworkType() { 1185 NetworkRegistrationInfo nri = mPhone.getServiceState().getNetworkRegistrationInfo( 1186 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1187 return nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN 1188 : nri.getAccessNetworkTechnology(); 1189 } 1190 getEventName(int event)1191 private String getEventName(int event) { 1192 try { 1193 return sEvents[event]; 1194 } catch (ArrayIndexOutOfBoundsException e) { 1195 return "EVENT_NOT_DEFINED"; 1196 } 1197 } 1198 isUsingPhysicalChannelConfigForRrcDetection()1199 private boolean isUsingPhysicalChannelConfigForRrcDetection() { 1200 return mIsPhysicalChannelConfig16Supported && !mIsUsingUserDataForRrcDetection; 1201 } 1202 log(String s)1203 protected void log(String s) { 1204 Rlog.d(TAG, "[" + mPhone.getPhoneId() + "] " + s); 1205 } 1206 loge(String s)1207 protected void loge(String s) { 1208 Rlog.e(TAG, "[" + mPhone.getPhoneId() + "] " + s); 1209 } 1210 1211 @Override toString()1212 public String toString() { 1213 return "mOverrideTimerRules=" + mOverrideTimerRules.toString() 1214 + ", mLteEnhancedPattern=" + mLteEnhancedPattern 1215 + ", mIsPhysicalChannelConfigOn=" + mIsPhysicalChannelConfigOn 1216 + ", mIsPrimaryTimerActive=" + mIsPrimaryTimerActive 1217 + ", mIsSecondaryTimerActive=" + mIsSecondaryTimerActive 1218 + ", mPrimaryTimerState=" + mPrimaryTimerState 1219 + ", mSecondaryTimerState=" + mSecondaryTimerState 1220 + ", mPreviousState=" + mPreviousState 1221 + ", misNrAdvanced=" + isNrAdvanced(); 1222 } 1223 1224 @Override dump(FileDescriptor fd, PrintWriter printWriter, String[] args)1225 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 1226 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 1227 pw.print("NetworkTypeController: "); 1228 super.dump(fd, pw, args); 1229 pw.flush(); 1230 pw.increaseIndent(); 1231 pw.println("mSubId=" + mPhone.getSubId()); 1232 pw.println("mOverrideTimerRules=" + mOverrideTimerRules.toString()); 1233 pw.println("mLteEnhancedPattern=" + mLteEnhancedPattern); 1234 pw.println("mIsPhysicalChannelConfigOn=" + mIsPhysicalChannelConfigOn); 1235 pw.println("mIsPrimaryTimerActive=" + mIsPrimaryTimerActive); 1236 pw.println("mIsSecondaryTimerActive=" + mIsSecondaryTimerActive); 1237 pw.println("mIsTimerRestEnabledForLegacyStateRRCIdle=" 1238 + mIsTimerResetEnabledForLegacyStateRRCIdle); 1239 pw.println("mLtePlusThresholdBandwidth=" + mLtePlusThresholdBandwidth); 1240 pw.println("mPrimaryTimerState=" + mPrimaryTimerState); 1241 pw.println("mSecondaryTimerState=" + mSecondaryTimerState); 1242 pw.println("mPreviousState=" + mPreviousState); 1243 pw.println("mPhysicalLinkState=" + mPhysicalLinkState); 1244 pw.println("mAdditionalNrAdvancedBandsList=" 1245 + Arrays.toString(mAdditionalNrAdvancedBandsList)); 1246 pw.println("mNrAdvancedCapablePcoId=" + mNrAdvancedCapablePcoId); 1247 pw.decreaseIndent(); 1248 pw.flush(); 1249 } 1250 } 1251