Merge "Retry selection when receiving specific IMS reason codes" into 24D1-dev
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 099bf10..1161e50 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -42,6 +42,7 @@
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_SCAN_TIMER_SEC_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_IMS_REASONINFO_CODE_TO_RETRY_EMERGENCY_INT_ARRAY;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
@@ -98,6 +99,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.function.IntFunction;
+import java.util.stream.Collectors;
/**
* Selects the domain for emergency calling.
@@ -117,6 +119,12 @@
private static final int NOT_SUPPORTED = -1;
+ private static List<Integer> sDefaultRetryReasonCodes = List.of(
+ ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED,
+ ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR,
+ ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
+ ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL);
+
private static final LocalLog sLocalLog = new LocalLog(LOG_SIZE);
private static List<String> sSimReadyAllowList;
@@ -185,6 +193,7 @@
private boolean mRequiresVoLteEnabled;
private boolean mLtePreferredAfterNrFailure;
private boolean mScanLimitedOnlyAfterVolteFailure;
+ private List<Integer> mRetryReasonCodes;
// Members for states
private boolean mIsMonitoringConnectivity;
@@ -347,17 +356,17 @@
return;
}
- if (maybeTerminateSelection(cause)) {
- logi("reselectDomain terminate selection");
- return;
- }
-
if (mCrossStackTimerExpired) {
logi("reselectDomain cross stack timer expired");
terminateSelectionForCrossSimRedialing(false);
return;
}
+ if (maybeTerminateSelection(cause)) {
+ logi("reselectDomain terminate selection");
+ return;
+ }
+
if (mTryCsWhenPsFails) {
mTryCsWhenPsFails = false;
// Initial state was CSFB available and dial PS failed.
@@ -550,6 +559,7 @@
KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL,
KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL,
KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL,
+ KEY_IMS_REASONINFO_CODE_TO_RETRY_EMERGENCY_INT_ARRAY,
KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY);
if (b == null) {
b = CarrierConfigManager.getDefaultConfig();
@@ -583,6 +593,8 @@
mScanLimitedOnlyAfterVolteFailure = b.getBoolean(
KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL);
String[] numbers = b.getStringArray(KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY);
+ int[] imsReasonCodes =
+ b.getIntArray(KEY_IMS_REASONINFO_CODE_TO_RETRY_EMERGENCY_INT_ARRAY);
if (mImsRatsConfig == null) mImsRatsConfig = new int[0];
if (mCsRatsConfig == null) mCsRatsConfig = new int[0];
@@ -591,6 +603,10 @@
if (mDomainPreference == null) mDomainPreference = new int[0];
if (mDomainPreferenceRoam == null) mDomainPreferenceRoam = new int[0];
if (numbers == null) numbers = new String[0];
+ if (imsReasonCodes == null) imsReasonCodes = new int[0];
+
+ mRetryReasonCodes = Arrays.stream(imsReasonCodes).boxed().collect(Collectors.toList());
+ mRetryReasonCodes.addAll(sDefaultRetryReasonCodes);
logi("updateCarrierConfiguration "
+ "imsRats=" + arrayToString(mImsRatsConfig,
@@ -618,6 +634,7 @@
+ ", requiresVoLteEnabled=" + mRequiresVoLteEnabled
+ ", ltePreferredAfterNr=" + mLtePreferredAfterNrFailure
+ ", scanLimitedOnly=" + mScanLimitedOnlyAfterVolteFailure
+ + ", retryReasonCodes=" + mRetryReasonCodes
+ ", cdmaPreferredNumbers=" + arrayToString(numbers));
mCdmaPreferredNumbers = Arrays.asList(numbers);
@@ -1328,7 +1345,6 @@
EmergencyRegistrationResult regResult = mLastRegResult;
if (regResult != null) {
if (regResult.getRegState() == REGISTRATION_STATE_HOME) return false;
- if (regResult.getRegState() == REGISTRATION_STATE_ROAMING) return true;
String iso = regResult.getCountryIso();
if (!TextUtils.isEmpty(iso)) netIso = iso;
@@ -1518,30 +1534,38 @@
private void terminateSelectionPermanentlyForSlot() {
logi("terminateSelectionPermanentlyForSlot");
- terminateSelection(true);
+ terminateSelection(DisconnectCause.EMERGENCY_PERM_FAILURE);
}
private void terminateSelectionForCrossSimRedialing(boolean permanent) {
logi("terminateSelectionForCrossSimRedialing perm=" + permanent);
- terminateSelection(permanent);
+ terminateSelection(permanent ? DisconnectCause.EMERGENCY_PERM_FAILURE
+ : DisconnectCause.EMERGENCY_TEMP_FAILURE);
}
- private void terminateSelection(boolean permanent) {
- mTransportSelectorCallback.onSelectionTerminated(permanent
- ? DisconnectCause.EMERGENCY_PERM_FAILURE
- : DisconnectCause.EMERGENCY_TEMP_FAILURE);
+ private void terminateSelection(int cause) {
+ mTransportSelectorCallback.onSelectionTerminated(cause);
}
private boolean maybeTerminateSelection(int cause) {
switch (cause) {
case NO_VALID_SIM:
// The disconnect cause saved in DomainSelectionConnection shall be used.
- mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.NOT_VALID);
+ terminateSelection(DisconnectCause.NOT_VALID);
return true;
default:
break;
}
+ // If CS call fails, retry always. Otherwise, check the reason code.
+ ImsReasonInfo reasonInfo = mSelectionAttributes.getPsDisconnectCause();
+ if (mRetryReasonCodes != null && reasonInfo != null) {
+ if (!mRetryReasonCodes.contains(reasonInfo.getCode())) {
+ // The disconnect cause saved in DomainSelectionConnection shall be used.
+ terminateSelection(DisconnectCause.NOT_VALID);
+ return true;
+ }
+ }
return false;
}
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 7aa52c5..ef2b055 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -39,6 +39,7 @@
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_SCAN_TIMER_SEC_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_IMS_REASONINFO_CODE_TO_RETRY_EMERGENCY_INT_ARRAY;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
@@ -1932,17 +1933,43 @@
}
@Test
- public void testFullServiceInRoaming() throws Exception {
+ public void testFullServiceInDomesticRoaming() throws Exception {
PersistableBundle bundle = getDefaultPersistableBundle();
bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, SCAN_TYPE_FULL_SERVICE);
when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+ doReturn("us").when(mTelephonyManager).getSimCountryIso();
createSelector(SLOT_0_SUB_ID);
unsolBarringInfoChanged(true);
EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
REGISTRATION_STATE_ROAMING,
- 0, true, false, 0, 0, "", "");
+ 0, true, false, 0, 0, "", "", "us");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+ any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE),
+ anyBoolean(), any(), any());
+ }
+
+ @Test
+ public void testFullServiceInInterNationalRoaming() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, SCAN_TYPE_FULL_SERVICE);
+ when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+ doReturn("us").when(mTelephonyManager).getSimCountryIso();
+
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(true);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+ REGISTRATION_STATE_ROAMING,
+ 0, true, false, 0, 0, "", "", "zz");
SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
processAllMessages();
@@ -3240,6 +3267,162 @@
.onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
}
+ @Test
+ public void testReceiveSipErrorThenTerminateSelection() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+ REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsService();
+
+ verifyPsDialed();
+
+ attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, false, regResult,
+ new ImsReasonInfo(ImsReasonInfo.CODE_SIP_FORBIDDEN, 0, null));
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verify(mTransportSelectorCallback)
+ .onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
+ }
+
+ @Test
+ public void testReceiveSipErrorThenNotTerminateSelection() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putIntArray(KEY_IMS_REASONINFO_CODE_TO_RETRY_EMERGENCY_INT_ARRAY,
+ new int[] { ImsReasonInfo.CODE_SIP_FORBIDDEN });
+ when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+ REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsService();
+
+ verifyPsDialed();
+
+ attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, false, regResult,
+ new ImsReasonInfo(ImsReasonInfo.CODE_SIP_FORBIDDEN, 0, null));
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verifyCsDialed();
+ }
+
+ @Test
+ public void testRetryWithCodeLocalCallCsRetryRequired() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+ REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsService();
+
+ verifyPsDialed();
+
+ attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, false, regResult,
+ new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED, 0, null));
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verifyCsDialed();
+ }
+
+ @Test
+ public void testRetryWithCodeLocalNotRegistered() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+ REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsService();
+
+ verifyPsDialed();
+
+ attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, false, regResult,
+ new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, 0, null));
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verifyCsDialed();
+ }
+
+ @Test
+ public void testRetryWithCodeSipAlternateEemergencyCall() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+ REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsService();
+
+ verifyPsDialed();
+
+ attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, false, regResult,
+ new ImsReasonInfo(ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null));
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verifyCsDialed();
+ }
+
+ @Test
+ public void testRetryWithCodeLocalInternalError() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+ REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsService();
+
+ verifyPsDialed();
+
+ attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, false, regResult,
+ new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR, 0, null));
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verifyCsDialed();
+ }
+
private void setupForScanListTest(PersistableBundle bundle) throws Exception {
setupForScanListTest(bundle, false);
}