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.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.net.ConnectivityManager; 26 import android.net.Network; 27 import android.net.NetworkCapabilities; 28 import android.net.NetworkRequest; 29 import android.os.AsyncResult; 30 import android.os.Handler; 31 import android.os.HandlerThread; 32 import android.os.Message; 33 import android.os.PersistableBundle; 34 import android.os.PowerManager; 35 import android.os.SystemClock; 36 import android.telephony.AccessNetworkConstants; 37 import android.telephony.Annotation; 38 import android.telephony.CarrierConfigManager; 39 import android.telephony.CellInfo; 40 import android.telephony.NetworkRegistrationInfo; 41 import android.telephony.PhysicalChannelConfig; 42 import android.telephony.ServiceState; 43 import android.telephony.TelephonyDisplayInfo; 44 import android.telephony.TelephonyManager; 45 import android.telephony.data.DataCallResponse; 46 import android.telephony.data.DataCallResponse.LinkStatus; 47 import android.telephony.data.EpsQos; 48 import android.telephony.data.NrQos; 49 import android.telephony.data.QosBearerSession; 50 import android.text.TextUtils; 51 52 import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; 53 import com.android.internal.telephony.data.DataUtils; 54 import com.android.internal.telephony.flags.FeatureFlags; 55 import com.android.internal.util.IState; 56 import com.android.internal.util.IndentingPrintWriter; 57 import com.android.internal.util.State; 58 import com.android.internal.util.StateMachine; 59 import com.android.telephony.Rlog; 60 61 import java.io.FileDescriptor; 62 import java.io.PrintWriter; 63 import java.util.ArrayList; 64 import java.util.Arrays; 65 import java.util.HashMap; 66 import java.util.HashSet; 67 import java.util.List; 68 import java.util.Locale; 69 import java.util.Map; 70 import java.util.Set; 71 import java.util.regex.Matcher; 72 import java.util.regex.Pattern; 73 import java.util.stream.IntStream; 74 75 /** 76 * The NetworkTypeController evaluates the override network type of {@link TelephonyDisplayInfo} 77 * and sends it to {@link DisplayInfoController}. The override network type can replace the signal 78 * icon displayed on the status bar. It is affected by changes in data RAT, NR state, NR frequency, 79 * data activity, physical channel config, and carrier configurations. Based on carrier configs, 80 * NetworkTypeController also allows timers between various 5G states to prevent flickering. 81 */ 82 public class NetworkTypeController extends StateMachine { 83 private static final boolean DBG = true; 84 private static final String TAG = "NetworkTypeController"; 85 private static final String ICON_5G = "5g"; 86 private static final String ICON_5G_PLUS = "5g_plus"; 87 private static final String STATE_CONNECTED_NR_ADVANCED = "connected_mmwave"; 88 private static final String STATE_CONNECTED_RRC_IDLE = "connected_rrc_idle"; 89 private static final String STATE_CONNECTED = "connected"; 90 private static final String STATE_NOT_RESTRICTED_RRC_IDLE = "not_restricted_rrc_idle"; 91 private static final String STATE_NOT_RESTRICTED_RRC_CON = "not_restricted_rrc_con"; 92 private static final String STATE_RESTRICTED = "restricted"; 93 private static final String STATE_ANY = "any"; 94 private static final String STATE_LEGACY = "legacy"; 95 private static final String[] ALL_STATES = {STATE_CONNECTED_NR_ADVANCED, STATE_CONNECTED, 96 STATE_CONNECTED_RRC_IDLE, STATE_NOT_RESTRICTED_RRC_IDLE, STATE_NOT_RESTRICTED_RRC_CON, 97 STATE_RESTRICTED, STATE_LEGACY }; 98 99 /** Stop all timers and go to current state. */ 100 public static final int EVENT_UPDATE = 0; 101 /** Quit after processing all existing messages. */ 102 private static final int EVENT_QUIT = 1; 103 /** Initialize all events. */ 104 private static final int EVENT_INITIALIZE = 2; 105 /** Event for service state changed (data rat, bandwidth, NR state, NR frequency, etc). */ 106 private static final int EVENT_SERVICE_STATE_CHANGED = 3; 107 /** Event for physical link status changed. */ 108 private static final int EVENT_PHYSICAL_LINK_STATUS_CHANGED = 4; 109 /** Event for physical channel config indications turned on/off. */ 110 private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED = 5; 111 /** Event for carrier configs changed. */ 112 private static final int EVENT_CARRIER_CONFIG_CHANGED = 6; 113 /** Event for primary timer expired. If a secondary timer exists, it will begin afterwards. */ 114 private static final int EVENT_PRIMARY_TIMER_EXPIRED = 7; 115 /** Event for secondary timer expired. */ 116 private static final int EVENT_SECONDARY_TIMER_EXPIRED = 8; 117 /** Event for radio off or unavailable. */ 118 private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 9; 119 /** Event for preferred network mode changed. */ 120 private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 10; 121 /** Event for physical channel configs changed. */ 122 private static final int EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED = 11; 123 /** Event for device idle mode changed, when device goes to deep sleep and pauses all timers. */ 124 private static final int EVENT_DEVICE_IDLE_MODE_CHANGED = 12; 125 /** Event for qos sessions changed. */ 126 private static final int EVENT_QOS_SESSION_CHANGED = 13; 127 128 private static final String[] sEvents = new String[EVENT_QOS_SESSION_CHANGED + 1]; 129 static { 130 sEvents[EVENT_UPDATE] = "EVENT_UPDATE"; 131 sEvents[EVENT_QUIT] = "EVENT_QUIT"; 132 sEvents[EVENT_SERVICE_STATE_CHANGED] = "EVENT_SERVICE_STATE_CHANGED"; 133 sEvents[EVENT_PHYSICAL_LINK_STATUS_CHANGED] = "EVENT_PHYSICAL_LINK_STATUS_CHANGED"; 134 sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED] = 135 "EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED"; 136 sEvents[EVENT_CARRIER_CONFIG_CHANGED] = "EVENT_CARRIER_CONFIG_CHANGED"; 137 sEvents[EVENT_PRIMARY_TIMER_EXPIRED] = "EVENT_PRIMARY_TIMER_EXPIRED"; 138 sEvents[EVENT_SECONDARY_TIMER_EXPIRED] = "EVENT_SECONDARY_TIMER_EXPIRED"; 139 sEvents[EVENT_RADIO_OFF_OR_UNAVAILABLE] = "EVENT_RADIO_OFF_OR_UNAVAILABLE"; 140 sEvents[EVENT_PREFERRED_NETWORK_MODE_CHANGED] = "EVENT_PREFERRED_NETWORK_MODE_CHANGED"; 141 sEvents[EVENT_INITIALIZE] = "EVENT_INITIALIZE"; 142 sEvents[EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED] = "EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED"; 143 sEvents[EVENT_DEVICE_IDLE_MODE_CHANGED] = "EVENT_DEVICE_IDLE_MODE_CHANGED"; 144 sEvents[EVENT_QOS_SESSION_CHANGED] = "EVENT_QOS_SESSION_CHANGED"; 145 } 146 147 @NonNull private final Phone mPhone; 148 @NonNull private final DisplayInfoController mDisplayInfoController; 149 @NonNull private final FeatureFlags mFeatureFlags; 150 @NonNull private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 151 @Override 152 public void onReceive(Context context, Intent intent) { 153 switch (intent.getAction()) { 154 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: 155 sendMessage(EVENT_DEVICE_IDLE_MODE_CHANGED); 156 break; 157 } 158 } 159 }; 160 161 @NonNull private final CarrierConfigManager.CarrierConfigChangeListener 162 mCarrierConfigChangeListener = 163 new CarrierConfigManager.CarrierConfigChangeListener() { 164 @Override 165 public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId, 166 int specificCarrierId) { 167 // CarrierConfigChangeListener wouldn't send notification on device unlock 168 if (slotIndex == mPhone.getPhoneId()) { 169 sendMessage(EVENT_CARRIER_CONFIG_CHANGED); 170 } 171 } 172 }; 173 174 @NonNull private final DataNetworkControllerCallback mDataNetworkControllerCallback = 175 new DataNetworkControllerCallback(getHandler()::post) { 176 @Override 177 public void onQosSessionsChanged( 178 @NonNull List<QosBearerSession> qosBearerSessions) { 179 sendMessage(obtainMessage(EVENT_QOS_SESSION_CHANGED, qosBearerSessions)); 180 } 181 182 @Override 183 public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) { 184 if (mNrAdvancedCapablePcoId <= 0) return; 185 log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable); 186 mIsNrAdvancedAllowedByPco = nrAdvancedCapable; 187 sendMessage(EVENT_UPDATE); 188 } 189 190 @Override 191 public void onPhysicalLinkStatusChanged(@LinkStatus int status) { 192 if (isUsingPhysicalChannelConfigForRrcDetection()) return; 193 sendMessage(obtainMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED, status)); 194 } 195 }; 196 197 @NonNull private Map<String, OverrideTimerRule> mOverrideTimerRules = new HashMap<>(); 198 @NonNull private String mLteEnhancedPattern = ""; 199 @Annotation.OverrideNetworkType private int mOverrideNetworkType; 200 private boolean mIsPhysicalChannelConfigOn; 201 private boolean mIsPrimaryTimerActive; 202 private boolean mIsSecondaryTimerActive; 203 private long mSecondaryTimerExpireTimestamp; 204 private boolean mIsTimerResetEnabledForLegacyStateRrcIdle; 205 /** Carrier config to reset timers when mccmnc changes */ 206 private boolean mIsTimerResetEnabledOnPlmnChanges; 207 /** Carrier config to reset timers when QCI(LTE) or 5QI(NR) is 1(conversational voice) */ 208 private boolean mIsTimerResetEnabledOnVoiceQos; 209 private int mLtePlusThresholdBandwidth; 210 private int mNrAdvancedThresholdBandwidth; 211 private boolean mIncludeLteForNrAdvancedThresholdBandwidth; 212 private boolean mRatchetPccFieldsForSameAnchorNrCell; 213 @NonNull private final Set<Integer> mAdditionalNrAdvancedBands = new HashSet<>(); 214 @NonNull private String mPrimaryTimerState; 215 @NonNull private String mSecondaryTimerState; 216 private int mNrAdvancedBandsSecondaryTimer; 217 private int mNrAdvancedPciChangeSecondaryTimer; 218 @NonNull private String mPreviousState; 219 @LinkStatus private int mPhysicalLinkStatus; 220 private boolean mIsPhysicalChannelConfig16Supported; 221 private boolean mIsNrAdvancedAllowedByPco = false; 222 private int mNrAdvancedCapablePcoId = 0; 223 private boolean mIsUsingUserDataForRrcDetection = false; 224 private boolean mEnableNrAdvancedWhileRoaming = true; 225 private boolean mIsDeviceIdleMode = false; 226 private boolean mPrimaryCellChangedWhileIdle = false; 227 private boolean mPciChangedDuringPrimaryTimer = false; 228 229 // Cached copies below to prevent race conditions 230 @NonNull private ServiceState mServiceState; 231 /** Used to track link status to be DORMANT or ACTIVE */ 232 @Nullable private List<PhysicalChannelConfig> mPhysicalChannelConfigs; 233 234 // Ratchet physical channel config fields to prevent 5G/5G+ flickering 235 @NonNull private Set<Integer> mRatchetedNrBands = new HashSet<>(); 236 // TODO(b/316425811 remove the workaround) 237 private boolean mLastShownNrDueToAdvancedBand = false; 238 private int mRatchetedNrBandwidths = 0; 239 private int mLastAnchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN; 240 private boolean mDoesPccListIndicateIdle = false; 241 242 private boolean mInVoiceCall = false; 243 private boolean mIsSatelliteConstrainedData = false; 244 private boolean mIsSatelliteNetworkCallbackRegistered = false; 245 private ConnectivityManager mConnectivityManager; 246 247 private final ConnectivityManager.NetworkCallback mNetworkCallback = 248 new ConnectivityManager.NetworkCallback() { 249 @Override 250 public void onAvailable(Network network) { 251 log("On Available: " + network); 252 if (network != null) { 253 if (mConnectivityManager != null) { 254 NetworkCapabilities capabilities = 255 mConnectivityManager.getNetworkCapabilities(network); 256 updateBandwidthConstrainedStatus(capabilities); 257 } else { 258 log("network is null"); 259 } 260 } 261 } 262 263 @Override 264 public void onCapabilitiesChanged(Network network, 265 NetworkCapabilities networkCapabilities) { 266 log("onCapabilitiesChanged: " + network); 267 if (network != null) { 268 updateBandwidthConstrainedStatus(networkCapabilities); 269 } else { 270 log("network is null"); 271 } 272 } 273 274 @Override 275 public void onLost(Network network) { 276 log("Network Lost"); 277 if (mIsSatelliteConstrainedData) { 278 mIsSatelliteConstrainedData = false; 279 mDisplayInfoController.updateTelephonyDisplayInfo(); 280 } 281 } 282 }; 283 isBandwidthConstrainedCapabilitySupported(NetworkCapabilities capabilities)284 private boolean isBandwidthConstrainedCapabilitySupported(NetworkCapabilities 285 capabilities) { 286 // TODO (b/382002908: Remove try catch exception for 287 // NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED & replace datautils with 288 // NetworkCapabilities on api availability at mainline module) 289 try { 290 return capabilities.hasTransport( 291 NetworkCapabilities.TRANSPORT_SATELLITE) && 292 !capabilities.hasCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED); 293 } catch (Exception ignored) { 294 log("NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED not supported "); 295 return false; 296 } 297 } 298 updateBandwidthConstrainedStatus(NetworkCapabilities capabilities)299 private void updateBandwidthConstrainedStatus(NetworkCapabilities capabilities) { 300 if (capabilities != null) { 301 mIsSatelliteConstrainedData 302 = isBandwidthConstrainedCapabilitySupported(capabilities); 303 log("satellite constrained data status : " + mIsSatelliteConstrainedData); 304 mDisplayInfoController.updateTelephonyDisplayInfo(); 305 } else { 306 log("capabilities is null"); 307 } 308 } 309 310 /** 311 * NetworkTypeController constructor. 312 * 313 * @param phone Phone object. 314 * @param displayInfoController DisplayInfoController to send override network types to. 315 * @param featureFlags FeatureFlags controlling what icon features are enabled. 316 */ NetworkTypeController(Phone phone, DisplayInfoController displayInfoController, FeatureFlags featureFlags)317 public NetworkTypeController(Phone phone, DisplayInfoController displayInfoController, 318 FeatureFlags featureFlags) { 319 super(TAG, displayInfoController); 320 mPhone = phone; 321 mFeatureFlags = featureFlags; 322 mDisplayInfoController = displayInfoController; 323 mOverrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 324 mIsPhysicalChannelConfigOn = true; 325 mPrimaryTimerState = ""; 326 mSecondaryTimerState = ""; 327 mPreviousState = ""; 328 DefaultState defaultState = new DefaultState(); 329 addState(defaultState); 330 addState(mLegacyState, defaultState); 331 addState(mIdleState, defaultState); 332 addState(mLteConnectedState, defaultState); 333 addState(mNrIdleState, defaultState); 334 addState(mNrConnectedState, defaultState); 335 addState(mNrConnectedAdvancedState, defaultState); 336 setInitialState(defaultState); 337 start(); 338 339 mServiceState = mPhone.getServiceStateTracker().getServiceState(); 340 mPhysicalChannelConfigs = mPhone.getServiceStateTracker().getPhysicalChannelConfigList(); 341 342 sendMessage(EVENT_INITIALIZE); 343 } 344 registerForSatelliteNetwork()345 public synchronized void registerForSatelliteNetwork() { 346 if (!mIsSatelliteNetworkCallbackRegistered) { 347 mIsSatelliteNetworkCallbackRegistered = true; 348 HandlerThread handlerThread = new HandlerThread("SatelliteDataUsageThread"); 349 handlerThread.start(); 350 Handler handler = new Handler(handlerThread.getLooper()); 351 352 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 353 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 354 // TODO (b/382002908: Remove try catch exception for 355 // NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED & replace datautils with 356 // NetworkCapabilities on api availability at mainline module) 357 try { 358 builder.removeCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED); 359 } catch (Exception ignored) { 360 log("NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED not supported "); 361 } 362 mConnectivityManager = 363 (ConnectivityManager) mPhone.getContext() 364 .getSystemService(Context.CONNECTIVITY_SERVICE); 365 if (mConnectivityManager != null) { 366 mConnectivityManager.registerBestMatchingNetworkCallback( 367 builder.build(), mNetworkCallback, handler); 368 } else { 369 loge("network callback not registered"); 370 } 371 } 372 } 373 374 /** 375 * @return The current override network type, used to create TelephonyDisplayInfo in 376 * DisplayInfoController. 377 */ getOverrideNetworkType()378 public @Annotation.OverrideNetworkType int getOverrideNetworkType() { 379 return mOverrideNetworkType; 380 } 381 382 /** 383 * @return The current data network type, used to create TelephonyDisplayInfo in 384 * DisplayInfoController. 385 */ getDataNetworkType()386 public @Annotation.NetworkType int getDataNetworkType() { 387 NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo( 388 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 389 return nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN 390 : nri.getAccessNetworkTechnology(); 391 } 392 393 /** 394 * @return satellite bandwidth constrained connection status, used to create 395 * TelephonyDisplayInfo in DisplayInfoController. 396 * 397 */ getSatelliteConstrainedData()398 public boolean getSatelliteConstrainedData() { 399 return mIsSatelliteConstrainedData; 400 } 401 402 /** 403 * @return {@code true} if either the primary or secondary 5G icon timers are active, 404 * and {@code false} if neither are. 405 */ areAnyTimersActive()406 public boolean areAnyTimersActive() { 407 return mIsPrimaryTimerActive || mIsSecondaryTimerActive; 408 } 409 registerForAllEvents()410 private void registerForAllEvents() { 411 mPhone.registerForRadioOffOrNotAvailable(getHandler(), 412 EVENT_RADIO_OFF_OR_UNAVAILABLE, null); 413 mPhone.registerForPreferredNetworkTypeChanged(getHandler(), 414 EVENT_PREFERRED_NETWORK_MODE_CHANGED, null); 415 mPhone.registerForPhysicalChannelConfig(getHandler(), 416 EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED, null); 417 mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(), 418 EVENT_SERVICE_STATE_CHANGED, null); 419 mIsPhysicalChannelConfig16Supported = mPhone.getContext().getSystemService( 420 TelephonyManager.class).isRadioInterfaceCapabilitySupported( 421 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED); 422 mPhone.getDeviceStateMonitor().registerForPhysicalChannelConfigNotifChanged(getHandler(), 423 EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED, null); 424 mPhone.getDataNetworkController().registerDataNetworkControllerCallback( 425 mDataNetworkControllerCallback); 426 IntentFilter filter = new IntentFilter(); 427 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 428 mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 429 CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class); 430 if (ccm != null) { 431 ccm.registerCarrierConfigChangeListener(Runnable::run, mCarrierConfigChangeListener); 432 } 433 } 434 unRegisterForAllEvents()435 private void unRegisterForAllEvents() { 436 mPhone.unregisterForRadioOffOrNotAvailable(getHandler()); 437 mPhone.unregisterForPreferredNetworkTypeChanged(getHandler()); 438 mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler()); 439 mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler()); 440 mPhone.getDataNetworkController().unregisterDataNetworkControllerCallback( 441 mDataNetworkControllerCallback); 442 mPhone.getContext().unregisterReceiver(mIntentReceiver); 443 CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class); 444 if (ccm != null && mCarrierConfigChangeListener != null) { 445 ccm.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener); 446 } 447 } 448 parseCarrierConfigs()449 private void parseCarrierConfigs() { 450 PersistableBundle config = CarrierConfigManager.getDefaultConfig(); 451 CarrierConfigManager configManager = 452 mPhone.getContext().getSystemService(CarrierConfigManager.class); 453 if (configManager != null) { 454 PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId()); 455 if (b != null) { 456 config = b; 457 } 458 } 459 mLteEnhancedPattern = config.getString( 460 CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING); 461 mIsTimerResetEnabledForLegacyStateRrcIdle = config.getBoolean( 462 CarrierConfigManager.KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL); 463 mIsTimerResetEnabledOnPlmnChanges = config.getBoolean( 464 CarrierConfigManager.KEY_NR_TIMERS_RESET_ON_PLMN_CHANGE_BOOL); 465 mIsTimerResetEnabledOnVoiceQos = config.getBoolean( 466 CarrierConfigManager.KEY_NR_TIMERS_RESET_ON_VOICE_QOS_BOOL); 467 mLtePlusThresholdBandwidth = config.getInt( 468 CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT); 469 mNrAdvancedThresholdBandwidth = config.getInt( 470 CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT); 471 mIncludeLteForNrAdvancedThresholdBandwidth = config.getBoolean( 472 CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL); 473 mRatchetPccFieldsForSameAnchorNrCell = config.getBoolean( 474 CarrierConfigManager.KEY_RATCHET_NR_ADVANCED_BANDWIDTH_IF_RRC_IDLE_BOOL); 475 mEnableNrAdvancedWhileRoaming = config.getBoolean( 476 CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL); 477 mAdditionalNrAdvancedBands.clear(); 478 int[] additionalNrAdvancedBands = config.getIntArray( 479 CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY); 480 if (additionalNrAdvancedBands != null) { 481 Arrays.stream(additionalNrAdvancedBands).forEach(mAdditionalNrAdvancedBands::add); 482 } 483 mNrAdvancedCapablePcoId = config.getInt( 484 CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT); 485 mIsUsingUserDataForRrcDetection = config.getBoolean( 486 CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL); 487 mNrAdvancedBandsSecondaryTimer = config.getInt( 488 CarrierConfigManager.KEY_NR_ADVANCED_BANDS_SECONDARY_TIMER_SECONDS_INT); 489 mNrAdvancedPciChangeSecondaryTimer = config.getInt( 490 CarrierConfigManager.KEY_NR_ADVANCED_PCI_CHANGE_SECONDARY_TIMER_SECONDS_INT); 491 String nrIconConfiguration = config.getString( 492 CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING); 493 String overrideTimerRule = config.getString( 494 CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING); 495 String overrideSecondaryTimerRule = config.getString( 496 CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING); 497 createTimerRules(nrIconConfiguration, overrideTimerRule, overrideSecondaryTimerRule); 498 updatePhysicalChannelConfigs( 499 mPhone.getServiceStateTracker().getPhysicalChannelConfigList()); 500 if (isUsingPhysicalChannelConfigForRrcDetection()) { 501 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 502 } 503 } 504 createTimerRules(String icons, String timers, String secondaryTimers)505 private void createTimerRules(String icons, String timers, String secondaryTimers) { 506 Map<String, OverrideTimerRule> tempRules = new HashMap<>(); 507 if (!TextUtils.isEmpty(icons)) { 508 // Format: "STATE:ICON,STATE2:ICON2" 509 for (String pair : icons.trim().split(",")) { 510 String[] kv = (pair.trim().toLowerCase(Locale.ROOT)).split(":"); 511 if (kv.length != 2) { 512 if (DBG) loge("Invalid 5G icon configuration, config = " + pair); 513 continue; 514 } 515 int icon = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 516 if (kv[1].equals(ICON_5G)) { 517 icon = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA; 518 } else if (kv[1].equals(ICON_5G_PLUS)) { 519 icon = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED; 520 } else { 521 if (DBG) loge("Invalid 5G icon = " + kv[1]); 522 } 523 tempRules.put(kv[0], new OverrideTimerRule(kv[0], icon)); 524 } 525 } 526 // Ensure all states have an associated OverrideTimerRule and icon 527 for (String state : ALL_STATES) { 528 if (!tempRules.containsKey(state)) { 529 tempRules.put(state, new OverrideTimerRule( 530 state, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE)); 531 } 532 } 533 534 if (!TextUtils.isEmpty(timers)) { 535 // Format: "FROM_STATE,TO_STATE,DURATION;FROM_STATE_2,TO_STATE_2,DURATION_2" 536 for (String triple : timers.trim().split(";")) { 537 String[] kv = (triple.trim().toLowerCase(Locale.ROOT)).split(","); 538 if (kv.length != 3) { 539 if (DBG) loge("Invalid 5G icon timer configuration, config = " + triple); 540 continue; 541 } 542 int duration; 543 try { 544 duration = Integer.parseInt(kv[2]); 545 } catch (NumberFormatException e) { 546 continue; 547 } 548 if (kv[0].equals(STATE_ANY)) { 549 for (String state : ALL_STATES) { 550 OverrideTimerRule node = tempRules.get(state); 551 node.addTimer(kv[1], duration); 552 } 553 } else { 554 OverrideTimerRule node = tempRules.get(kv[0]); 555 node.addTimer(kv[1], duration); 556 } 557 } 558 } 559 560 if (!TextUtils.isEmpty(secondaryTimers)) { 561 // Format: "PRIMARY_STATE,TO_STATE,DURATION;PRIMARY_STATE_2,TO_STATE_2,DURATION_2" 562 for (String triple : secondaryTimers.trim().split(";")) { 563 String[] kv = (triple.trim().toLowerCase(Locale.ROOT)).split(","); 564 if (kv.length != 3) { 565 if (DBG) { 566 loge("Invalid 5G icon secondary timer configuration, config = " + triple); 567 } 568 continue; 569 } 570 int duration; 571 try { 572 duration = Integer.parseInt(kv[2]); 573 } catch (NumberFormatException e) { 574 continue; 575 } 576 if (kv[0].equals(STATE_ANY)) { 577 for (String state : ALL_STATES) { 578 OverrideTimerRule node = tempRules.get(state); 579 node.addSecondaryTimer(kv[1], duration); 580 } 581 } else { 582 OverrideTimerRule node = tempRules.get(kv[0]); 583 node.addSecondaryTimer(kv[1], duration); 584 } 585 } 586 } 587 588 // TODO: Remove this workaround to make STATE_CONNECTED_RRC_IDLE backwards compatible with 589 // STATE_CONNECTED once carrier configs are updated. 590 OverrideTimerRule nrRules = tempRules.get(STATE_CONNECTED); 591 if (!tempRules.get(STATE_CONNECTED_RRC_IDLE).isDefined() && nrRules.isDefined()) { 592 OverrideTimerRule nrIdleRules = 593 new OverrideTimerRule(STATE_CONNECTED_RRC_IDLE, nrRules.mOverrideType); 594 for (Map.Entry<String, Integer> entry : nrIdleRules.mPrimaryTimers.entrySet()) { 595 nrIdleRules.addTimer(entry.getKey(), entry.getValue()); 596 } 597 for (Map.Entry<String, Integer> entry : nrIdleRules.mSecondaryTimers.entrySet()) { 598 nrIdleRules.addSecondaryTimer(entry.getKey(), entry.getValue()); 599 } 600 tempRules.put(STATE_CONNECTED_RRC_IDLE, nrIdleRules); 601 } 602 603 mOverrideTimerRules = tempRules; 604 if (DBG) log("mOverrideTimerRules: " + mOverrideTimerRules); 605 } 606 updateOverrideNetworkType()607 private void updateOverrideNetworkType() { 608 if (mIsPrimaryTimerActive || mIsSecondaryTimerActive) { 609 if (DBG) log("Skip updating override network type since timer is active."); 610 return; 611 } 612 mOverrideNetworkType = getCurrentOverrideNetworkType(); 613 mDisplayInfoController.updateTelephonyDisplayInfo(); 614 } 615 getCurrentOverrideNetworkType()616 private @Annotation.OverrideNetworkType int getCurrentOverrideNetworkType() { 617 int displayNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 618 int dataNetworkType = getDataNetworkType(); 619 boolean nrNsa = isLte(dataNetworkType) 620 && mServiceState.getNrState() != NetworkRegistrationInfo.NR_STATE_NONE; 621 boolean nrSa = dataNetworkType == TelephonyManager.NETWORK_TYPE_NR; 622 623 // NR display is not accurate when physical channel config notifications are off 624 if (mIsPhysicalChannelConfigOn && (nrNsa || nrSa)) { 625 // Process NR display network type 626 displayNetworkType = getNrDisplayType(nrSa); 627 if (displayNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE && !nrSa) { 628 // Use LTE values if 5G values aren't defined 629 displayNetworkType = getLteDisplayType(); 630 } 631 } else if (isLte(dataNetworkType)) { 632 // Process LTE display network type 633 displayNetworkType = getLteDisplayType(); 634 } 635 return displayNetworkType; 636 } 637 getNrDisplayType(boolean isNrSa)638 private @Annotation.OverrideNetworkType int getNrDisplayType(boolean isNrSa) { 639 // Don't show 5G icon if preferred network type does not include 5G 640 if ((mPhone.getCachedAllowedNetworkTypesBitmask() 641 & TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) { 642 return TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 643 } 644 // Icon display keys in order of priority 645 List<String> keys = new ArrayList<>(); 646 if (isNrSa) { 647 if (isNrAdvanced()) { 648 keys.add(STATE_CONNECTED_NR_ADVANCED); 649 } 650 } else { 651 switch (mServiceState.getNrState()) { 652 case NetworkRegistrationInfo.NR_STATE_CONNECTED: 653 if (isNrAdvanced()) { 654 keys.add(STATE_CONNECTED_NR_ADVANCED); 655 } 656 keys.add(STATE_CONNECTED); 657 break; 658 case NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED: 659 keys.add(isPhysicalLinkActive() ? STATE_NOT_RESTRICTED_RRC_CON 660 : STATE_NOT_RESTRICTED_RRC_IDLE); 661 break; 662 case NetworkRegistrationInfo.NR_STATE_RESTRICTED: 663 keys.add(STATE_RESTRICTED); 664 break; 665 } 666 } 667 668 for (String key : keys) { 669 OverrideTimerRule rule = mOverrideTimerRules.get(key); 670 if (rule != null && rule.mOverrideType 671 != TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) { 672 return rule.mOverrideType; 673 } 674 } 675 return TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 676 } 677 getLteDisplayType()678 private @Annotation.OverrideNetworkType int getLteDisplayType() { 679 int value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 680 if ((getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA 681 || mServiceState.isUsingCarrierAggregation()) 682 && IntStream.of(mServiceState.getCellBandwidths()).sum() 683 > mLtePlusThresholdBandwidth) { 684 value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA; 685 } 686 if (isLteEnhancedAvailable()) { 687 value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO; 688 } 689 return value; 690 } 691 isLteEnhancedAvailable()692 private boolean isLteEnhancedAvailable() { 693 if (TextUtils.isEmpty(mLteEnhancedPattern)) { 694 return false; 695 } 696 Pattern stringPattern = Pattern.compile(mLteEnhancedPattern); 697 for (String opName : new String[] {mServiceState.getOperatorAlphaLongRaw(), 698 mServiceState.getOperatorAlphaShortRaw()}) { 699 if (!TextUtils.isEmpty(opName)) { 700 Matcher matcher = stringPattern.matcher(opName); 701 if (matcher.find()) { 702 return true; 703 } 704 } 705 } 706 return false; 707 } 708 709 /** 710 * The parent state for all other states. 711 */ 712 private final class DefaultState extends State { 713 @Override processMessage(Message msg)714 public boolean processMessage(Message msg) { 715 AsyncResult ar; 716 if (DBG) log("DefaultState: process " + getEventName(msg.what)); 717 switch (msg.what) { 718 case EVENT_UPDATE: 719 resetAllTimers(); 720 transitionToCurrentState(); 721 break; 722 case EVENT_QUIT: 723 if (DBG) log("Reset timers on state machine quitting."); 724 resetAllTimers(); 725 unRegisterForAllEvents(); 726 quit(); 727 break; 728 case EVENT_INITIALIZE: 729 // The reason that we do it here is that the work below requires other modules 730 // (e.g. DataNetworkController, ServiceStateTracker), which are not created 731 // when NetworkTypeController is created. 732 registerForAllEvents(); 733 parseCarrierConfigs(); 734 break; 735 case EVENT_SERVICE_STATE_CHANGED: 736 onServiceStateChanged(); 737 transitionToCurrentState(); 738 break; 739 case EVENT_PHYSICAL_LINK_STATUS_CHANGED: 740 mPhysicalLinkStatus = msg.arg1; 741 break; 742 case EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED: 743 ar = (AsyncResult) msg.obj; 744 mIsPhysicalChannelConfigOn = (boolean) ar.result; 745 if (DBG) { 746 log("mIsPhysicalChannelConfigOn changed to: " + mIsPhysicalChannelConfigOn); 747 } 748 if (!mIsPhysicalChannelConfigOn) { 749 if (DBG) { 750 log("Reset timers since physical channel config indications are off."); 751 } 752 resetAllTimers(); 753 } 754 transitionToCurrentState(); 755 break; 756 case EVENT_CARRIER_CONFIG_CHANGED: 757 parseCarrierConfigs(); 758 if (DBG) log("Reset timers since carrier configurations changed."); 759 resetAllTimers(); 760 transitionToCurrentState(); 761 break; 762 case EVENT_PRIMARY_TIMER_EXPIRED: 763 if (DBG) log("Primary timer expired for state: " + mPrimaryTimerState); 764 transitionWithSecondaryTimerTo((IState) msg.obj); 765 break; 766 case EVENT_SECONDARY_TIMER_EXPIRED: 767 if (DBG) log("Secondary timer expired for state: " + mSecondaryTimerState); 768 mIsSecondaryTimerActive = false; 769 mSecondaryTimerExpireTimestamp = 0; 770 mSecondaryTimerState = ""; 771 updateTimers(); 772 mLastShownNrDueToAdvancedBand = false; 773 updateOverrideNetworkType(); 774 break; 775 case EVENT_RADIO_OFF_OR_UNAVAILABLE: 776 if (DBG) log("Reset timers since radio is off or unavailable."); 777 resetAllTimers(); 778 mRatchetedNrBands.clear(); 779 mRatchetedNrBandwidths = 0; 780 mLastAnchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN; 781 mDoesPccListIndicateIdle = false; 782 mIsNrAdvancedAllowedByPco = false; 783 mInVoiceCall = false; 784 mPhysicalChannelConfigs = null; 785 transitionTo(mLegacyState); 786 break; 787 case EVENT_PREFERRED_NETWORK_MODE_CHANGED: 788 if (DBG) log("Reset timers since preferred network mode changed."); 789 resetAllTimers(); 790 transitionToCurrentState(); 791 break; 792 case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED: 793 ar = (AsyncResult) msg.obj; 794 updatePhysicalChannelConfigs((List<PhysicalChannelConfig>) ar.result); 795 if (isUsingPhysicalChannelConfigForRrcDetection()) { 796 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 797 } 798 transitionToCurrentState(); 799 break; 800 case EVENT_DEVICE_IDLE_MODE_CHANGED: 801 PowerManager pm = mPhone.getContext().getSystemService(PowerManager.class); 802 mIsDeviceIdleMode = pm.isDeviceIdleMode(); 803 if (DBG) { 804 log("mIsDeviceIdleMode changed to: " + mIsDeviceIdleMode); 805 } 806 if (mIsDeviceIdleMode) { 807 if (DBG) log("Reset timers since device is in idle mode."); 808 resetAllTimers(); 809 } 810 transitionToCurrentState(); 811 break; 812 case EVENT_QOS_SESSION_CHANGED: 813 List<QosBearerSession> qosBearerSessions = (List<QosBearerSession>) msg.obj; 814 mInVoiceCall = false; 815 for (QosBearerSession session : qosBearerSessions) { 816 // TS 23.203 23.501 - 1 means conversational voice 817 if (session.getQos() instanceof EpsQos qos && qos.getQci() == 1) { 818 mInVoiceCall = true; 819 break; 820 } else if (session.getQos() instanceof NrQos qos && qos.get5Qi() == 1) { 821 mInVoiceCall = true; 822 break; 823 } 824 } 825 if (mIsTimerResetEnabledOnVoiceQos && mInVoiceCall) { 826 if (DBG) log("Device in voice call, reset all timers"); 827 resetAllTimers(); 828 transitionToCurrentState(); 829 } 830 break; 831 default: 832 throw new RuntimeException("Received invalid event: " + msg.what); 833 } 834 return HANDLED; 835 } 836 } 837 838 /** 839 * Device does not have NR available, due to any of the below reasons: 840 * <ul> 841 * <li> LTE cell does not support EN-DC 842 * <li> LTE cell supports EN-DC, but the use of NR is restricted 843 * <li> Data network type is not LTE, NR NSA, or NR SA 844 * </ul> 845 * This is the initial state. 846 */ 847 private final class LegacyState extends State { 848 private boolean mIsNrRestricted = false; 849 850 @Override enter()851 public void enter() { 852 if (DBG) log("Entering LegacyState"); 853 updateTimers(); 854 updateOverrideNetworkType(); 855 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 856 mIsNrRestricted = isNrRestricted(); 857 mPreviousState = getName(); 858 } 859 } 860 861 @Override processMessage(Message msg)862 public boolean processMessage(Message msg) { 863 if (DBG) log("LegacyState: process " + getEventName(msg.what)); 864 updateTimers(); 865 AsyncResult ar; 866 switch (msg.what) { 867 case EVENT_SERVICE_STATE_CHANGED: 868 onServiceStateChanged(); 869 // fallthrough 870 case EVENT_UPDATE: 871 int rat = getDataNetworkType(); 872 if (rat == TelephonyManager.NETWORK_TYPE_NR || isLte(rat) && isNrConnected()) { 873 if (isNrAdvanced()) { 874 transitionTo(mNrConnectedAdvancedState); 875 } else { 876 transitionTo(isPhysicalLinkActive() 877 ? mNrConnectedState : mNrIdleState); 878 } 879 } else if (isLte(rat) && isNrNotRestricted()) { 880 transitionWithTimerTo(isPhysicalLinkActive() 881 ? mLteConnectedState : mIdleState); 882 } else { 883 if (!isLte(rat)) { 884 if (DBG) log("Reset timers since 2G and 3G don't need NR timers."); 885 resetAllTimers(); 886 } 887 updateOverrideNetworkType(); 888 } 889 mIsNrRestricted = isNrRestricted(); 890 break; 891 case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED: 892 ar = (AsyncResult) msg.obj; 893 updatePhysicalChannelConfigs((List<PhysicalChannelConfig>) ar.result); 894 if (isUsingPhysicalChannelConfigForRrcDetection()) { 895 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 896 if (mIsTimerResetEnabledForLegacyStateRrcIdle && !isPhysicalLinkActive()) { 897 if (DBG) log("Reset timers since timer reset is enabled for RRC idle."); 898 resetAllTimers(); 899 updateOverrideNetworkType(); 900 } 901 } 902 break; 903 case EVENT_PHYSICAL_LINK_STATUS_CHANGED: 904 mPhysicalLinkStatus = msg.arg1; 905 if (mIsTimerResetEnabledForLegacyStateRrcIdle && !isPhysicalLinkActive()) { 906 if (DBG) log("Reset timers since timer reset is enabled for RRC idle."); 907 resetAllTimers(); 908 updateOverrideNetworkType(); 909 } 910 break; 911 default: 912 return NOT_HANDLED; 913 } 914 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 915 mPreviousState = getName(); 916 } 917 return HANDLED; 918 } 919 920 @Override getName()921 public String getName() { 922 return mIsNrRestricted ? STATE_RESTRICTED : STATE_LEGACY; 923 } 924 } 925 926 private final LegacyState mLegacyState = new LegacyState(); 927 928 /** 929 * Device does not have any physical connection with the cell (RRC idle). 930 */ 931 private final class IdleState extends State { 932 @Override enter()933 public void enter() { 934 if (DBG) log("Entering IdleState"); 935 updateTimers(); 936 updateOverrideNetworkType(); 937 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 938 mPreviousState = getName(); 939 } 940 } 941 942 @Override processMessage(Message msg)943 public boolean processMessage(Message msg) { 944 if (DBG) log("IdleState: process " + getEventName(msg.what)); 945 updateTimers(); 946 AsyncResult ar; 947 switch (msg.what) { 948 case EVENT_SERVICE_STATE_CHANGED: 949 onServiceStateChanged(); 950 // fallthrough 951 case EVENT_UPDATE: 952 int rat = getDataNetworkType(); 953 if (rat == TelephonyManager.NETWORK_TYPE_NR 954 || (isLte(rat) && isNrConnected())) { 955 if (isNrAdvanced()) { 956 transitionTo(mNrConnectedAdvancedState); 957 } else { 958 transitionTo(isPhysicalLinkActive() 959 ? mNrConnectedState : mNrIdleState); 960 } 961 } else if (!isLte(rat) || !isNrNotRestricted()) { 962 transitionWithTimerTo(mLegacyState); 963 } else { 964 if (isPhysicalLinkActive()) { 965 transitionWithTimerTo(mLteConnectedState); 966 } else { 967 // Update in case the override network type changed 968 updateOverrideNetworkType(); 969 } 970 } 971 break; 972 case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED: 973 ar = (AsyncResult) msg.obj; 974 updatePhysicalChannelConfigs((List<PhysicalChannelConfig>) ar.result); 975 if (isUsingPhysicalChannelConfigForRrcDetection()) { 976 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 977 if (isPhysicalLinkActive()) { 978 transitionWithTimerTo(mLteConnectedState); 979 } else { 980 log("Reevaluating state due to link status changed."); 981 sendMessage(EVENT_UPDATE); 982 } 983 } 984 break; 985 case EVENT_PHYSICAL_LINK_STATUS_CHANGED: 986 mPhysicalLinkStatus = msg.arg1; 987 if (isPhysicalLinkActive()) { 988 transitionWithTimerTo(mLteConnectedState); 989 } else { 990 log("Reevaluating state due to link status changed."); 991 sendMessage(EVENT_UPDATE); 992 } 993 break; 994 default: 995 return NOT_HANDLED; 996 } 997 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 998 mPreviousState = getName(); 999 } 1000 return HANDLED; 1001 } 1002 1003 @Override getName()1004 public String getName() { 1005 return STATE_NOT_RESTRICTED_RRC_IDLE; 1006 } 1007 } 1008 1009 private final IdleState mIdleState = new IdleState(); 1010 1011 /** 1012 * Device is connected to LTE as the primary cell (RRC connected). 1013 */ 1014 private final class LteConnectedState extends State { 1015 @Override enter()1016 public void enter() { 1017 if (DBG) log("Entering LteConnectedState"); 1018 updateTimers(); 1019 updateOverrideNetworkType(); 1020 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1021 mPreviousState = getName(); 1022 } 1023 } 1024 1025 @Override processMessage(Message msg)1026 public boolean processMessage(Message msg) { 1027 if (DBG) log("LteConnectedState: process " + getEventName(msg.what)); 1028 updateTimers(); 1029 AsyncResult ar; 1030 switch (msg.what) { 1031 case EVENT_SERVICE_STATE_CHANGED: 1032 onServiceStateChanged(); 1033 // fallthrough 1034 case EVENT_UPDATE: 1035 int rat = getDataNetworkType(); 1036 if (rat == TelephonyManager.NETWORK_TYPE_NR 1037 || (isLte(rat) && isNrConnected())) { 1038 if (isNrAdvanced()) { 1039 transitionTo(mNrConnectedAdvancedState); 1040 } else { 1041 transitionTo(isPhysicalLinkActive() 1042 ? mNrConnectedState : mNrIdleState); 1043 } 1044 } else if (!isLte(rat) || !isNrNotRestricted()) { 1045 transitionWithTimerTo(mLegacyState); 1046 } else { 1047 if (!isPhysicalLinkActive()) { 1048 transitionWithTimerTo(mIdleState); 1049 } else { 1050 // Update in case the override network type changed 1051 updateOverrideNetworkType(); 1052 } 1053 } 1054 break; 1055 case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED: 1056 ar = (AsyncResult) msg.obj; 1057 updatePhysicalChannelConfigs((List<PhysicalChannelConfig>) ar.result); 1058 if (isUsingPhysicalChannelConfigForRrcDetection()) { 1059 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 1060 if (!isPhysicalLinkActive()) { 1061 transitionWithTimerTo(mIdleState); 1062 } else { 1063 log("Reevaluating state due to link status changed."); 1064 sendMessage(EVENT_UPDATE); 1065 } 1066 } 1067 break; 1068 case EVENT_PHYSICAL_LINK_STATUS_CHANGED: 1069 mPhysicalLinkStatus = msg.arg1; 1070 if (!isPhysicalLinkActive()) { 1071 transitionWithTimerTo(mIdleState); 1072 } else { 1073 log("Reevaluating state due to link status changed."); 1074 sendMessage(EVENT_UPDATE); 1075 } 1076 break; 1077 default: 1078 return NOT_HANDLED; 1079 } 1080 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1081 mPreviousState = getName(); 1082 } 1083 return HANDLED; 1084 } 1085 1086 @Override getName()1087 public String getName() { 1088 return STATE_NOT_RESTRICTED_RRC_CON; 1089 } 1090 } 1091 1092 private final LteConnectedState mLteConnectedState = new LteConnectedState(); 1093 1094 /** 1095 * Device is connected to 5G NR as the primary or secondary cell but not actively using data. 1096 */ 1097 private final class NrIdleState extends State { 1098 @Override enter()1099 public void enter() { 1100 if (DBG) log("Entering NrIdleState"); 1101 updateTimers(); 1102 updateOverrideNetworkType(); 1103 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1104 mPreviousState = getName(); 1105 } 1106 } 1107 1108 @Override processMessage(Message msg)1109 public boolean processMessage(Message msg) { 1110 if (DBG) log("NrIdleState: process " + getEventName(msg.what)); 1111 updateTimers(); 1112 AsyncResult ar; 1113 switch (msg.what) { 1114 case EVENT_SERVICE_STATE_CHANGED: 1115 onServiceStateChanged(); 1116 // fallthrough 1117 case EVENT_UPDATE: 1118 int rat = getDataNetworkType(); 1119 if (rat == TelephonyManager.NETWORK_TYPE_NR 1120 || (isLte(rat) && isNrConnected())) { 1121 if (isNrAdvanced()) { 1122 // Move into idle state because mPhysicalLinkStatus indicated idle, 1123 // ignored any advance reason because unless mPhysicalLinkStatus changed 1124 // again, shouldn't move back to advance. 1125 log("Ignore NR advanced from cached PCC/RatchetedNrBands while idle"); 1126 } else if (isPhysicalLinkActive()) { 1127 transitionWithTimerTo(mNrConnectedState); 1128 } else { 1129 // Update in case the override network type changed 1130 updateOverrideNetworkType(); 1131 } 1132 } else if (isLte(rat) && isNrNotRestricted()) { 1133 transitionWithTimerTo(isPhysicalLinkActive() 1134 ? mLteConnectedState : mIdleState); 1135 } else { 1136 transitionWithTimerTo(mLegacyState); 1137 } 1138 break; 1139 case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED: 1140 ar = (AsyncResult) msg.obj; 1141 updatePhysicalChannelConfigs((List<PhysicalChannelConfig>) ar.result); 1142 if (isUsingPhysicalChannelConfigForRrcDetection()) { 1143 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 1144 } 1145 if (isPhysicalLinkActive()) { 1146 if (isNrAdvanced()) { 1147 transitionTo(mNrConnectedAdvancedState); 1148 } else { 1149 transitionWithTimerTo(mNrConnectedState); 1150 } 1151 } else { 1152 // Update in case the override network type changed 1153 updateOverrideNetworkType(); 1154 } 1155 break; 1156 case EVENT_PHYSICAL_LINK_STATUS_CHANGED: 1157 mPhysicalLinkStatus = msg.arg1; 1158 if (isPhysicalLinkActive()) { 1159 transitionWithTimerTo(mNrConnectedState); 1160 } 1161 break; 1162 default: 1163 return NOT_HANDLED; 1164 } 1165 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1166 mPreviousState = getName(); 1167 } 1168 return HANDLED; 1169 } 1170 1171 @Override getName()1172 public String getName() { 1173 return STATE_CONNECTED_RRC_IDLE; 1174 } 1175 } 1176 1177 private final NrIdleState mNrIdleState = new NrIdleState(); 1178 1179 /** 1180 * Device is connected to 5G NR as the primary or secondary cell. 1181 */ 1182 private final class NrConnectedState extends State { 1183 @Override enter()1184 public void enter() { 1185 if (DBG) log("Entering NrConnectedState"); 1186 updateTimers(); 1187 updateOverrideNetworkType(); 1188 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1189 mPreviousState = getName(); 1190 } 1191 } 1192 1193 @Override processMessage(Message msg)1194 public boolean processMessage(Message msg) { 1195 if (DBG) log("NrConnectedState: process " + getEventName(msg.what)); 1196 updateTimers(); 1197 AsyncResult ar; 1198 switch (msg.what) { 1199 case EVENT_SERVICE_STATE_CHANGED: 1200 onServiceStateChanged(); 1201 // fallthrough 1202 case EVENT_UPDATE: 1203 int rat = getDataNetworkType(); 1204 if (rat == TelephonyManager.NETWORK_TYPE_NR 1205 || (isLte(rat) && isNrConnected())) { 1206 if (isNrAdvanced()) { 1207 transitionTo(mNrConnectedAdvancedState); 1208 } else if (!isPhysicalLinkActive()) { 1209 transitionWithTimerTo(mNrIdleState); 1210 } else { 1211 // Update in case the override network type changed 1212 updateOverrideNetworkType(); 1213 } 1214 } else if (isLte(rat) && isNrNotRestricted()) { 1215 transitionWithTimerTo(isPhysicalLinkActive() 1216 ? mLteConnectedState : mIdleState); 1217 } else { 1218 transitionWithTimerTo(mLegacyState); 1219 } 1220 break; 1221 case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED: 1222 ar = (AsyncResult) msg.obj; 1223 updatePhysicalChannelConfigs((List<PhysicalChannelConfig>) ar.result); 1224 if (isUsingPhysicalChannelConfigForRrcDetection()) { 1225 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 1226 } 1227 if (!isPhysicalLinkActive()) { 1228 transitionWithTimerTo(mNrIdleState); 1229 } else if (isNrAdvanced()) { 1230 transitionTo(mNrConnectedAdvancedState); 1231 } 1232 break; 1233 case EVENT_PHYSICAL_LINK_STATUS_CHANGED: 1234 mPhysicalLinkStatus = msg.arg1; 1235 if (!isPhysicalLinkActive()) { 1236 transitionWithTimerTo(mNrIdleState); 1237 } 1238 break; 1239 default: 1240 return NOT_HANDLED; 1241 } 1242 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1243 mPreviousState = getName(); 1244 } 1245 return HANDLED; 1246 } 1247 1248 @Override getName()1249 public String getName() { 1250 return STATE_CONNECTED; 1251 } 1252 } 1253 1254 private final NrConnectedState mNrConnectedState = new NrConnectedState(); 1255 1256 /** 1257 * Device is connected to 5G NR as the primary cell and the data rate is higher than 1258 * the generic 5G data rate. 1259 */ 1260 private final class NrConnectedAdvancedState extends State { 1261 @Override enter()1262 public void enter() { 1263 if (DBG) log("Entering NrConnectedAdvancedState"); 1264 updateTimers(); 1265 updateOverrideNetworkType(); 1266 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1267 mPreviousState = getName(); 1268 } 1269 } 1270 1271 @Override processMessage(Message msg)1272 public boolean processMessage(Message msg) { 1273 mLastShownNrDueToAdvancedBand = isAdditionalNrAdvancedBand(mRatchetedNrBands); 1274 if (DBG) { 1275 log("NrConnectedAdvancedState: process " + getEventName(msg.what) 1276 + ", been using advanced band is " + mLastShownNrDueToAdvancedBand); 1277 } 1278 updateTimers(); 1279 AsyncResult ar; 1280 switch (msg.what) { 1281 case EVENT_SERVICE_STATE_CHANGED: 1282 onServiceStateChanged(); 1283 // fallthrough 1284 case EVENT_UPDATE: 1285 int rat = getDataNetworkType(); 1286 if (rat == TelephonyManager.NETWORK_TYPE_NR 1287 || (isLte(rat) && isNrConnected())) { 1288 if (isNrAdvanced()) { 1289 // Update in case the override network type changed 1290 updateOverrideNetworkType(); 1291 } else { 1292 if (rat == TelephonyManager.NETWORK_TYPE_NR && mOverrideNetworkType 1293 != TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED) { 1294 // manually override network type after data rat changes since 1295 // timer will prevent it from being updated 1296 mOverrideNetworkType = 1297 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 1298 } 1299 transitionWithTimerTo(isPhysicalLinkActive() 1300 ? mNrConnectedState : mNrIdleState); 1301 } 1302 } else if (isLte(rat) && isNrNotRestricted()) { 1303 transitionWithTimerTo(isPhysicalLinkActive() 1304 ? mLteConnectedState : mIdleState); 1305 } else { 1306 transitionWithTimerTo(mLegacyState); 1307 } 1308 break; 1309 case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED: 1310 ar = (AsyncResult) msg.obj; 1311 updatePhysicalChannelConfigs((List<PhysicalChannelConfig>) ar.result); 1312 if (isUsingPhysicalChannelConfigForRrcDetection()) { 1313 mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig(); 1314 } 1315 if (!isPhysicalLinkActive()) { 1316 transitionWithTimerTo(mNrIdleState); 1317 } else if (!isNrAdvanced()) { 1318 transitionWithTimerTo(mNrConnectedState); 1319 } 1320 break; 1321 case EVENT_PHYSICAL_LINK_STATUS_CHANGED: 1322 mPhysicalLinkStatus = msg.arg1; 1323 break; 1324 default: 1325 return NOT_HANDLED; 1326 } 1327 if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) { 1328 mPreviousState = getName(); 1329 } 1330 return HANDLED; 1331 } 1332 1333 @Override getName()1334 public String getName() { 1335 return STATE_CONNECTED_NR_ADVANCED; 1336 } 1337 } 1338 1339 private final NrConnectedAdvancedState mNrConnectedAdvancedState = 1340 new NrConnectedAdvancedState(); 1341 1342 /** On service state changed. */ onServiceStateChanged()1343 private void onServiceStateChanged() { 1344 ServiceState ss = mPhone.getServiceStateTracker().getServiceState(); 1345 if (mIsTimerResetEnabledOnPlmnChanges 1346 && !TextUtils.equals(mServiceState.getOperatorNumeric(), ss.getOperatorNumeric())) { 1347 log("Reset any timers due to nr_timers_reset_on_plmn_change_bool"); 1348 resetAllTimers(); 1349 } 1350 mServiceState = ss; 1351 if (DBG) log("ServiceState updated: " + mServiceState); 1352 } 1353 updatePhysicalChannelConfigs(List<PhysicalChannelConfig> physicalChannelConfigs)1354 private void updatePhysicalChannelConfigs(List<PhysicalChannelConfig> physicalChannelConfigs) { 1355 boolean isPccListEmpty = physicalChannelConfigs == null || physicalChannelConfigs.isEmpty(); 1356 if (isPccListEmpty && isUsingPhysicalChannelConfigForRrcDetection()) { 1357 // Clear mPrimaryCellChangedWhileIdle to allow later potential one-off PCI change. 1358 // Update link status to be DORMANT, but keep ratcheted bands. 1359 log("Physical channel configs updated: not updating PCC fields for empty PCC list " 1360 + "indicating RRC idle."); 1361 mPrimaryCellChangedWhileIdle = false; 1362 mPhysicalChannelConfigs = physicalChannelConfigs; 1363 mDoesPccListIndicateIdle = true; 1364 return; 1365 } 1366 1367 int anchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN; 1368 int anchorLteCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN; 1369 int nrBandwidths = 0; 1370 Set<Integer> nrBands = new HashSet<>(); 1371 if (physicalChannelConfigs != null) { 1372 for (PhysicalChannelConfig config : physicalChannelConfigs) { 1373 if (config.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR) { 1374 if (config.getConnectionStatus() == CellInfo.CONNECTION_PRIMARY_SERVING 1375 && anchorNrCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) { 1376 anchorNrCellId = config.getPhysicalCellId(); 1377 } 1378 nrBandwidths += config.getCellBandwidthDownlinkKhz(); 1379 nrBands.add(config.getBand()); 1380 } else if (config.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE) { 1381 if (config.getConnectionStatus() == CellInfo.CONNECTION_PRIMARY_SERVING 1382 && anchorLteCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) { 1383 anchorLteCellId = config.getPhysicalCellId(); 1384 } 1385 if (mIncludeLteForNrAdvancedThresholdBandwidth) { 1386 nrBandwidths += config.getCellBandwidthDownlinkKhz(); 1387 } 1388 } 1389 } 1390 } 1391 1392 // Update anchor NR cell from anchor LTE cell for NR NSA 1393 if (anchorNrCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN 1394 && anchorLteCellId != PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) { 1395 anchorNrCellId = anchorLteCellId; 1396 } 1397 1398 if (anchorNrCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) { 1399 if (!isPccListEmpty) { 1400 log("Ignoring physical channel config fields without an anchor NR cell, " 1401 + "either due to LTE-only configs or an unspecified cell ID."); 1402 } 1403 mRatchetedNrBandwidths = 0; 1404 mRatchetedNrBands.clear(); 1405 } else if (anchorNrCellId == mLastAnchorNrCellId && mRatchetPccFieldsForSameAnchorNrCell) { 1406 log("Ratchet physical channel config fields since anchor NR cell is the same."); 1407 mRatchetedNrBandwidths = Math.max(mRatchetedNrBandwidths, nrBandwidths); 1408 mRatchetedNrBands.addAll(nrBands); 1409 } else { 1410 mRatchetedNrBandwidths = nrBandwidths; 1411 mRatchetedNrBands = nrBands; 1412 if (mDoesPccListIndicateIdle 1413 && anchorNrCellId != mLastAnchorNrCellId 1414 && isUsingPhysicalChannelConfigForRrcDetection() 1415 && !mPrimaryCellChangedWhileIdle 1416 && !isNrAdvancedForPccFields(nrBandwidths, nrBands)) { 1417 log("Allow primary cell change once during RRC idle without changing state: " 1418 + mLastAnchorNrCellId + " -> " + anchorNrCellId); 1419 mPrimaryCellChangedWhileIdle = true; 1420 mLastAnchorNrCellId = anchorNrCellId; 1421 reduceSecondaryTimerIfNeeded(); 1422 return; 1423 } 1424 if (mRatchetPccFieldsForSameAnchorNrCell) { 1425 log("Not ratcheting physical channel config fields since anchor NR cell changed: " 1426 + mLastAnchorNrCellId + " -> " + anchorNrCellId); 1427 } 1428 } 1429 1430 mLastAnchorNrCellId = anchorNrCellId; 1431 mPhysicalChannelConfigs = physicalChannelConfigs; 1432 mDoesPccListIndicateIdle = false; 1433 mPciChangedDuringPrimaryTimer = mIsPrimaryTimerActive; 1434 if (DBG) { 1435 log("Physical channel configs updated: anchorNrCell=" + mLastAnchorNrCellId 1436 + ", nrBandwidths=" + mRatchetedNrBandwidths + ", nrBands=" + mRatchetedNrBands 1437 + ", configs=" + mPhysicalChannelConfigs); 1438 } 1439 } 1440 1441 /** 1442 * Called when PCI change, specifically during idle state. 1443 */ reduceSecondaryTimerIfNeeded()1444 private void reduceSecondaryTimerIfNeeded() { 1445 if (!mIsSecondaryTimerActive || mNrAdvancedBandsSecondaryTimer <= 0) return; 1446 // Secondary timer is active, so we must have a valid secondary rule right now. 1447 OverrideTimerRule secondaryRule = mOverrideTimerRules.get(mPrimaryTimerState); 1448 if (secondaryRule != null) { 1449 int secondaryDuration = secondaryRule.getSecondaryTimer(mSecondaryTimerState); 1450 long durationMillis = secondaryDuration * 1000L; 1451 long now = SystemClock.uptimeMillis(); 1452 if ((mSecondaryTimerExpireTimestamp - now) > durationMillis) { 1453 if (DBG) log("Due to PCI change, reduce the secondary timer to " + durationMillis); 1454 removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); 1455 sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, mSecondaryTimerState, 1456 durationMillis); 1457 mSecondaryTimerExpireTimestamp = now + durationMillis; 1458 } 1459 } else { 1460 loge("!! Secondary timer is active, but found no rule for " + mPrimaryTimerState); 1461 } 1462 } 1463 transitionWithTimerTo(IState destState)1464 private void transitionWithTimerTo(IState destState) { 1465 String destName = destState.getName(); 1466 if (mIsPrimaryTimerActive) { 1467 log("Transition without timer from " + getCurrentState().getName() + " to " + destName 1468 + " due to existing " + mPrimaryTimerState + " primary timer."); 1469 } else if (mIsTimerResetEnabledOnVoiceQos && mInVoiceCall) { 1470 log("Skip primary timer to " + destName + " due to in call"); 1471 } else { 1472 if (DBG) { 1473 log("Transition with primary timer from " + mPreviousState + " to " + destName); 1474 } 1475 OverrideTimerRule rule = mOverrideTimerRules.get(mPreviousState); 1476 if (!mIsDeviceIdleMode && rule != null && rule.getTimer(destName) > 0) { 1477 int duration = rule.getTimer(destName); 1478 if (DBG) log(duration + "s primary timer started for state: " + mPreviousState); 1479 mPrimaryTimerState = mPreviousState; 1480 mPreviousState = getCurrentState().getName(); 1481 mIsPrimaryTimerActive = true; 1482 sendMessageDelayed(EVENT_PRIMARY_TIMER_EXPIRED, destState, duration * 1000L); 1483 } 1484 } 1485 transitionTo(destState); 1486 } 1487 transitionWithSecondaryTimerTo(IState destState)1488 private void transitionWithSecondaryTimerTo(IState destState) { 1489 String currentName = getCurrentState().getName(); 1490 OverrideTimerRule rule = mOverrideTimerRules.get(mPrimaryTimerState); 1491 int duration = -1; 1492 if (DBG) { 1493 log("Transition with secondary timer from " + currentName + " to " 1494 + destState.getName()); 1495 } 1496 if (mIsTimerResetEnabledOnVoiceQos && mInVoiceCall) { 1497 log("Skip secondary timer from " + currentName + " to " 1498 + destState.getName() + " due to in call"); 1499 } else if (!mIsDeviceIdleMode && rule != null && rule.getSecondaryTimer(currentName) > 0) { 1500 duration = rule.getSecondaryTimer(currentName); 1501 if (mLastShownNrDueToAdvancedBand && mNrAdvancedBandsSecondaryTimer > 0) { 1502 duration = mNrAdvancedBandsSecondaryTimer; 1503 if (DBG) log("timer adjusted by nr_advanced_bands_secondary_timer_seconds_int"); 1504 } 1505 if (DBG) log(duration + "s secondary timer started for state: " + currentName); 1506 } else if (mNrAdvancedPciChangeSecondaryTimer > 0 1507 && mPciChangedDuringPrimaryTimer) { 1508 duration = mNrAdvancedPciChangeSecondaryTimer; 1509 if (DBG) log(duration + "s secondary timer started for PCI changed"); 1510 } 1511 1512 if (duration > 0) { 1513 mSecondaryTimerState = currentName; 1514 mPreviousState = currentName; 1515 mIsSecondaryTimerActive = true; 1516 long durationMillis = duration * 1000L; 1517 mSecondaryTimerExpireTimestamp = SystemClock.uptimeMillis() + durationMillis; 1518 sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState, durationMillis); 1519 } 1520 1521 mIsPrimaryTimerActive = false; 1522 mPciChangedDuringPrimaryTimer = false; 1523 transitionTo(getCurrentState()); 1524 } 1525 transitionToCurrentState()1526 private void transitionToCurrentState() { 1527 int dataRat = getDataNetworkType(); 1528 IState transitionState; 1529 if (dataRat == TelephonyManager.NETWORK_TYPE_NR || (isLte(dataRat) && isNrConnected())) { 1530 if (!isPhysicalLinkActive()) { 1531 transitionState = mNrIdleState; 1532 } else if (isNrAdvanced()) { 1533 transitionState = mNrConnectedAdvancedState; 1534 } else { 1535 transitionState = mNrConnectedState; 1536 } 1537 } else if (isLte(dataRat) && isNrNotRestricted()) { 1538 if (isPhysicalLinkActive()) { 1539 transitionState = mLteConnectedState; 1540 } else { 1541 transitionState = mIdleState; 1542 } 1543 } else { 1544 transitionState = mLegacyState; 1545 } 1546 if (!transitionState.equals(getCurrentState())) { 1547 mPreviousState = getCurrentState().getName(); 1548 transitionTo(transitionState); 1549 } else { 1550 updateOverrideNetworkType(); 1551 } 1552 } 1553 updateTimers()1554 private void updateTimers() { 1555 if ((mPhone.getCachedAllowedNetworkTypesBitmask() 1556 & TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) { 1557 if (DBG) log("Reset timers since NR is not allowed."); 1558 resetAllTimers(); 1559 return; 1560 } 1561 1562 String currentState = getCurrentState().getName(); 1563 1564 if (mIsPrimaryTimerActive && mPrimaryTimerState.equals(currentState)) { 1565 // remove primary timer if device goes back to the original state 1566 if (DBG) { 1567 log("Remove primary timer since primary timer state (" 1568 + mPrimaryTimerState + ") was reestablished."); 1569 } 1570 removeMessages(EVENT_PRIMARY_TIMER_EXPIRED); 1571 mIsPrimaryTimerActive = false; 1572 mPciChangedDuringPrimaryTimer = false; 1573 mPrimaryTimerState = ""; 1574 transitionToCurrentState(); 1575 return; 1576 } 1577 1578 if (mIsSecondaryTimerActive && !mSecondaryTimerState.equals(currentState)) { 1579 // remove secondary timer if devices is no longer in secondary timer state 1580 if (DBG) { 1581 log("Remove secondary timer since current state (" + currentState 1582 + ") is no longer secondary timer state (" + mSecondaryTimerState + ")."); 1583 } 1584 removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); 1585 mIsSecondaryTimerActive = false; 1586 mSecondaryTimerExpireTimestamp = 0; 1587 mSecondaryTimerState = ""; 1588 transitionToCurrentState(); 1589 return; 1590 } 1591 1592 if (mIsPrimaryTimerActive || mIsSecondaryTimerActive) { 1593 if (currentState.equals(STATE_CONNECTED_NR_ADVANCED)) { 1594 if (DBG) log("Reset timers since state is NR_ADVANCED."); 1595 resetAllTimers(); 1596 } else if ((currentState.equals(STATE_CONNECTED) 1597 || currentState.equals(STATE_CONNECTED_RRC_IDLE)) 1598 && !mPrimaryTimerState.equals(STATE_CONNECTED_NR_ADVANCED) 1599 && !mSecondaryTimerState.equals(STATE_CONNECTED_NR_ADVANCED)) { 1600 if (DBG) log("Reset non-NR advanced timers since state is NR connected/idle"); 1601 resetAllTimers(); 1602 } else { 1603 int rat = getDataNetworkType(); 1604 if (!isLte(rat) && rat != TelephonyManager.NETWORK_TYPE_NR) { 1605 if (DBG) log("Reset timers since 2G and 3G don't need NR timers."); 1606 resetAllTimers(); 1607 } 1608 } 1609 } 1610 } 1611 resetAllTimers()1612 private void resetAllTimers() { 1613 removeMessages(EVENT_PRIMARY_TIMER_EXPIRED); 1614 removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); 1615 mIsPrimaryTimerActive = false; 1616 mPciChangedDuringPrimaryTimer = false; 1617 mIsSecondaryTimerActive = false; 1618 mSecondaryTimerExpireTimestamp = 0; 1619 mPrimaryTimerState = ""; 1620 mSecondaryTimerState = ""; 1621 1622 mLastShownNrDueToAdvancedBand = false; 1623 } 1624 1625 /** 1626 * Private class defining timer rules between states to prevent flickering. These rules are 1627 * created in {@link #parseCarrierConfigs()} based on various carrier configs. 1628 */ 1629 private static class OverrideTimerRule { 1630 /** The 5G state this timer rule applies for. See {@link #ALL_STATES}. */ 1631 final String mState; 1632 1633 /** 1634 * The override network type associated with this 5G state. This is the icon that will be 1635 * displayed on the status bar. An override type of NONE will display the LTE value instead. 1636 */ 1637 final int mOverrideType; 1638 1639 /** 1640 * A map of destination states and associated timers. If the 5G state changes from mState 1641 * to the destination state, keep the override type until either the primary timer expires 1642 * or mState is regained. 1643 */ 1644 final Map<String, Integer> mPrimaryTimers; 1645 1646 /** 1647 * A map of secondary states and associated timers. After the primary timer expires, keep 1648 * the override type until either the secondary timer expires or the device is no longer in 1649 * the secondary state. 1650 */ 1651 final Map<String, Integer> mSecondaryTimers; 1652 OverrideTimerRule(String state, int overrideType)1653 OverrideTimerRule(String state, int overrideType) { 1654 mState = state; 1655 mOverrideType = overrideType; 1656 mPrimaryTimers = new HashMap<>(); 1657 mSecondaryTimers = new HashMap<>(); 1658 } 1659 1660 /** 1661 * Add a primary timer. 1662 * @param destination Transitions from mState to the destination state. 1663 * @param duration How long to keep the override type after transition to destination state. 1664 */ addTimer(String destination, int duration)1665 public void addTimer(String destination, int duration) { 1666 mPrimaryTimers.put(destination, duration); 1667 } 1668 1669 /** 1670 * Add a secondary timer 1671 * @param secondaryState Stays in secondaryState after primary timer expires. 1672 * @param duration How long to keep the override type while in secondaryState. 1673 */ addSecondaryTimer(String secondaryState, int duration)1674 public void addSecondaryTimer(String secondaryState, int duration) { 1675 mSecondaryTimers.put(secondaryState, duration); 1676 } 1677 1678 /** 1679 * @return Primary timer duration from mState to destination state, or 0 if not defined. 1680 */ getTimer(String destination)1681 public int getTimer(String destination) { 1682 Integer timer = mPrimaryTimers.get(destination); 1683 timer = timer == null ? mPrimaryTimers.get(STATE_ANY) : timer; 1684 return timer == null ? 0 : timer; 1685 } 1686 1687 /** 1688 * @return Secondary timer duration for secondaryState, or 0 if not defined. 1689 */ getSecondaryTimer(String secondaryState)1690 public int getSecondaryTimer(String secondaryState) { 1691 Integer secondaryTimer = mSecondaryTimers.get(secondaryState); 1692 secondaryTimer = secondaryTimer == null 1693 ? mSecondaryTimers.get(STATE_ANY) : secondaryTimer; 1694 return secondaryTimer == null ? 0 : secondaryTimer; 1695 } 1696 1697 /** 1698 * @return Whether timer rules have been defined for this {@link #mState}. 1699 */ isDefined()1700 public boolean isDefined() { 1701 // TODO: Remove this method added to make STATE_CONNECTED_RRC_IDLE backwards compatible 1702 // with STATE_CONNECTED once carrier configs are updated. 1703 return mOverrideType != TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE 1704 || !mPrimaryTimers.isEmpty() || !mSecondaryTimers.isEmpty(); 1705 } 1706 1707 @Override toString()1708 public String toString() { 1709 return "{mState=" + mState 1710 + ", mOverrideType=" 1711 + TelephonyDisplayInfo.overrideNetworkTypeToString(mOverrideType) 1712 + ", mPrimaryTimers=" + mPrimaryTimers 1713 + ", mSecondaryTimers=" + mSecondaryTimers + "}"; 1714 } 1715 } 1716 isNrConnected()1717 private boolean isNrConnected() { 1718 return mServiceState.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED; 1719 } 1720 isNrNotRestricted()1721 private boolean isNrNotRestricted() { 1722 return mServiceState.getNrState() == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED; 1723 } 1724 isNrRestricted()1725 private boolean isNrRestricted() { 1726 return mServiceState.getNrState() == NetworkRegistrationInfo.NR_STATE_RESTRICTED; 1727 } 1728 1729 /** 1730 * @return {@code true} if the device is in NR advanced mode (i.e. 5G+). 1731 */ isNrAdvanced()1732 private boolean isNrAdvanced() { 1733 return isNrAdvancedForPccFields(mRatchetedNrBandwidths, mRatchetedNrBands); 1734 } 1735 isNrAdvancedForPccFields(int bandwidths, Set<Integer> bands)1736 private boolean isNrAdvancedForPccFields(int bandwidths, Set<Integer> bands) { 1737 // Check PCO requirement. For carriers using PCO to indicate whether the data connection is 1738 // NR advanced capable, mNrAdvancedCapablePcoId should be configured to non-zero. 1739 if (mNrAdvancedCapablePcoId > 0 && !mIsNrAdvancedAllowedByPco) { 1740 if (DBG) log("isNrAdvanced: not allowed by PCO for PCO ID " + mNrAdvancedCapablePcoId); 1741 return false; 1742 } 1743 1744 // Check if NR advanced is enabled when the device is roaming. Some carriers disable it 1745 // while the device is roaming. 1746 if (mServiceState.getDataRoaming() && !mEnableNrAdvancedWhileRoaming) { 1747 if (DBG) log("isNrAdvanced: false because NR advanced is unavailable while roaming."); 1748 return false; 1749 } 1750 1751 // Check if meeting minimum bandwidth requirement. For most carriers, there is no minimum 1752 // bandwidth requirement and mNrAdvancedThresholdBandwidth is 0. 1753 if (mNrAdvancedThresholdBandwidth > 0 && bandwidths < mNrAdvancedThresholdBandwidth) { 1754 if (DBG) { 1755 log("isNrAdvanced: false because bandwidths=" + bandwidths 1756 + " does not meet the threshold=" + mNrAdvancedThresholdBandwidth); 1757 } 1758 return false; 1759 } 1760 1761 // If all above tests passed, then check if the device is using millimeter wave bands or 1762 // carrier designated bands. 1763 return isNrMmwave() || isAdditionalNrAdvancedBand(bands); 1764 } 1765 isNrMmwave()1766 private boolean isNrMmwave() { 1767 return mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE; 1768 } 1769 isAdditionalNrAdvancedBand(Set<Integer> bands)1770 private boolean isAdditionalNrAdvancedBand(Set<Integer> bands) { 1771 if (mAdditionalNrAdvancedBands.isEmpty() || bands.isEmpty()) { 1772 if (DBG && !mAdditionalNrAdvancedBands.isEmpty()) { 1773 // Only log if mAdditionalNrAdvancedBands is empty to prevent log spam 1774 log("isAdditionalNrAdvancedBand: false because bands are empty; configs=" 1775 + mAdditionalNrAdvancedBands + ", bands=" + bands); 1776 } 1777 return false; 1778 } 1779 Set<Integer> intersection = new HashSet<>(mAdditionalNrAdvancedBands); 1780 intersection.retainAll(bands); 1781 return !intersection.isEmpty(); 1782 } 1783 isLte(int rat)1784 private boolean isLte(int rat) { 1785 return rat == TelephonyManager.NETWORK_TYPE_LTE 1786 || rat == TelephonyManager.NETWORK_TYPE_LTE_CA; 1787 } 1788 isPhysicalLinkActive()1789 private boolean isPhysicalLinkActive() { 1790 return mPhysicalLinkStatus == DataCallResponse.LINK_STATUS_ACTIVE; 1791 } 1792 getPhysicalLinkStatusFromPhysicalChannelConfig()1793 private int getPhysicalLinkStatusFromPhysicalChannelConfig() { 1794 return (mPhysicalChannelConfigs == null || mPhysicalChannelConfigs.isEmpty() 1795 || mDoesPccListIndicateIdle) 1796 ? DataCallResponse.LINK_STATUS_DORMANT : DataCallResponse.LINK_STATUS_ACTIVE; 1797 } 1798 getEventName(int event)1799 private String getEventName(int event) { 1800 try { 1801 return sEvents[event]; 1802 } catch (ArrayIndexOutOfBoundsException e) { 1803 return "EVENT_NOT_DEFINED"; 1804 } 1805 } 1806 isUsingPhysicalChannelConfigForRrcDetection()1807 private boolean isUsingPhysicalChannelConfigForRrcDetection() { 1808 return mIsPhysicalChannelConfig16Supported && !mIsUsingUserDataForRrcDetection; 1809 } 1810 log(String s)1811 protected void log(String s) { 1812 Rlog.d(TAG, "[" + mPhone.getPhoneId() + "] " + s); 1813 } 1814 loge(String s)1815 protected void loge(String s) { 1816 Rlog.e(TAG, "[" + mPhone.getPhoneId() + "] " + s); 1817 } 1818 1819 @Override toString()1820 public String toString() { 1821 return "mOverrideTimerRules=" + mOverrideTimerRules.toString() 1822 + ", mLteEnhancedPattern=" + mLteEnhancedPattern 1823 + ", mIsPhysicalChannelConfigOn=" + mIsPhysicalChannelConfigOn 1824 + ", mIsPrimaryTimerActive=" + mIsPrimaryTimerActive 1825 + ", mIsSecondaryTimerActive=" + mIsSecondaryTimerActive 1826 + ", mPrimaryTimerState=" + mPrimaryTimerState 1827 + ", mSecondaryTimerState=" + mSecondaryTimerState 1828 + ", mPreviousState=" + mPreviousState 1829 + ", mIsNrAdvanced=" + isNrAdvanced(); 1830 } 1831 1832 @Override dump(FileDescriptor fd, PrintWriter printWriter, String[] args)1833 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 1834 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 1835 pw.print("NetworkTypeController: "); 1836 super.dump(fd, pw, args); 1837 pw.flush(); 1838 pw.increaseIndent(); 1839 pw.println("mSubId=" + mPhone.getSubId()); 1840 pw.println("mOverrideTimerRules=" + mOverrideTimerRules); 1841 pw.println("mLteEnhancedPattern=" + mLteEnhancedPattern); 1842 pw.println("mIsPhysicalChannelConfigOn=" + mIsPhysicalChannelConfigOn); 1843 pw.println("mIsPrimaryTimerActive=" + mIsPrimaryTimerActive); 1844 pw.println("mPciChangedDuringPrimaryTimer=" + mPciChangedDuringPrimaryTimer); 1845 pw.println("mIsSecondaryTimerActive=" + mIsSecondaryTimerActive); 1846 pw.println("mIsTimerResetEnabledForLegacyStateRrcIdle=" 1847 + mIsTimerResetEnabledForLegacyStateRrcIdle); 1848 pw.println("mLtePlusThresholdBandwidth=" + mLtePlusThresholdBandwidth); 1849 pw.println("mNrAdvancedThresholdBandwidth=" + mNrAdvancedThresholdBandwidth); 1850 pw.println("mIncludeLteForNrAdvancedThresholdBandwidth=" 1851 + mIncludeLteForNrAdvancedThresholdBandwidth); 1852 pw.println("mRatchetPccFieldsForSameAnchorNrCell=" + mRatchetPccFieldsForSameAnchorNrCell); 1853 pw.println("mRatchetedNrBandwidths=" + mRatchetedNrBandwidths); 1854 pw.println("mAdditionalNrAdvancedBandsList=" + mAdditionalNrAdvancedBands); 1855 pw.println("mRatchetedNrBands=" + mRatchetedNrBands); 1856 pw.println("mLastAnchorNrCellId=" + mLastAnchorNrCellId); 1857 pw.println("mDoesPccListIndicateIdle=" + mDoesPccListIndicateIdle); 1858 pw.println("mPrimaryTimerState=" + mPrimaryTimerState); 1859 pw.println("mSecondaryTimerState=" + mSecondaryTimerState); 1860 pw.println("mPreviousState=" + mPreviousState); 1861 pw.println("mPhysicalLinkStatus=" + DataUtils.linkStatusToString(mPhysicalLinkStatus)); 1862 pw.println("mIsPhysicalChannelConfig16Supported=" + mIsPhysicalChannelConfig16Supported); 1863 pw.println("mIsNrAdvancedAllowedByPco=" + mIsNrAdvancedAllowedByPco); 1864 pw.println("mNrAdvancedCapablePcoId=" + mNrAdvancedCapablePcoId); 1865 pw.println("mIsUsingUserDataForRrcDetection=" + mIsUsingUserDataForRrcDetection); 1866 pw.println("mPrimaryCellChangedWhileIdle=" + mPrimaryCellChangedWhileIdle); 1867 pw.println("mEnableNrAdvancedWhileRoaming=" + mEnableNrAdvancedWhileRoaming); 1868 pw.println("mIsDeviceIdleMode=" + mIsDeviceIdleMode); 1869 pw.println("mIsTimerResetEnabledOnVoiceQos=" + mIsTimerResetEnabledOnVoiceQos); 1870 pw.decreaseIndent(); 1871 pw.flush(); 1872 } 1873 } 1874