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