aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/android/internal/telephony/NetworkTypeController.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/android/internal/telephony/NetworkTypeController.java')
-rw-r--r--src/java/com/android/internal/telephony/NetworkTypeController.java220
1 files changed, 149 insertions, 71 deletions
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index beebf2206e..d1c83590d3 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -29,6 +29,7 @@ import android.os.PowerManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation;
import android.telephony.CarrierConfigManager;
+import android.telephony.CellInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
@@ -40,7 +41,6 @@ import android.text.TextUtils;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
import com.android.internal.telephony.data.DataUtils;
-import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.util.IState;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.State;
@@ -52,9 +52,11 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
@@ -105,7 +107,7 @@ public class NetworkTypeController extends StateMachine {
/** Event for preferred network mode changed. */
private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 10;
/** Event for physical channel configs changed. */
- private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 11;
+ private static final int EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED = 11;
/** Event for device idle mode changed, when device goes to deep sleep and pauses all timers. */
private static final int EVENT_DEVICE_IDLE_MODE_CHANGED = 12;
@@ -123,13 +125,13 @@ public class NetworkTypeController extends StateMachine {
sEvents[EVENT_RADIO_OFF_OR_UNAVAILABLE] = "EVENT_RADIO_OFF_OR_UNAVAILABLE";
sEvents[EVENT_PREFERRED_NETWORK_MODE_CHANGED] = "EVENT_PREFERRED_NETWORK_MODE_CHANGED";
sEvents[EVENT_INITIALIZE] = "EVENT_INITIALIZE";
- sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED] = "EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED";
+ sEvents[EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED] = "EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED";
sEvents[EVENT_DEVICE_IDLE_MODE_CHANGED] = "EVENT_DEVICE_IDLE_MODE_CHANGED";
}
- private final @NonNull Phone mPhone;
- private final @NonNull DisplayInfoController mDisplayInfoController;
- private final @NonNull BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @NonNull private final Phone mPhone;
+ @NonNull private final DisplayInfoController mDisplayInfoController;
+ @NonNull private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
@@ -140,7 +142,7 @@ public class NetworkTypeController extends StateMachine {
}
};
- private final @NonNull CarrierConfigManager.CarrierConfigChangeListener
+ @NonNull private final CarrierConfigManager.CarrierConfigChangeListener
mCarrierConfigChangeListener =
new CarrierConfigManager.CarrierConfigChangeListener() {
@Override
@@ -153,9 +155,9 @@ public class NetworkTypeController extends StateMachine {
}
};
- private @NonNull Map<String, OverrideTimerRule> mOverrideTimerRules = new HashMap<>();
- private @NonNull String mLteEnhancedPattern = "";
- private @Annotation.OverrideNetworkType int mOverrideNetworkType;
+ @NonNull private Map<String, OverrideTimerRule> mOverrideTimerRules = new HashMap<>();
+ @NonNull private String mLteEnhancedPattern = "";
+ @Annotation.OverrideNetworkType private int mOverrideNetworkType;
private boolean mIsPhysicalChannelConfigOn;
private boolean mIsPrimaryTimerActive;
private boolean mIsSecondaryTimerActive;
@@ -163,11 +165,12 @@ public class NetworkTypeController extends StateMachine {
private int mLtePlusThresholdBandwidth;
private int mNrAdvancedThresholdBandwidth;
private boolean mIncludeLteForNrAdvancedThresholdBandwidth;
- private @NonNull int[] mAdditionalNrAdvancedBandsList;
- private @NonNull String mPrimaryTimerState;
- private @NonNull String mSecondaryTimerState;
- private @NonNull String mPreviousState;
- private @LinkStatus int mPhysicalLinkStatus;
+ private boolean mRatchetPccFieldsForSameAnchorNrCell;
+ @NonNull private final Set<Integer> mAdditionalNrAdvancedBands = new HashSet<>();
+ @NonNull private String mPrimaryTimerState;
+ @NonNull private String mSecondaryTimerState;
+ @NonNull private String mPreviousState;
+ @LinkStatus private int mPhysicalLinkStatus;
private boolean mIsPhysicalChannelConfig16Supported;
private boolean mIsNrAdvancedAllowedByPco = false;
private int mNrAdvancedCapablePcoId = 0;
@@ -175,12 +178,17 @@ public class NetworkTypeController extends StateMachine {
private boolean mEnableNrAdvancedWhileRoaming = true;
private boolean mIsDeviceIdleMode = false;
- private @Nullable DataNetworkControllerCallback mNrAdvancedCapableByPcoChangedCallback = null;
- private @Nullable DataNetworkControllerCallback mNrPhysicalLinkStatusChangedCallback = null;
+ @Nullable private DataNetworkControllerCallback mNrAdvancedCapableByPcoChangedCallback = null;
+ @Nullable private DataNetworkControllerCallback mNrPhysicalLinkStatusChangedCallback = null;
// Cached copies below to prevent race conditions
- private @NonNull ServiceState mServiceState;
- private @Nullable List<PhysicalChannelConfig> mPhysicalChannelConfigs;
+ @NonNull private ServiceState mServiceState;
+ @Nullable private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
+
+ // Ratchet physical channel config fields to prevent 5G/5G+ flickering
+ @NonNull private Set<Integer> mRatchetedNrBands = new HashSet<>();
+ private int mRatchetedNrBandwidths = 0;
+ private int mLastAnchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
/**
* NetworkTypeController constructor.
@@ -246,7 +254,7 @@ public class NetworkTypeController extends StateMachine {
mPhone.registerForPreferredNetworkTypeChanged(getHandler(),
EVENT_PREFERRED_NETWORK_MODE_CHANGED, null);
mPhone.registerForPhysicalChannelConfig(getHandler(),
- EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, null);
+ EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED, null);
mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(),
EVENT_SERVICE_STATE_CHANGED, null);
mIsPhysicalChannelConfig16Supported = mPhone.getContext().getSystemService(
@@ -293,10 +301,16 @@ public class NetworkTypeController extends StateMachine {
CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT);
mIncludeLteForNrAdvancedThresholdBandwidth = config.getBoolean(
CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL);
+ mRatchetPccFieldsForSameAnchorNrCell = config.getBoolean(
+ CarrierConfigManager.KEY_RATCHET_NR_ADVANCED_BANDWIDTH_IF_RRC_IDLE_BOOL);
mEnableNrAdvancedWhileRoaming = config.getBoolean(
CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
- mAdditionalNrAdvancedBandsList = config.getIntArray(
+ mAdditionalNrAdvancedBands.clear();
+ int[] additionalNrAdvancedBands = config.getIntArray(
CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY);
+ if (additionalNrAdvancedBands != null) {
+ Arrays.stream(additionalNrAdvancedBands).forEach(mAdditionalNrAdvancedBands::add);
+ }
mNrAdvancedCapablePcoId = config.getInt(
CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
if (mNrAdvancedCapablePcoId > 0 && mNrAdvancedCapableByPcoChangedCallback == null) {
@@ -343,6 +357,7 @@ public class NetworkTypeController extends StateMachine {
String overrideSecondaryTimerRule = config.getString(
CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING);
createTimerRules(nrIconConfiguration, overrideTimerRule, overrideSecondaryTimerRule);
+ updatePhysicalChannelConfigs();
}
private void createTimerRules(String icons, String timers, String secondaryTimers) {
@@ -553,9 +568,9 @@ public class NetworkTypeController extends StateMachine {
quit();
break;
case EVENT_INITIALIZE:
- // The reason that we do it here is because some of the works below requires
- // other modules (e.g. DataNetworkController, ServiceStateTracker), which is not
- // created yet when NetworkTypeController is created.
+ // The reason that we do it here is that the work below requires other modules
+ // (e.g. DataNetworkController, ServiceStateTracker), which are not created
+ // when NetworkTypeController is created.
registerForAllEvents();
parseCarrierConfigs();
break;
@@ -579,6 +594,9 @@ public class NetworkTypeController extends StateMachine {
log("Reset timers since physical channel config indications are off.");
}
resetAllTimers();
+ mRatchetedNrBands.clear();
+ mRatchetedNrBandwidths = 0;
+ mLastAnchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
}
transitionToCurrentState();
break;
@@ -609,10 +627,8 @@ public class NetworkTypeController extends StateMachine {
resetAllTimers();
transitionToCurrentState();
break;
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
- mPhysicalChannelConfigs =
- mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
- if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+ case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED:
+ updatePhysicalChannelConfigs();
if (isUsingPhysicalChannelConfigForRrcDetection()) {
mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
}
@@ -689,10 +705,8 @@ public class NetworkTypeController extends StateMachine {
}
mIsNrRestricted = isNrRestricted();
break;
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
- mPhysicalChannelConfigs =
- mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
- if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+ case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED:
+ updatePhysicalChannelConfigs();
if (isUsingPhysicalChannelConfigForRrcDetection()) {
mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
if (mIsTimerResetEnabledForLegacyStateRrcIdle && !isPhysicalLinkActive()) {
@@ -770,10 +784,8 @@ public class NetworkTypeController extends StateMachine {
}
}
break;
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
- mPhysicalChannelConfigs =
- mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
- if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+ case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED:
+ updatePhysicalChannelConfigs();
if (isUsingPhysicalChannelConfigForRrcDetection()) {
mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
if (isPhysicalLinkActive()) {
@@ -854,10 +866,8 @@ public class NetworkTypeController extends StateMachine {
}
}
break;
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
- mPhysicalChannelConfigs =
- mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
- if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+ case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED:
+ updatePhysicalChannelConfigs();
if (isUsingPhysicalChannelConfigForRrcDetection()) {
mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
if (!isPhysicalLinkActive()) {
@@ -935,10 +945,8 @@ public class NetworkTypeController extends StateMachine {
transitionWithTimerTo(mLegacyState);
}
break;
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
- mPhysicalChannelConfigs =
- mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
- if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+ case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED:
+ updatePhysicalChannelConfigs();
if (isUsingPhysicalChannelConfigForRrcDetection()) {
mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
}
@@ -1016,10 +1024,8 @@ public class NetworkTypeController extends StateMachine {
transitionWithTimerTo(mLegacyState);
}
break;
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
- mPhysicalChannelConfigs =
- mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
- if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+ case EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED:
+ updatePhysicalChannelConfigs();
if (isUsingPhysicalChannelConfigForRrcDetection()) {
mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
}
@@ -1050,6 +1056,77 @@ public class NetworkTypeController extends StateMachine {
private final NrConnectedAdvancedState mNrConnectedAdvancedState =
new NrConnectedAdvancedState();
+ private void updatePhysicalChannelConfigs() {
+ List<PhysicalChannelConfig> physicalChannelConfigs =
+ mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+ boolean isPccListEmpty = physicalChannelConfigs == null || physicalChannelConfigs.isEmpty();
+ if (isPccListEmpty && isUsingPhysicalChannelConfigForRrcDetection()) {
+ log("Physical channel configs updated: not updating PCC fields for empty PCC list "
+ + "indicating RRC idle.");
+ mPhysicalChannelConfigs = physicalChannelConfigs;
+ return;
+ }
+
+ int anchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
+ int anchorLteCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
+ int nrBandwidths = 0;
+ Set<Integer> nrBands = new HashSet<>();
+ if (physicalChannelConfigs != null) {
+ for (PhysicalChannelConfig config : physicalChannelConfigs) {
+ if (config.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR) {
+ if (config.getConnectionStatus() == CellInfo.CONNECTION_PRIMARY_SERVING
+ && anchorNrCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) {
+ anchorNrCellId = config.getPhysicalCellId();
+ }
+ nrBandwidths += config.getCellBandwidthDownlinkKhz();
+ nrBands.add(config.getBand());
+ } else if (config.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE) {
+ if (config.getConnectionStatus() == CellInfo.CONNECTION_PRIMARY_SERVING
+ && anchorLteCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) {
+ anchorLteCellId = config.getPhysicalCellId();
+ }
+ if (mIncludeLteForNrAdvancedThresholdBandwidth) {
+ nrBandwidths += config.getCellBandwidthDownlinkKhz();
+ }
+ }
+ }
+ }
+
+ // Update anchor NR cell from anchor LTE cell for NR NSA
+ if (anchorNrCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN
+ && anchorLteCellId != PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) {
+ anchorNrCellId = anchorLteCellId;
+ }
+
+ if (anchorNrCellId == PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) {
+ if (!isPccListEmpty) {
+ log("Ignoring physical channel config fields without an anchor NR cell, "
+ + "either due to LTE-only configs or an unspecified cell ID.");
+ }
+ mRatchetedNrBandwidths = 0;
+ mRatchetedNrBands.clear();
+ } else if (anchorNrCellId == mLastAnchorNrCellId && mRatchetPccFieldsForSameAnchorNrCell) {
+ log("Ratchet physical channel config fields since anchor NR cell is the same.");
+ mRatchetedNrBandwidths = Math.max(mRatchetedNrBandwidths, nrBandwidths);
+ mRatchetedNrBands.addAll(nrBands);
+ } else {
+ if (mRatchetPccFieldsForSameAnchorNrCell) {
+ log("Not ratcheting physical channel config fields since anchor NR cell changed: "
+ + mLastAnchorNrCellId + " -> " + anchorNrCellId);
+ }
+ mRatchetedNrBandwidths = nrBandwidths;
+ mRatchetedNrBands = nrBands;
+ }
+
+ mLastAnchorNrCellId = anchorNrCellId;
+ mPhysicalChannelConfigs = physicalChannelConfigs;
+ if (DBG) {
+ log("Physical channel configs updated: anchorNrCell=" + mLastAnchorNrCellId
+ + ", nrBandwidths=" + mRatchetedNrBandwidths + ", nrBands=" + mRatchetedNrBands
+ + ", configs=" + mPhysicalChannelConfigs);
+ }
+ }
+
private void transitionWithTimerTo(IState destState) {
String destName = destState.getName();
if (DBG) log("Transition with primary timer from " + mPreviousState + " to " + destName);
@@ -1275,29 +1352,25 @@ public class NetworkTypeController extends StateMachine {
// Check PCO requirement. For carriers using PCO to indicate whether the data connection is
// NR advanced capable, mNrAdvancedCapablePcoId should be configured to non-zero.
if (mNrAdvancedCapablePcoId > 0 && !mIsNrAdvancedAllowedByPco) {
+ if (DBG) log("isNrAdvanced: not allowed by PCO for PCO ID " + mNrAdvancedCapablePcoId);
return false;
}
// Check if NR advanced is enabled when the device is roaming. Some carriers disable it
// while the device is roaming.
if (mServiceState.getDataRoaming() && !mEnableNrAdvancedWhileRoaming) {
+ if (DBG) log("isNrAdvanced: false because NR advanced is unavailable while roaming.");
return false;
}
- int bandwidths = 0;
- if (mPhone.getServiceStateTracker().getPhysicalChannelConfigList() != null) {
- bandwidths = mPhone.getServiceStateTracker().getPhysicalChannelConfigList()
- .stream()
- .filter(config -> mIncludeLteForNrAdvancedThresholdBandwidth
- || config.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR)
- .map(PhysicalChannelConfig::getCellBandwidthDownlinkKhz)
- .mapToInt(Integer::intValue)
- .sum();
- }
-
// Check if meeting minimum bandwidth requirement. For most carriers, there is no minimum
// bandwidth requirement and mNrAdvancedThresholdBandwidth is 0.
- if (mNrAdvancedThresholdBandwidth > 0 && bandwidths < mNrAdvancedThresholdBandwidth) {
+ if (mNrAdvancedThresholdBandwidth > 0
+ && mRatchetedNrBandwidths < mNrAdvancedThresholdBandwidth) {
+ if (DBG) {
+ log("isNrAdvanced: false because bandwidths=" + mRatchetedNrBandwidths
+ + " does not meet the threshold=" + mNrAdvancedThresholdBandwidth);
+ }
return false;
}
@@ -1311,17 +1384,17 @@ public class NetworkTypeController extends StateMachine {
}
private boolean isAdditionalNrAdvancedBand() {
- if (ArrayUtils.isEmpty(mAdditionalNrAdvancedBandsList)
- || mPhysicalChannelConfigs == null) {
- return false;
- }
- for (PhysicalChannelConfig item : mPhysicalChannelConfigs) {
- if (item.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR
- && ArrayUtils.contains(mAdditionalNrAdvancedBandsList, item.getBand())) {
- return true;
+ if (mAdditionalNrAdvancedBands.isEmpty() || mRatchetedNrBands.isEmpty()) {
+ if (DBG && !mAdditionalNrAdvancedBands.isEmpty()) {
+ // Only log if mAdditionalNrAdvancedBands is empty to prevent log spam
+ log("isAdditionalNrAdvancedBand: false because bands are empty; configs="
+ + mAdditionalNrAdvancedBands + ", bands=" + mRatchetedNrBands);
}
+ return false;
}
- return false;
+ Set<Integer> intersection = new HashSet<>(mAdditionalNrAdvancedBands);
+ intersection.retainAll(mRatchetedNrBands);
+ return !intersection.isEmpty();
}
private boolean isLte(int rat) {
@@ -1388,8 +1461,13 @@ public class NetworkTypeController extends StateMachine {
+ mIsTimerResetEnabledForLegacyStateRrcIdle);
pw.println("mLtePlusThresholdBandwidth=" + mLtePlusThresholdBandwidth);
pw.println("mNrAdvancedThresholdBandwidth=" + mNrAdvancedThresholdBandwidth);
- pw.println("mAdditionalNrAdvancedBandsList="
- + Arrays.toString(mAdditionalNrAdvancedBandsList));
+ pw.println("mIncludeLteForNrAdvancedThresholdBandwidth="
+ + mIncludeLteForNrAdvancedThresholdBandwidth);
+ pw.println("mRatchetPccFieldsForSameAnchorNrCell=" + mRatchetPccFieldsForSameAnchorNrCell);
+ pw.println("mRatchetedNrBandwidths=" + mRatchetedNrBandwidths);
+ pw.println("mAdditionalNrAdvancedBandsList=" + mAdditionalNrAdvancedBands);
+ pw.println("mRatchetedNrBands=" + mRatchetedNrBands);
+ pw.println("mLastAnchorNrCellId=" + mLastAnchorNrCellId);
pw.println("mPrimaryTimerState=" + mPrimaryTimerState);
pw.println("mSecondaryTimerState=" + mSecondaryTimerState);
pw.println("mPreviousState=" + mPreviousState);