Merge "Create a single instance of CarrierPrivilegesTracker"
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index dd68591..8fdd16b 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -4051,13 +4051,19 @@
}
@Override
- public void setSignalStrengthReportingCriteria(
- int signalStrengthMeasure, int[] thresholds, int ran, boolean isEnabled) {
+ public void setSignalStrengthReportingCriteria(int signalStrengthMeasure,
+ int[] systemThresholds, int ran, boolean isEnabledForSystem) {
int[] consolidatedThresholds = mSST.getConsolidatedSignalThresholds(
ran,
signalStrengthMeasure,
- mSST.shouldHonorSystemThresholds() ? thresholds : new int[]{},
+ isEnabledForSystem && mSST.shouldHonorSystemThresholds() ? systemThresholds
+ : new int[]{},
REPORTING_HYSTERESIS_DB);
+ boolean isEnabledForAppRequest = mSST.shouldEnableSignalThresholdForAppRequest(
+ ran,
+ signalStrengthMeasure,
+ getSubId(),
+ isDeviceIdle());
mCi.setSignalStrengthReportingCriteria(
new SignalThresholdInfo.Builder()
.setRadioAccessNetworkType(ran)
@@ -4065,7 +4071,7 @@
.setHysteresisMs(REPORTING_HYSTERESIS_MILLIS)
.setHysteresisDb(REPORTING_HYSTERESIS_DB)
.setThresholds(consolidatedThresholds, true /*isSystem*/)
- .setIsEnabled(isEnabled)
+ .setIsEnabled(isEnabledForSystem || isEnabledForAppRequest)
.build(),
ran, null);
}
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 f511bae..9e07362 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
@@ -1842,6 +1843,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..241d510 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -581,19 +581,17 @@
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+ final String action = intent.getAction();
+ if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
int phoneId = intent.getExtras().getInt(CarrierConfigManager.EXTRA_SLOT_INDEX);
// Ignore the carrier config changed if the phoneId is not matched.
if (phoneId == mPhone.getPhoneId()) {
sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
}
- return;
- }
-
- if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
+ } else if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
// Update emergency string or operator name, polling service state.
pollState();
- } else if (intent.getAction().equals(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) {
+ } else if (action.equals(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) {
String lastKnownNetworkCountry = intent.getStringExtra(
TelephonyManager.EXTRA_LAST_KNOWN_NETWORK_COUNTRY);
if (!mLastKnownNetworkCountry.equals(lastKnownNetworkCountry)) {
@@ -1083,8 +1081,7 @@
/**
* @return the current reasons for which the radio is off.
*/
- @VisibleForTesting
- public Set<Integer> getRadioPowerOffReasonsForTest() {
+ public Set<Integer> getRadioPowerOffReasons() {
return sRadioPowerOffReasons;
}
@@ -1716,7 +1713,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 +1726,7 @@
hasChanged |= RatRatcheter
.updateBandwidths(getBandwidthsFromConfigs(list), mSS);
+ mPhone.notifyPhysicalChannelConfig(list);
// Notify NR frequency, NR connection status or bandwidths changed.
if (hasChanged) {
mPhone.notifyServiceStateChanged(mSS);
@@ -6243,8 +6240,7 @@
continue;
}
for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
- if (ran == info.getRadioAccessNetworkType()
- && measurement == info.getSignalMeasurementType()) {
+ if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)) {
for (int appThreshold : info.getThresholds()) {
target.add(appThreshold);
}
@@ -6275,12 +6271,44 @@
sendMessage(obtainMessage(EVENT_ON_DEVICE_IDLE_STATE_CHANGED, isDeviceIdle));
}
+ boolean shouldEnableSignalThresholdForAppRequest(
+ @AccessNetworkConstants.RadioAccessNetworkType int ran,
+ @SignalThresholdInfo.SignalMeasurementType int measurement,
+ int subId,
+ boolean isDeviceIdle) {
+ for (SignalRequestRecord record : mSignalRequestRecords) {
+ if (subId != record.mSubId) {
+ continue;
+ }
+ for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
+ if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)
+ && (!isDeviceIdle || isSignalReportRequestedWhileIdle(record.mRequest))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean isRanAndSignalMeasurementTypeMatch(
+ @AccessNetworkConstants.RadioAccessNetworkType int ran,
+ @SignalThresholdInfo.SignalMeasurementType int measurement,
+ SignalThresholdInfo info) {
+ return ran == info.getRadioAccessNetworkType()
+ && measurement == info.getSignalMeasurementType();
+ }
+
+ private static boolean isSignalReportRequestedWhileIdle(SignalStrengthUpdateRequest request) {
+ return request.isSystemThresholdReportingRequestedWhileIdle()
+ || request.isReportingRequestedWhileIdle();
+ }
+
private class SignalRequestRecord implements IBinder.DeathRecipient {
final int mSubId; // subId the request originally applied to
final int mCallingUid;
final SignalStrengthUpdateRequest mRequest;
- SignalRequestRecord(int subId, int uid, SignalStrengthUpdateRequest request) {
+ SignalRequestRecord(int subId, int uid, @NonNull SignalStrengthUpdateRequest request) {
this.mCallingUid = uid;
this.mSubId = subId;
this.mRequest = request;
@@ -6295,8 +6323,7 @@
private void updateAlwaysReportSignalStrength() {
final int curSubId = mPhone.getSubId();
boolean alwaysReport = mSignalRequestRecords.stream().anyMatch(
- srr -> srr.mSubId == curSubId && (srr.mRequest.isReportingRequestedWhileIdle()
- || srr.mRequest.isSystemThresholdReportingRequestedWhileIdle()));
+ srr -> srr.mSubId == curSubId && isSignalReportRequestedWhileIdle(srr.mRequest));
// TODO(b/177924721): TM#setAlwaysReportSignalStrength will be removed and we will not
// worry about unset flag which was set by other client.
diff --git a/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java b/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java
index 0ded77e..6d6d0ea 100644
--- a/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java
+++ b/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java
@@ -33,49 +33,52 @@
/** Ef data from carrier config. */
public final class CarrierConfigEfData implements EfData {
private static final String TAG = "CarrierConfigEfData";
- private final PersistableBundle mConfig;
+
+ private final String mSpn;
+ private final int mSpnDisplayCondition;
+ private final String[] mSpdi;
+ private final String[] mEhplmn;
+ private final String[] mPnn;
+ private final String[] mOpl;
public CarrierConfigEfData(@NonNull PersistableBundle config) {
- mConfig = config;
+ // Save only the relevant keys of the config.
+ mSpn = config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
+ mSpnDisplayCondition = config.getInt(
+ CarrierConfigManager.KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT,
+ IccRecords.INVALID_CARRIER_NAME_DISPLAY_CONDITION_BITMASK);
+ mSpdi = config.getStringArray(CarrierConfigManager.KEY_SPDI_OVERRIDE_STRING_ARRAY);
+ mEhplmn = config.getStringArray(CarrierConfigManager.KEY_EHPLMN_OVERRIDE_STRING_ARRAY);
+ mPnn = config.getStringArray(CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY);
+ mOpl = config.getStringArray(CarrierConfigManager.KEY_OPL_OVERRIDE_STRING_ARRAY);
}
@Override
public String getServiceProviderName() {
- String spn = mConfig.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
- if (TextUtils.isEmpty(spn)) return null;
- return spn;
+ return TextUtils.isEmpty(mSpn) ? null : mSpn;
}
@Override
public int getServiceProviderNameDisplayCondition(boolean isRoaming) {
- int condition = mConfig.getInt(
- CarrierConfigManager.KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT,
- IccRecords.INVALID_CARRIER_NAME_DISPLAY_CONDITION_BITMASK);
- return condition;
+ return mSpnDisplayCondition;
}
@Override
public List<String> getServiceProviderDisplayInformation() {
- String[] spdi = mConfig.getStringArray(
- CarrierConfigManager.KEY_SPDI_OVERRIDE_STRING_ARRAY);
- return spdi != null ? Arrays.asList(spdi) : null;
+ return mSpdi != null ? Arrays.asList(mSpdi) : null;
}
@Override
public List<String> getEhplmnList() {
- String[] ehplmn = mConfig.getStringArray(
- CarrierConfigManager.KEY_EHPLMN_OVERRIDE_STRING_ARRAY);
- return ehplmn != null ? Arrays.asList(ehplmn) : null;
+ return mEhplmn != null ? Arrays.asList(mEhplmn) : null;
}
@Override
public List<PlmnNetworkName> getPlmnNetworkNameList() {
- String[] pnn = mConfig.getStringArray(
- CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY);
List<PlmnNetworkName> pnnList = null;
- if (pnn != null) {
- pnnList = new ArrayList<>(pnn.length);
- for (String pnnStr : pnn) {
+ if (mPnn != null) {
+ pnnList = new ArrayList<>(mPnn.length);
+ for (String pnnStr : mPnn) {
try {
String[] names = pnnStr.split("\\s*,\\s*");
String alphal = names[0];
@@ -91,13 +94,10 @@
@Override
public List<OperatorPlmnInfo> getOperatorPlmnList() {
- // OPL
- String[] opl = mConfig.getStringArray(
- CarrierConfigManager.KEY_OPL_OVERRIDE_STRING_ARRAY);
List<OperatorPlmnInfo> oplList = null;
- if (opl != null) {
- oplList = new ArrayList<>(opl.length);
- for (String oplStr : opl) {
+ if (mOpl != null) {
+ oplList = new ArrayList<>(mOpl.length);
+ for (String oplStr : mOpl) {
try {
String[] info = oplStr.split("\\s*,\\s*");
oplList.add(new OperatorPlmnInfo(
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 7b1edd7..0551086 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -529,7 +529,10 @@
return mCid;
}
- ApnSetting getApnSetting() {
+ /**
+ * @return DataConnection's ApnSetting.
+ */
+ public ApnSetting getApnSetting() {
return mApnSetting;
}
@@ -2421,6 +2424,7 @@
mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L,
mApnSetting != null
? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false);
+ mDataCallSessionStats.onDataCallDisconnected(mDcFailCause);
if (mHandoverState == HANDOVER_STATE_BEING_TRANSFERRED) {
// This is from source data connection to set itself's state
setHandoverState(HANDOVER_STATE_COMPLETED);
@@ -2916,7 +2920,6 @@
TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
mCid, mApnSetting.getApnTypeBitmask(), RilDataCall.State.DISCONNECTED);
- mDataCallSessionStats.onDataCallDisconnected();
mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener);
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/metrics/DataCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
index 3b4fc69..da350c3 100644
--- a/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
@@ -22,8 +22,10 @@
import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION__IP_TYPE__APN_PROTOCOL_IPV4;
+import android.annotation.Nullable;
import android.os.SystemClock;
import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.NetworkType;
import android.telephony.DataFailCause;
import android.telephony.ServiceState;
@@ -50,8 +52,7 @@
private final Phone mPhone;
private long mStartTime;
- private boolean mOnRatChangedCalledBeforeSetup = false;
- DataCallSession mOngoingDataCall;
+ @Nullable private DataCallSession mDataCallSession;
private final PersistAtomsStorage mAtomsStorage =
PhoneFactory.getMetricsCollector().getAtomsStorage();
@@ -64,22 +65,8 @@
/** Creates a new ongoing atom when data call is set up. */
public synchronized void onSetupDataCall(@ApnType int apnTypeBitMask) {
- if (!mOnRatChangedCalledBeforeSetup) {
- // there shouldn't be an ongoing data call here, if that's the case, it means that
- // deactivateDataCall hasn't been processed properly, so we save the previous atom here
- // and move on to create a new atom.
- if (mOngoingDataCall != null) {
- mOngoingDataCall.failureCause = DataFailCause.UNKNOWN;
- onDataCallDisconnected();
- }
- mOngoingDataCall = getDefaultProto(apnTypeBitMask);
- mStartTime = getTimeMillis();
- } else {
- // if onRatChanged was called before onSetupDataCall, the atom is already initialized
- // but apnTypeBitMask is initialized to 0, so we need to update it
- mOngoingDataCall.apnTypeBitmask = apnTypeBitMask;
- }
- mOnRatChangedCalledBeforeSetup = false;
+ mDataCallSession = getDefaultProto(apnTypeBitMask);
+ mStartTime = getTimeMillis();
}
/**
@@ -92,89 +79,90 @@
* @param failureCause failure cause as per android.telephony.DataFailCause
*/
public synchronized void onSetupDataCallResponse(
- DataCallResponse response,
+ @Nullable DataCallResponse response,
@RilRadioTechnology int radioTechnology,
@ApnType int apnTypeBitmask,
@ProtocolType int protocol,
- int failureCause) {
- // there should've been another call to initiate the atom,
+ @DataFailureCause int failureCause) {
+ // there should've been a call to onSetupDataCall to initiate the atom,
// so this method is being called out of order -> no metric will be logged
- if (mOngoingDataCall == null) {
+ if (mDataCallSession == null) {
loge("onSetupDataCallResponse: no DataCallSession atom has been initiated.");
return;
}
- mOngoingDataCall.ratAtEnd = ServiceState.rilRadioTechnologyToNetworkType(radioTechnology);
+ mDataCallSession.ratAtEnd = ServiceState.rilRadioTechnologyToNetworkType(radioTechnology);
// only set if apn hasn't been set during setup
- if (mOngoingDataCall.apnTypeBitmask == 0) {
- mOngoingDataCall.apnTypeBitmask = apnTypeBitmask;
+ if (mDataCallSession.apnTypeBitmask == 0) {
+ mDataCallSession.apnTypeBitmask = apnTypeBitmask;
}
- mOngoingDataCall.ipType = protocol;
- mOngoingDataCall.failureCause = failureCause;
+ mDataCallSession.ipType = protocol;
+ mDataCallSession.failureCause = failureCause;
if (response != null) {
- mOngoingDataCall.suggestedRetryMillis =
+ mDataCallSession.suggestedRetryMillis =
(int) Math.min(response.getRetryDurationMillis(), Integer.MAX_VALUE);
+ // If setup has failed, then store the atom
if (failureCause != DataFailCause.NONE) {
- mOngoingDataCall.failureCause = failureCause;
- mOngoingDataCall.setupFailed = true;
- // set dataCall as inactive
- mOngoingDataCall.ongoing = false;
- // store it only if setup has failed
- mAtomsStorage.addDataCallSession(mOngoingDataCall);
- mOngoingDataCall = null;
+ mDataCallSession.failureCause = failureCause;
+ mDataCallSession.setupFailed = true;
+ mDataCallSession.ongoing = false;
+ mAtomsStorage.addDataCallSession(mDataCallSession);
+ mDataCallSession = null;
}
}
}
/**
- * Updates the ongoing dataCall's atom when data call is deactivated.
+ * Updates the dataCall atom when data call is deactivated.
*
* @param reason Deactivate reason
*/
public synchronized void setDeactivateDataCallReason(@DeactivateDataReason int reason) {
// there should've been another call to initiate the atom,
// so this method is being called out of order -> no metric will be logged
- if (mOngoingDataCall == null) {
- loge("onSetupDataCallResponse: no DataCallSession atom has been initiated.");
+ if (mDataCallSession == null) {
+ loge("setDeactivateDataCallReason: no DataCallSession atom has been initiated.");
return;
}
switch (reason) {
case DataService.REQUEST_REASON_NORMAL:
- mOngoingDataCall.deactivateReason =
+ mDataCallSession.deactivateReason =
DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_NORMAL;
break;
case DataService.REQUEST_REASON_SHUTDOWN:
- mOngoingDataCall.deactivateReason =
+ mDataCallSession.deactivateReason =
DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_RADIO_OFF;
break;
case DataService.REQUEST_REASON_HANDOVER:
- mOngoingDataCall.deactivateReason =
+ mDataCallSession.deactivateReason =
DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_HANDOVER;
break;
default:
- mOngoingDataCall.deactivateReason =
+ mDataCallSession.deactivateReason =
DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_UNKNOWN;
break;
}
-
- mOngoingDataCall.oosAtEnd = getIsOos();
}
- /** Stores the atom when DataConnection reaches DISCONNECTED state. */
- public synchronized void onDataCallDisconnected() {
+ /** Stores the atom when DataConnection reaches DISCONNECTED state.
+ * @param failureCause failure cause as per android.telephony.DataFailCause
+ **/
+ public synchronized void onDataCallDisconnected(@DataFailureCause int failureCause) {
// there should've been another call to initiate the atom,
// so this method is being called out of order -> no atom will be saved
- if (mOngoingDataCall == null) {
- loge("onSetupDataCallResponse: no DataCallSession atom has been initiated.");
+ if (mDataCallSession == null) {
+ loge("onDataCallDisconnected: no DataCallSession atom has been initiated.");
return;
}
- mOngoingDataCall.ongoing = false;
- mOngoingDataCall.durationMinutes = convertMillisToMinutes(getTimeMillis() - mStartTime);
+ mDataCallSession.failureCause = failureCause;
+ mDataCallSession.oosAtEnd = getIsOos();
+ mDataCallSession.ongoing = false;
+ mDataCallSession.durationMinutes = convertMillisToMinutes(getTimeMillis() - mStartTime);
// store for the data call list event, after DataCall is disconnected and entered into
// inactive mode
- mAtomsStorage.addDataCallSession(mOngoingDataCall);
- mOngoingDataCall = null;
+ mAtomsStorage.addDataCallSession(mDataCallSession);
+ mDataCallSession = null;
}
/**
@@ -184,24 +172,19 @@
* registration state change.
*/
public synchronized void onDrsOrRatChanged(@RilRadioTechnology int radioTechnology) {
- @NetworkType int rat = ServiceState.rilRadioTechnologyToNetworkType(radioTechnology);
- // if no data call is initiated, or we have a new data call while the last one has ended
- // because onRatChanged might be called before onSetupDataCall
- if (mOngoingDataCall == null) {
- mOngoingDataCall = getDefaultProto(0);
- mOngoingDataCall.ratAtEnd = rat;
- mStartTime = getTimeMillis();
- mOnRatChangedCalledBeforeSetup = true;
+ @NetworkType int currentRat =
+ ServiceState.rilRadioTechnologyToNetworkType(radioTechnology);
+ if (mDataCallSession != null
+ && currentRat != TelephonyManager.NETWORK_TYPE_UNKNOWN
+ && mDataCallSession.ratAtEnd != currentRat) {
+ mDataCallSession.ratSwitchCount++;
+ mDataCallSession.ratAtEnd = currentRat;
+ mDataCallSession.bandAtEnd = ServiceStateStats.getBand(mPhone, currentRat);
}
- if (rat != TelephonyManager.NETWORK_TYPE_UNKNOWN && mOngoingDataCall.ratAtEnd != rat) {
- mOngoingDataCall.ratSwitchCount++;
- mOngoingDataCall.ratAtEnd = rat;
- }
- mOngoingDataCall.bandAtEnd = ServiceStateStats.getBand(mPhone, rat);
}
private static long convertMillisToMinutes(long millis) {
- return Math.round(millis / 60000);
+ return Math.round(millis / 60000.0);
}
/** Creates a proto for a normal {@code DataCallSession} with default values. */
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 067454f..54ac7a3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -269,11 +269,6 @@
waitUntilReady();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
- mContext.sendBroadcast(intent);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-
// Override SPN related resource
mContextFixture.putResource(
com.android.internal.R.string.lockscreen_carrier_default,
@@ -334,6 +329,12 @@
15, /* SIGNAL_STRENGTH_GOOD */
30 /* SIGNAL_STRENGTH_GREAT */
});
+
+ Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+ intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
+ mContext.sendBroadcast(intent);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
logd("ServiceStateTrackerTest -Setup!");
}
@@ -404,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());
}
/**