Merge "Optimize usage of CarrierConfigEfData"
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index dc32ba5..949feee 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -82,6 +82,8 @@
private static final int EVENT_DEFAULT_DATA_SUBSCRIPTION_CHANGED = 6;
private static final int EVENT_CARRIER_CONFIG_CHANGED = 7;
private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 8;
+ @VisibleForTesting
+ public static final int EVENT_RADIO_STATE_CHANGED = 9;
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"PRIMARY_SUB_"},
@@ -294,6 +296,16 @@
case EVENT_MULTI_SIM_CONFIG_CHANGED:
int activeModems = (int) ((AsyncResult) msg.obj).result;
onMultiSimConfigChanged(activeModems);
+ break;
+ case EVENT_RADIO_STATE_CHANGED:
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (phone.mCi.getRadioState() == TelephonyManager.RADIO_POWER_UNAVAILABLE) {
+ if (DBG) log("Radio unavailable. Clearing sub info initialized flag.");
+ mSubInfoInitialized = false;
+ break;
+ }
+ }
+ break;
}
}
@@ -335,6 +347,9 @@
private void onAllSubscriptionsLoaded() {
if (DBG) log("onAllSubscriptionsLoaded");
mSubInfoInitialized = true;
+ for (Phone phone : PhoneFactory.getPhones()) {
+ phone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
+ }
reEvaluateAll();
}
@@ -424,6 +439,9 @@
for (int phoneId = activeModems; phoneId < mCarrierConfigLoadedSubIds.length; phoneId++) {
mCarrierConfigLoadedSubIds[phoneId] = INVALID_SUBSCRIPTION_ID;
}
+ for (Phone phone : PhoneFactory.getPhones()) {
+ phone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
+ }
}
/**
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index edd49b1..5d5fca0 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -27,15 +27,19 @@
import android.telephony.Annotation;
import android.telephony.CarrierConfigManager;
import android.telephony.NetworkRegistrationInfo;
+import android.telephony.PcoData;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.text.TextUtils;
+import com.android.internal.telephony.dataconnection.DataConnection;
import com.android.internal.telephony.dataconnection.DcController;
import com.android.internal.telephony.dataconnection.DcController.PhysicalLinkState;
+import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.util.IState;
import com.android.internal.util.IndentingPrintWriter;
@@ -93,8 +97,9 @@
private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 11;
private static final int EVENT_INITIALIZE = 12;
private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
+ private static final int EVENT_PCO_DATA_CHANGED = 14;
- private static final String[] sEvents = new String[EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED + 1];
+ private static final String[] sEvents = new String[EVENT_PCO_DATA_CHANGED + 1];
static {
sEvents[EVENT_UPDATE] = "EVENT_UPDATE";
sEvents[EVENT_QUIT] = "EVENT_QUIT";
@@ -111,6 +116,7 @@
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_PCO_DATA_CHANGED] = "EVENT_PCO_DATA_CHANGED";
}
private final Phone mPhone;
@@ -141,6 +147,9 @@
private String mSecondaryTimerState;
private String mPreviousState;
private @PhysicalLinkState int mPhysicalLinkState;
+ private boolean mIsPhysicalChannelConfig16Supported;
+ private Boolean mIsNrAdvancedAllowedByPco = false;
+ private int mNrAdvancedCapablePcoId = 0;
/**
* NetworkTypeController constructor.
@@ -190,9 +199,14 @@
mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler(),
EVENT_DATA_RAT_CHANGED, null);
- mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .registerForPhysicalLinkStateChanged(getHandler(),
- EVENT_PHYSICAL_LINK_STATE_CHANGED);
+ mIsPhysicalChannelConfig16Supported = mPhone.getContext().getSystemService(
+ TelephonyManager.class).isRadioInterfaceCapabilitySupported(
+ TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+ if (!mIsPhysicalChannelConfig16Supported) {
+ mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .registerForPhysicalLinkStateChanged(getHandler(),
+ EVENT_PHYSICAL_LINK_STATE_CHANGED);
+ }
mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(),
EVENT_NR_STATE_CHANGED, null);
mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(),
@@ -202,6 +216,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
+ mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null);
}
private void unRegisterForAllEvents() {
@@ -213,6 +228,7 @@
mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler());
mPhone.getContext().unregisterReceiver(mIntentReceiver);
+ mPhone.mCi.unregisterForPcoData(getHandler());
}
private void parseCarrierConfigs() {
@@ -261,6 +277,8 @@
mLtePlusThresholdBandwidth);
mAdditionalNrAdvancedBandsList = b.getIntArray(
CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY);
+ mNrAdvancedCapablePcoId = b.getInt(
+ CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
}
}
createTimerRules(nrIconConfiguration, overrideTimerRule, overrideSecondaryTimerRule);
@@ -481,9 +499,14 @@
case EVENT_DATA_RAT_CHANGED:
case EVENT_NR_STATE_CHANGED:
case EVENT_NR_FREQUENCY_CHANGED:
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+ case EVENT_PCO_DATA_CHANGED:
// ignored
break;
+ case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+ if (mIsPhysicalChannelConfig16Supported) {
+ mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
+ }
+ break;
case EVENT_PHYSICAL_LINK_STATE_CHANGED:
AsyncResult ar = (AsyncResult) msg.obj;
mPhysicalLinkState = (int) ar.result;
@@ -582,9 +605,18 @@
mIsNrRestricted = isNrRestricted();
break;
case EVENT_NR_FREQUENCY_CHANGED:
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
// ignored
break;
+ case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+ if (mIsPhysicalChannelConfig16Supported) {
+ mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
+ if (mIsTimerResetEnabledForLegacyStateRRCIdle && !isPhysicalLinkActive()) {
+ resetAllTimers();
+ }
+ }
+ // Update in case of LTE/LTE+ switch
+ updateOverrideNetworkType();
+ break;
case EVENT_PHYSICAL_LINK_STATE_CHANGED:
AsyncResult ar = (AsyncResult) msg.obj;
mPhysicalLinkState = (int) ar.result;
@@ -645,9 +677,25 @@
}
break;
case EVENT_NR_FREQUENCY_CHANGED:
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
// ignore
break;
+ case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+ if (mIsPhysicalChannelConfig16Supported) {
+ mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
+ if (isNrNotRestricted()) {
+ // NOT_RESTRICTED_RRC_IDLE -> NOT_RESTRICTED_RRC_CON
+ if (isPhysicalLinkActive()) {
+ transitionWithTimerTo(mLteConnectedState);
+ break;
+ }
+ } else {
+ log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
+ sendMessage(EVENT_NR_STATE_CHANGED);
+ }
+ }
+ // Update in case of LTE/LTE+ switch
+ updateOverrideNetworkType();
+ break;
case EVENT_PHYSICAL_LINK_STATE_CHANGED:
AsyncResult ar = (AsyncResult) msg.obj;
mPhysicalLinkState = (int) ar.result;
@@ -713,9 +761,25 @@
}
break;
case EVENT_NR_FREQUENCY_CHANGED:
- case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
// ignore
break;
+ case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+ if (mIsPhysicalChannelConfig16Supported) {
+ mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
+ if (isNrNotRestricted()) {
+ // NOT_RESTRICTED_RRC_CON -> NOT_RESTRICTED_RRC_IDLE
+ if (!isPhysicalLinkActive()) {
+ transitionWithTimerTo(mIdleState);
+ break;
+ }
+ } else {
+ log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
+ sendMessage(EVENT_NR_STATE_CHANGED);
+ }
+ }
+ // Update in case of LTE/LTE+ switch
+ updateOverrideNetworkType();
+ break;
case EVENT_PHYSICAL_LINK_STATE_CHANGED:
AsyncResult ar = (AsyncResult) msg.obj;
mPhysicalLinkState = (int) ar.result;
@@ -787,21 +851,15 @@
transitionWithTimerTo(mLegacyState);
}
break;
+ case EVENT_PCO_DATA_CHANGED:
+ handlePcoData((AsyncResult) msg.obj);
+ break;
case EVENT_NR_FREQUENCY_CHANGED:
case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
- if (!isNrConnected()) {
- log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
- sendMessage(EVENT_NR_STATE_CHANGED);
- break;
+ if (mIsPhysicalChannelConfig16Supported) {
+ mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
}
- if (!isNrAdvanced()) {
- // STATE_CONNECTED_NR_ADVANCED -> STATE_CONNECTED
- transitionWithTimerTo(mNrConnectedState);
- } else {
- // STATE_CONNECTED -> STATE_CONNECTED_NR_ADVANCED
- transitionTo(mNrConnectedState);
- }
- mIsNrAdvanced = isNrAdvanced();
+ updateNrAdvancedState();
break;
case EVENT_PHYSICAL_LINK_STATE_CHANGED:
AsyncResult ar = (AsyncResult) msg.obj;
@@ -824,6 +882,47 @@
public String getName() {
return mIsNrAdvanced ? STATE_CONNECTED_NR_ADVANCED : STATE_CONNECTED;
}
+
+ private void updateNrAdvancedState() {
+ if (!isNrConnected()) {
+ log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
+ sendMessage(EVENT_NR_STATE_CHANGED);
+ return;
+ }
+ if (!isNrAdvanced()) {
+ // STATE_CONNECTED_NR_ADVANCED -> STATE_CONNECTED
+ transitionWithTimerTo(mNrConnectedState);
+ } else {
+ // STATE_CONNECTED -> STATE_CONNECTED_NR_ADVANCED
+ transitionTo(mNrConnectedState);
+ }
+ mIsNrAdvanced = isNrAdvanced();
+ }
+
+ private void handlePcoData(AsyncResult ar) {
+ if (ar.exception != null) {
+ loge("PCO_DATA exception: " + ar.exception);
+ return;
+ }
+ PcoData pcodata = (PcoData) ar.result;
+ if (pcodata == null) {
+ return;
+ }
+ log("EVENT_PCO_DATA_CHANGED: pco data: " + pcodata);
+ DcTracker dcTracker = mPhone.getDcTracker(
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+ DataConnection dc =
+ dcTracker != null ? dcTracker.getDataConnectionByContextId(pcodata.cid) : null;
+ ApnSetting apnSettings = dc != null ? dc.getApnSetting() : null;
+ if (apnSettings != null && apnSettings.canHandleType(ApnSetting.TYPE_DEFAULT)
+ && mNrAdvancedCapablePcoId > 0
+ && pcodata.pcoId == mNrAdvancedCapablePcoId
+ ) {
+ log("EVENT_PCO_DATA_CHANGED: Nr Advanced is allowed by PCO.");
+ mIsNrAdvancedAllowedByPco = pcodata.contents[0] == 1;
+ updateNrAdvancedState();
+ }
+ }
}
private final NrConnectedState mNrConnectedState = new NrConnectedState();
@@ -1027,7 +1126,7 @@
}
private boolean isNrAdvanced() {
- return isNrMmwave() || isAdditionalNrAdvancedBand();
+ return isNrAdvancedCapable() && (isNrMmwave() || isAdditionalNrAdvancedBand());
}
private boolean isNrMmwave() {
@@ -1051,6 +1150,13 @@
return false;
}
+ private boolean isNrAdvancedCapable() {
+ if (mNrAdvancedCapablePcoId > 0) {
+ return mIsNrAdvancedAllowedByPco;
+ }
+ return true;
+ }
+
private boolean isLte(int rat) {
return rat == TelephonyManager.NETWORK_TYPE_LTE
|| rat == TelephonyManager.NETWORK_TYPE_LTE_CA;
@@ -1060,6 +1166,13 @@
return mPhysicalLinkState == DcController.PHYSICAL_LINK_ACTIVE;
}
+ private int getPhysicalLinkStateFromPhysicalChannelConfig() {
+ List<PhysicalChannelConfig> physicalChannelConfigList =
+ mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+ return (physicalChannelConfigList == null || physicalChannelConfigList.isEmpty())
+ ? DcController.PHYSICAL_LINK_NOT_ACTIVE : DcController.PHYSICAL_LINK_ACTIVE;
+ }
+
private int getDataNetworkType() {
NetworkRegistrationInfo nri = mPhone.getServiceState().getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1092,7 +1205,8 @@
+ ", mIsSecondaryTimerActive=" + mIsSecondaryTimerActive
+ ", mPrimaryTimerState=" + mPrimaryTimerState
+ ", mSecondaryTimerState=" + mSecondaryTimerState
- + ", mPreviousState=" + mPreviousState;
+ + ", mPreviousState=" + mPreviousState
+ + ", misNrAdvanced=" + isNrAdvanced();
}
@Override
@@ -1117,6 +1231,7 @@
pw.println("mPhysicalLinkState=" + mPhysicalLinkState);
pw.println("mAdditionalNrAdvancedBandsList="
+ Arrays.toString(mAdditionalNrAdvancedBandsList));
+ pw.println("mNrAdvancedCapablePcoId=" + mNrAdvancedCapablePcoId);
pw.decreaseIndent();
pw.flush();
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 2155c4a..8fea92f 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -187,7 +187,8 @@
protected static final int EVENT_RUIM_RECORDS_LOADED = 22;
protected static final int EVENT_NV_READY = 23;
private static final int EVENT_SET_ENHANCED_VP = 24;
- protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25;
+ @VisibleForTesting
+ public static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25;
protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
// other
@@ -1844,6 +1845,17 @@
}
/**
+ * Check whether the radio is off for thermal reason.
+ *
+ * @return {@code true} only if thermal mitigation is one of the reason for which radio is off.
+ */
+ public boolean isRadioOffForThermalMitigation() {
+ ServiceStateTracker sst = getServiceStateTracker();
+ return sst != null && sst.getRadioPowerOffReasons()
+ .contains(Phone.RADIO_POWER_REASON_THERMAL);
+ }
+
+ /**
* Retrieves the EmergencyNumberTracker of the phone instance.
*/
public EmergencyNumberTracker getEmergencyNumberTracker() {
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index 598e8db..19c6021 100644
--- a/src/java/com/android/internal/telephony/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -433,8 +433,7 @@
NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
builder.build(), this);
// we want to see all requests
- networkFactory.setScoreFilter(101);
- networkFactory.register();
+ networkFactory.registerIgnoringScore();
updateHalCommandToUse();
diff --git a/src/java/com/android/internal/telephony/RadioConfigResponse.java b/src/java/com/android/internal/telephony/RadioConfigResponse.java
index bbacbdc..1ec9cff 100644
--- a/src/java/com/android/internal/telephony/RadioConfigResponse.java
+++ b/src/java/com/android/internal/telephony/RadioConfigResponse.java
@@ -19,6 +19,7 @@
import static android.telephony.TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED;
import static android.telephony.TelephonyManager
.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE;
+import static android.telephony.TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED;
import static android.telephony.TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE;
import static android.telephony.TelephonyManager.CAPABILITY_SIM_PHONEBOOK_IN_MODEM;
import static android.telephony.TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING;
@@ -311,6 +312,8 @@
Rlog.d(TAG, "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING");
caps.add(CAPABILITY_SIM_PHONEBOOK_IN_MODEM);
Rlog.d(TAG, "CAPABILITY_SIM_PHONEBOOK_IN_MODEM");
+ caps.add(CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+ Rlog.d(TAG, "CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED");
}
}
return caps;
diff --git a/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java b/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
index 99ffe36..de62c70 100644
--- a/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
+++ b/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
@@ -123,6 +123,10 @@
if (ar.exception != null) {
loge("setupRadioInterfaceCapabilities: " + ar.exception);
}
+ if (ar.result == null) {
+ loge("setupRadioInterfaceCapabilities: ar.result is null");
+ return;
+ }
log("setupRadioInterfaceCapabilities: "
+ "mRadioInterfaceCapabilities now setup");
mRadioInterfaceCapabilities =
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index c91bf40..fb7f8f5 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -1083,8 +1083,7 @@
/**
* @return the current reasons for which the radio is off.
*/
- @VisibleForTesting
- public Set<Integer> getRadioPowerOffReasonsForTest() {
+ public Set<Integer> getRadioPowerOffReasons() {
return sRadioPowerOffReasons;
}
@@ -1716,7 +1715,6 @@
log("EVENT_PHYSICAL_CHANNEL_CONFIG: size=" + list.size() + " list="
+ list);
}
- mPhone.notifyPhysicalChannelConfig(list);
mLastPhysicalChannelConfigList = list;
boolean hasChanged = false;
if (updateNrStateFromPhysicalChannelConfigs(list, mSS)) {
@@ -1730,6 +1728,7 @@
hasChanged |= RatRatcheter
.updateBandwidths(getBandwidthsFromConfigs(list), mSS);
+ mPhone.notifyPhysicalChannelConfig(list);
// Notify NR frequency, NR connection status or bandwidths changed.
if (hasChanged) {
mPhone.notifyServiceStateChanged(mSS);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index ef4af08..2051919 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -528,7 +528,10 @@
return mCid;
}
- ApnSetting getApnSetting() {
+ /**
+ * @return DataConnection's ApnSetting.
+ */
+ public ApnSetting getApnSetting() {
return mApnSetting;
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index d2fa226..4d4ca81 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -1593,8 +1593,7 @@
}
// Check if it fails because of the existing data is still disconnecting.
- if (dataConnectionReasons.containsOnly(
- DataDisallowedReasonType.DATA_IS_DISCONNECTING)
+ if (dataConnectionReasons.contains(DataDisallowedReasonType.DATA_IS_DISCONNECTING)
&& isHandoverPending(apnContext.getApnTypeBitmask())) {
// Normally we don't retry when isDataAllow() returns false, because that's consider
// pre-condition not met, for example, data not enabled by the user, or airplane
diff --git a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
index 4081cd6..df3f0f1 100644
--- a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
@@ -130,7 +130,15 @@
return makeNetworkFilter(subscriptionId);
}
- private NetworkCapabilities makeNetworkFilter(int subscriptionId) {
+ /**
+ * Build the network request filter used by this factory.
+ * @param subscriptionId the subscription ID to listen to
+ * @return the filter to send to the system server
+ */
+ // This is used by the test to simulate the behavior of the system server, which is to
+ // send requests that match the network filter.
+ @VisibleForTesting
+ public NetworkCapabilities makeNetworkFilter(int subscriptionId) {
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
diff --git a/src/java/com/android/internal/telephony/uicc/PinStorage.java b/src/java/com/android/internal/telephony/uicc/PinStorage.java
index df20401..b348c61 100644
--- a/src/java/com/android/internal/telephony/uicc/PinStorage.java
+++ b/src/java/com/android/internal/telephony/uicc/PinStorage.java
@@ -25,6 +25,9 @@
import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT;
import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__CACHED_PIN_DISCARDED;
+import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_COUNT_NOT_MATCHING_AFTER_REBOOT;
+import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR;
+import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR;
import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT;
import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION;
import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE;
@@ -125,6 +128,7 @@
private static final String SHARED_PREFS_NAME = "pinstorage_prefs";
private static final String SHARED_PREFS_AVAILABLE_PIN_BASE_KEY = "encrypted_pin_available_";
private static final String SHARED_PREFS_REBOOT_PIN_BASE_KEY = "encrypted_pin_reboot_";
+ private static final String SHARED_PREFS_STORED_PINS = "stored_pins";
// Events
private static final int ICC_CHANGED_EVENT = 1;
@@ -347,6 +351,9 @@
PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT, notAvailableCount);
}
+ // Save number of PINs to generate metrics after reboot
+ saveNumberOfCachedPins(storedCount);
+
return result;
}
@@ -407,7 +414,7 @@
mShortTermSecretKey =
initializeSecretKey(KEYSTORE_ALIAS_SHORT_TERM, /*createIfAbsent=*/ false);
- boolean otaReboot = false;
+ int verificationReadyCount = 0;
int slotCount = getSlotCount();
for (int slotId = 0; slotId < slotCount; slotId++) {
// Read PIN information from storage
@@ -434,12 +441,22 @@
if (storedPin.status == PinStatus.REBOOT_READY) {
storedPin.status = PinStatus.VERIFICATION_READY;
savePinInformation(slotId, storedPin);
- otaReboot = true;
+ verificationReadyCount++;
}
}
- if (otaReboot) {
+ if (verificationReadyCount > 0) {
startTimer(TIMER_VALUE_AFTER_OTA_MILLIS);
}
+
+ // Generate metrics for PINs that had been stored before reboot, but are not available
+ // after. This can happen if there is an excessive delay in unlocking the device (short
+ // term key expires), but also if a new SIM card without PIN is present.
+ int prevCachedPinCount = saveNumberOfCachedPins(0);
+ if (prevCachedPinCount > verificationReadyCount) {
+ TelephonyStatsLog.write(PIN_STORAGE_EVENT,
+ PIN_STORAGE_EVENT__EVENT__PIN_COUNT_NOT_MATCHING_AFTER_REBOOT,
+ prevCachedPinCount - verificationReadyCount);
+ }
}
/**
@@ -484,6 +501,9 @@
deleteSecretKey(KEYSTORE_ALIAS_SHORT_TERM);
mShortTermSecretKey = null;
+ // Reset number of stored PINs (applicable if timer expired before unattended reboot).
+ saveNumberOfCachedPins(0);
+
// Write metrics about number of discarded PINs
if (discardedPin > 0) {
TelephonyStatsLog.write(PIN_STORAGE_EVENT,
@@ -892,6 +912,19 @@
}
}
+ /**
+ * Saves the number of cached PINs ready for verification after reboot and returns the
+ * previous value.
+ */
+ private int saveNumberOfCachedPins(int storedCount) {
+ SharedPreferences sharedPrefs =
+ mContext.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
+
+ int previousValue = sharedPrefs.getInt(SHARED_PREFS_STORED_PINS, 0);
+ sharedPrefs.edit().putInt(SHARED_PREFS_STORED_PINS, storedCount).commit();
+ return previousValue;
+ }
+
private boolean startTimer(int duration) {
removeMessages(TIMER_EXPIRATION_EVENT);
return duration > 0 ? sendEmptyMessageDelayed(TIMER_EXPIRATION_EVENT, duration) : true;
@@ -1118,6 +1151,8 @@
return EncryptedPin.toByteArray(encryptedPin);
} catch (Exception e) {
loge("Encrypt exception", e);
+ TelephonyStatsLog.write(PIN_STORAGE_EVENT,
+ PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR, 1);
}
return new byte[0];
}
@@ -1141,6 +1176,8 @@
}
} catch (Exception e) {
loge("Decrypt exception", e);
+ TelephonyStatsLog.write(PIN_STORAGE_EVENT,
+ PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR, 1);
}
return new byte[0];
}
diff --git a/tests/telephonytests/src/android/telephony/ims/RcsConfigTest.java b/tests/telephonytests/src/android/telephony/ims/RcsConfigTest.java
index 280176f..a81e93f 100644
--- a/tests/telephonytests/src/android/telephony/ims/RcsConfigTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/RcsConfigTest.java
@@ -277,14 +277,17 @@
@Test
@SmallTest
public void testIsRcsVolteSingleRegistrationSupported() {
- String[] vals = new String[]{"0", "1", "false", "true"};
- boolean[] expectedRes = new boolean[]{false, true, false, true};
+ String[] vals = new String[]{"0", "1", "2"};
+ boolean[] expectedResHome = new boolean[]{false, true, true};
+ boolean[] expectedResRoaming = new boolean[]{false, true, false};
for (int i = 0; i < vals.length; i++) {
String xml = "\t\t\t\t<characteristic type=\"GSMA\">\n"
+ "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\""
+ vals[i] + "\"/>\n" + "\t\t\t\t</characteristic>\n";
RcsConfig config = new RcsConfig(xml.getBytes());
- assertEquals(config.isRcsVolteSingleRegistrationSupported(), expectedRes[i]);
+ assertEquals(config.isRcsVolteSingleRegistrationSupported(false), expectedResHome[i]);
+ assertEquals(config.isRcsVolteSingleRegistrationSupported(true),
+ expectedResRoaming[i]);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index c93de7d..9058a44 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -50,6 +50,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+
import androidx.test.InstrumentationRegistry;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
@@ -62,6 +63,7 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
@@ -132,6 +134,8 @@
doReturn(true).when(mSubControllerMock).isOpportunistic(5);
doReturn(1).when(mPhoneMock1).getSubId();
doReturn(2).when(mPhoneMock2).getSubId();
+ mPhoneMock1.mCi = mSimulatedCommands;
+ mPhoneMock2.mCi = mSimulatedCommands;
List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo2);
doReturn(infoList).when(mSubControllerMock)
.getActiveSubscriptionInfoList(anyString(), nullable(String.class));
@@ -163,7 +167,7 @@
@Test
@SmallTest
- public void testTestSubInfoChangeBeforeAllSubReady() throws Exception {
+ public void testSubInfoChangeBeforeAllSubReady() throws Exception {
doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
.getDefaultDataSubId();
doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
@@ -199,6 +203,50 @@
}
@Test
+ public void testSubInfoChangeAfterRadioUnavailable() throws Exception {
+ mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
+ mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
+ mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+ processAllMessages();
+
+ // Notify radio unavailable.
+ replaceInstance(BaseCommands.class, "mState", mSimulatedCommands,
+ TelephonyManager.RADIO_POWER_UNAVAILABLE);
+ mMultiSimSettingControllerUT.obtainMessage(
+ MultiSimSettingController.EVENT_RADIO_STATE_CHANGED).sendToTarget();
+
+ // Mark all subs as inactive.
+ doReturn(false).when(mSubControllerMock).isActiveSubId(1);
+ doReturn(false).when(mSubControllerMock).isActiveSubId(2);
+ doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(1);
+ doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
+ doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock1).getSubId();
+ doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
+ List<SubscriptionInfo> infoList = new ArrayList<>();
+ doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+ nullable(String.class));
+ doReturn(new int[]{}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+ clearInvocations(mSubControllerMock);
+
+ // The below sub info change should be ignored.
+ mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
+ processAllMessages();
+ verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
+ verify(mSubControllerMock, never()).setDefaultVoiceSubId(anyInt());
+ verify(mSubControllerMock, never()).setDefaultSmsSubId(anyInt());
+
+ // Send all sub ready notification
+ mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
+ processAllMessages();
+
+ // Everything should be set to invalid since nothing is active.
+ verify(mSubControllerMock).setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ verify(mSubControllerMock)
+ .setDefaultVoiceSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ verify(mSubControllerMock).setDefaultSmsSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ }
+
+ @Test
@SmallTest
public void testSingleActiveDsds() throws Exception {
doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index ab25842..1fc5d37 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -29,14 +29,17 @@
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.NetworkRegistrationInfo;
+import android.telephony.PcoData;
import android.telephony.PhysicalChannelConfig;
import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import com.android.internal.telephony.dataconnection.DataConnection;
import com.android.internal.telephony.dataconnection.DcController;
import com.android.internal.util.IState;
import com.android.internal.util.StateMachine;
@@ -45,6 +48,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -66,9 +70,14 @@
private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 11;
private static final int EVENT_INITIALIZE = 12;
private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
+ private static final int EVENT_PCO_DATA_CHANGED = 14;
private NetworkTypeController mNetworkTypeController;
private PersistableBundle mBundle;
+ @Mock
+ DataConnection mDataConnection;
+ @Mock
+ ApnSetting mApnSetting;
private IState getCurrentState() throws Exception {
Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
@@ -103,6 +112,8 @@
doReturn(RadioAccessFamily.getRafFromNetworkType(
TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA)).when(
mPhone).getCachedAllowedNetworkTypesBitmask();
+ doReturn(false).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
+ TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
processAllMessages();
}
@@ -275,6 +286,22 @@
}
@Test
+ public void testTransitionToCurrentStateIdleSupportPhysicalChannelConfig1_6() throws Exception {
+ doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
+ TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+ mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
+ processAllMessages();
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
+ setPhysicalLinkState(false);
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
+ }
+
+ @Test
public void testTransitionToCurrentStateLteConnected() throws Exception {
assertEquals("DefaultState", getCurrentState().getName());
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
@@ -287,6 +314,23 @@
}
@Test
+ public void testTransitionToCurrentStateLteConnectedSupportPhysicalChannelConfig1_6()
+ throws Exception {
+ doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
+ TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+ mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
+ processAllMessages();
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
+ setPhysicalLinkState(true);
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("not_restricted_rrc_con", getCurrentState().getName());
+ }
+
+ @Test
public void testTransitionToCurrentStateNrConnected() throws Exception {
assertEquals("DefaultState", getCurrentState().getName());
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
@@ -322,9 +366,9 @@
.setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
.setBand(41)
.build();
- List<PhysicalChannelConfig> mLastPhysicalChannelConfigList = new ArrayList<>();
- mLastPhysicalChannelConfigList.add(physicalChannelConfig);
- doReturn(mLastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
+ List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
+ lastPhysicalChannelConfigList.add(physicalChannelConfig);
+ doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
broadcastCarrierConfigs();
mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
@@ -345,9 +389,9 @@
.setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
.setBand(2)
.build();
- List<PhysicalChannelConfig> mLastPhysicalChannelConfigList = new ArrayList<>();
- mLastPhysicalChannelConfigList.add(physicalChannelConfig);
- doReturn(mLastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
+ List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
+ lastPhysicalChannelConfigList.add(physicalChannelConfig);
+ doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
broadcastCarrierConfigs();
mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
@@ -356,6 +400,92 @@
}
@Test
+ public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapable() throws Exception {
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0);
+ broadcastCarrierConfigs();
+
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("connected_mmwave", getCurrentState().getName());
+ }
+
+ @Test
+ public void testTransitionToCurrentStateNrConnectedWithPcoAndNoNrAdvancedCapable()
+ throws Exception {
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
+ broadcastCarrierConfigs();
+ int cid = 1;
+ byte[] contents = new byte[]{0};
+ doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
+ doReturn(mApnSetting).when(mDataConnection).getApnSetting();
+ doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
+ broadcastCarrierConfigs();
+
+
+ mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
+ new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("connected", getCurrentState().getName());
+ }
+
+ @Test
+ public void testTransitionToCurrentStateNrConnectedWithWrongPcoAndNoNrAdvancedCapable()
+ throws Exception {
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
+ broadcastCarrierConfigs();
+ int cid = 1;
+ byte[] contents = new byte[]{1};
+ doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
+ doReturn(mApnSetting).when(mDataConnection).getApnSetting();
+ doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF00);
+ broadcastCarrierConfigs();
+
+
+ mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
+ new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("connected", getCurrentState().getName());
+ }
+
+ @Test
+ public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapableAndPco()
+ throws Exception {
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ int cid = 1;
+ byte[] contents = new byte[]{1};
+ doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
+ doReturn(mApnSetting).when(mDataConnection).getApnSetting();
+ doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
+ broadcastCarrierConfigs();
+
+ mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
+ new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("connected_mmwave", getCurrentState().getName());
+ }
+
+ @Test
public void testEventDataRatChanged() throws Exception {
testTransitionToCurrentStateLegacy();
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
@@ -415,12 +545,126 @@
}
@Test
+ public void testNrPhysicalChannelChange1_6FromNrConnectedMmwaveToLteConnected()
+ throws Exception {
+ doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
+ TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+ mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
+ processAllMessages();
+ testTransitionToCurrentStateNrConnectedMmwave();
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
+ setPhysicalLinkState(true);
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+ mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+ mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+
+ processAllMessages();
+
+ assertEquals("not_restricted_rrc_con", getCurrentState().getName());
+ }
+
+ @Test
+ public void testEventPhysicalChannelChangeFromLteToLteCaInLegacyState() throws Exception {
+ testTransitionToCurrentStateLegacy();
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ updateOverrideNetworkType();
+ assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
+ mNetworkTypeController.getOverrideNetworkType());
+
+ doReturn(true).when(mServiceState).isUsingCarrierAggregation();
+ doReturn(new int[] {30000}).when(mServiceState).getCellBandwidths();
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+ processAllMessages();
+
+ assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA,
+ mNetworkTypeController.getOverrideNetworkType());
+ }
+
+ @Test
+ public void testEventPhysicalChannelChangeFromLteToLteCaInLteConnectedState() throws Exception {
+ // Remove RRC idle/RRC connected from 5G override
+ mBundle = mContextFixture.getCarrierConfigBundle();
+ mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
+ "connected_mmwave:5G_Plus,connected:5G");
+ broadcastCarrierConfigs();
+
+ // Transition to LTE connected state
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+ new AsyncResult(null, DcController.PHYSICAL_LINK_ACTIVE, null));
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("not_restricted_rrc_con", getCurrentState().getName());
+ assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
+ mNetworkTypeController.getOverrideNetworkType());
+
+ // LTE -> LTE+
+ doReturn(true).when(mServiceState).isUsingCarrierAggregation();
+ doReturn(new int[] {30000}).when(mServiceState).getCellBandwidths();
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+ processAllMessages();
+
+ assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA,
+ mNetworkTypeController.getOverrideNetworkType());
+ }
+
+ @Test
+ public void testEventPhysicalChannelChangeFromLteToLteCaInIdleState() throws Exception {
+ // Remove RRC idle/RRC connected from 5G override
+ mBundle = mContextFixture.getCarrierConfigBundle();
+ mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
+ "connected_mmwave:5G_Plus,connected:5G");
+ broadcastCarrierConfigs();
+
+ // Transition to idle state
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+ new AsyncResult(null, DcController.PHYSICAL_LINK_NOT_ACTIVE, null));
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
+ assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
+ mNetworkTypeController.getOverrideNetworkType());
+
+ // LTE -> LTE+
+ doReturn(true).when(mServiceState).isUsingCarrierAggregation();
+ doReturn(new int[] {30000}).when(mServiceState).getCellBandwidths();
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+ processAllMessages();
+
+ assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA,
+ mNetworkTypeController.getOverrideNetworkType());
+ }
+
+ @Test
public void testEventPhysicalLinkStateChanged() throws Exception {
testTransitionToCurrentStateLteConnected();
doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
new AsyncResult(null, DcController.PHYSICAL_LINK_NOT_ACTIVE, null));
+
processAllMessages();
+
+ assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
+ }
+
+ @Test
+ public void testEventPhysicalLinkStateChangedSupportPhysicalChannelConfig1_6()
+ throws Exception {
+ doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
+ TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+ mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
+ processAllMessages();
+ testTransitionToCurrentStateLteConnectedSupportPhysicalChannelConfig1_6();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ setPhysicalLinkState(false);
+ mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+
+ processAllMessages();
+
assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
}
@@ -837,4 +1081,21 @@
mNetworkTypeController.getOverrideNetworkType());
assertFalse(mNetworkTypeController.is5GHysteresisActive());
}
+
+ private void setPhysicalLinkState(Boolean state) {
+ List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
+ // If PhysicalChannelConfigList is empty, PhysicalLinkState is DcController
+ // .PHYSICAL_LINK_NOT_ACTIVE
+ // If PhysicalChannelConfigList is not empty, PhysicalLinkState is DcController
+ // .PHYSICAL_LINK_ACTIVE
+
+ if (state) {
+ PhysicalChannelConfig physicalChannelConfig = new PhysicalChannelConfig.Builder()
+ .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
+ .setBand(41)
+ .build();
+ lastPhysicalChannelConfigList.add(physicalChannelConfig);
+ }
+ doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 2be24db..54ac7a3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -405,33 +405,33 @@
public void testSetRadioPowerForReason() {
// Radio does not turn on if off for other reason and not emergency call.
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
- assertTrue(sst.getRadioPowerOffReasonsForTest().isEmpty());
+ assertTrue(sst.getRadioPowerOffReasons().isEmpty());
sst.setRadioPowerForReason(false, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
- assertTrue(sst.getRadioPowerOffReasonsForTest().contains(Phone.RADIO_POWER_REASON_THERMAL));
- assertTrue(sst.getRadioPowerOffReasonsForTest().size() == 1);
+ assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
+ assertTrue(sst.getRadioPowerOffReasons().size() == 1);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
sst.setRadioPowerForReason(true, false, false, false, Phone.RADIO_POWER_REASON_USER);
- assertTrue(sst.getRadioPowerOffReasonsForTest().contains(Phone.RADIO_POWER_REASON_THERMAL));
- assertTrue(sst.getRadioPowerOffReasonsForTest().size() == 1);
+ assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
+ assertTrue(sst.getRadioPowerOffReasons().size() == 1);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
// Radio power state reason is removed and radio turns on if turned on for same reason it
// had been turned off for.
sst.setRadioPowerForReason(true, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
- assertTrue(sst.getRadioPowerOffReasonsForTest().isEmpty());
+ assertTrue(sst.getRadioPowerOffReasons().isEmpty());
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
// Turn radio off, then successfully turn radio on for emergency call.
sst.setRadioPowerForReason(false, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
- assertTrue(sst.getRadioPowerOffReasonsForTest().contains(Phone.RADIO_POWER_REASON_THERMAL));
- assertTrue(sst.getRadioPowerOffReasonsForTest().size() == 1);
+ assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
+ assertTrue(sst.getRadioPowerOffReasons().size() == 1);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
sst.setRadioPower(true, true, true, false);
- assertTrue(sst.getRadioPowerOffReasonsForTest().isEmpty());
+ assertTrue(sst.getRadioPowerOffReasons().isEmpty());
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index ce5dc21..c0b8d9a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -2829,6 +2829,7 @@
doReturn(mApnContext).when(apnContextsByType).get(eq(ApnSetting.TYPE_IMS));
doReturn(mApnContext).when(apnContexts).get(eq(ApnSetting.TYPE_IMS_STRING));
doReturn(false).when(mApnContext).isConnectable();
+ doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
doReturn(DctConstants.State.DISCONNECTING).when(mApnContext).getState();
replaceInstance(DcTracker.class, "mApnContextsByType", mDct, apnContextsByType);
replaceInstance(DcTracker.class, "mApnContexts", mDct, apnContexts);
@@ -2850,6 +2851,7 @@
doReturn(DctConstants.State.RETRYING).when(mApnContext).getState();
// Data now is disconnected
doReturn(true).when(mApnContext).isConnectable();
+ doReturn(true).when(mDataEnabledSettings).isDataEnabled(anyInt());
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE,
new AsyncResult(Pair.create(mApnContext, 0), null, null)));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
index 0aa2a4d..7dd65c2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
@@ -32,6 +32,7 @@
import static org.mockito.Mockito.verify;
import android.net.NetworkCapabilities;
+import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.os.AsyncResult;
@@ -42,6 +43,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.ArraySet;
import androidx.test.filters.FlakyTest;
@@ -56,6 +58,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -77,6 +80,9 @@
private String mTestName = "";
+ // List of all requests filed by a test
+ private final ArraySet<NetworkRequest> mAllNetworkRequestSet = new ArraySet<>();
+ // List of requests active in DcTracker
private final ArrayList<NetworkRequest> mNetworkRequestList = new ArrayList<>();
private TelephonyNetworkFactory mTelephonyNetworkFactoryUT;
@@ -155,7 +161,9 @@
"mobile_ia,14,0,2,-1,true", "mobile_emergency,15,0,2,-1,true"});
doAnswer(invocation -> {
- mNetworkRequestList.add((NetworkRequest) invocation.getArguments()[0]);
+ final NetworkRequest req = (NetworkRequest) invocation.getArguments()[0];
+ mNetworkRequestList.add(req);
+ mAllNetworkRequestSet.add(req);
return null;
}).when(mDcTracker).requestNetwork(any(), anyInt(), any());
@@ -174,8 +182,36 @@
replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mPhoneSwitcher);
mTelephonyNetworkFactoryUT = new TelephonyNetworkFactory(Looper.myLooper(), mPhone);
- verify(mConnectivityManager).registerNetworkProvider(any());
+ final ArgumentCaptor<NetworkProvider> providerCaptor =
+ ArgumentCaptor.forClass(NetworkProvider.class);
+ verify(mConnectivityManager).registerNetworkProvider(providerCaptor.capture());
+ // For NetworkFactory to function as expected, the provider ID must be set to some
+ // number > 0.
+ providerCaptor.getValue().setProviderId(1);
verify(mPhoneSwitcher).registerForActivePhoneSwitch(any(), anyInt(), any());
+
+ // Simulate the behavior of the system server. When offerNetwork is called, it will
+ // update the factory about all requests that pass the registered filter, by calling
+ // NetworkProvider#onNetworkNeeded or onNetworkUnneeded.
+ // Note that this simulation is a little bit incomplete, as the system server will
+ // *update* only for those requests for which the status has changed, but this
+ // simulation will send REQUEST_NETWORK or CANCEL_REQUEST for all registered requests.
+ // At this time it makes no difference in this test.
+ // Also, this test reads from mAllNetworkRequestSet, which is not really the list of
+ // requests sent to the system server as the test doesn't instrument that. Instead, it's
+ // the list of requests ever sent to the factory. This also makes no difference in this
+ // test at this time.
+ doAnswer(invocation -> {
+ final NetworkCapabilities capabilitiesFilter =
+ mTelephonyNetworkFactoryUT.makeNetworkFilter(
+ mSubscriptionController.getSubIdUsingPhoneId(0));
+ for (final NetworkRequest request : mAllNetworkRequestSet) {
+ final int message = request.canBeSatisfiedBy(capabilitiesFilter)
+ ? CMD_REQUEST_NETWORK : CMD_CANCEL_REQUEST;
+ mTelephonyNetworkFactoryUT.obtainMessage(message, 0, 0, request).sendToTarget();
+ }
+ return null;
+ }).when(mConnectivityManager).offerNetwork(anyInt(), any(), any(), any());
}
/**