Terminate selection after CS call failure
For PTCRB, terminate selection if call fails with a specific cause.
In 34.123-1 6.1.2.6_FDD II, UE has to keep camping on 3G cell
after call failure and has to do the inter-frequency cell reselection.
Bug: 341055741
Test: atest EmergencyCallDomainSelectorTest
Change-Id: I12fda927fc2b41c1ccf69b5de4eca84c4ae0cd37
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 099def8..897f226 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -149,6 +149,9 @@
ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL);
+ private static List<Integer> sDisconnectCauseForTerminatation = List.of(
+ SERVICE_OPTION_NOT_AVAILABLE);
+
private static final LocalLog sLocalLog = new LocalLog(LOG_SIZE);
private static List<String> sSimReadyAllowList;
@@ -229,6 +232,7 @@
private boolean mTryEsFallback;
private boolean mIsWaitingForDataDisconnection;
private boolean mSwitchRatPreferenceWithLocalNotRegistered;
+ private boolean mTerminateAfterCsFailure;
private int mModemCount;
/** Indicates whether this instance is deactivated. */
@@ -361,6 +365,8 @@
return;
}
+ checkAndSetTerminateAfterCsFailure(result);
+
if (result.getRegState() != REGISTRATION_STATE_HOME
&& result.getRegState() != REGISTRATION_STATE_ROAMING) {
if (maybeRedialOnTheOtherSlotInNormalService(result)) {
@@ -437,6 +443,8 @@
return;
}
+ mTerminateAfterCsFailure = false;
+
if (mTryCsWhenPsFails) {
mTryCsWhenPsFails = false;
// Initial state was CSFB available and dial PS failed.
@@ -883,6 +891,7 @@
if (mPsNetworkType == EUTRAN) {
onWwanNetworkTypeSelected(mPsNetworkType);
} else if (mCsNetworkType != UNKNOWN) {
+ checkAndSetTerminateAfterCsFailure(mLastRegResult);
onWwanNetworkTypeSelected(mCsNetworkType);
} else {
requestScan(true);
@@ -1717,7 +1726,6 @@
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())) {
@@ -1725,6 +1733,13 @@
terminateSelection(DisconnectCause.NOT_VALID);
return true;
}
+ } else if (reasonInfo == null
+ && sDisconnectCauseForTerminatation.contains(cause)
+ && mTerminateAfterCsFailure) {
+ // b/341055741
+ logi("maybeTerminateSelection terminate after CS failure");
+ terminateSelection(DisconnectCause.NOT_VALID);
+ return true;
}
return false;
}
@@ -1925,6 +1940,17 @@
return ret;
}
+ private void checkAndSetTerminateAfterCsFailure(EmergencyRegistrationResult result) {
+ if (result == null) return;
+ String mcc = result.getMcc();
+ int accessNetwork = result.getAccessNetwork();
+ if (!TextUtils.isEmpty(mcc) && mcc.startsWith("00") // test network
+ && (accessNetwork == UTRAN || accessNetwork == GERAN)) {
+ // b/341055741
+ mTerminateAfterCsFailure = true;
+ }
+ }
+
@Override
protected void logi(String msg) {
super.logi(msg);
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 38c9677..13ff5ac 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -3969,6 +3969,155 @@
assertFalse(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
}
+ @Test
+ public void testNotTerminateSelectionAfterCsFailure() throws Exception {
+ mResultConsumer = null;
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ // mcc is identified but it doesn't start with 00.
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(
+ UTRAN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "999", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+ SelectionAttributes.Builder builder =
+ new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+ .setAddress(TEST_URI)
+ .setCsDisconnectCause(SERVICE_OPTION_NOT_AVAILABLE)
+ .setEmergency(true)
+ .setEmergencyRegistrationResult(regResult);
+ attr = builder.build();
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ // Verify reselection.
+ verify(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+ any(), anyInt(), anyBoolean(), any(), any());
+ verify(mTransportSelectorCallback, never())
+ .onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
+ }
+
+ @Test
+ public void testTerminateSelectionAfterCsFailure() throws Exception {
+ mResultConsumer = null;
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ // mcc is identified and it starts with 00.
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(
+ UTRAN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "003", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+ SelectionAttributes.Builder builder =
+ new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+ .setAddress(TEST_URI)
+ .setCsDisconnectCause(SERVICE_OPTION_NOT_AVAILABLE)
+ .setEmergency(true)
+ .setEmergencyRegistrationResult(regResult);
+ attr = builder.build();
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ // Verify selection termination.
+ verify(mWwanSelectorCallback, never()).onRequestEmergencyNetworkScan(
+ any(), anyInt(), anyBoolean(), any(), any());
+ verify(mTransportSelectorCallback)
+ .onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
+ }
+
+ @Test
+ public void testTerminateSelectionAfterCsFailureAfterScan() throws Exception {
+ mResultConsumer = null;
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegistrationResult regResult = getEmergencyRegResult(
+ UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mTransportSelectorCallback, times(1)).onWwanSelected(any());
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), anyBoolean(), any(), any());
+ assertNotNull(mResultConsumer);
+
+ // mcc is not identified.
+ regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_UNKNOWN,
+ 0, false, false, 0, 0, "", "");
+ mResultConsumer.accept(regResult);
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+ SelectionAttributes.Builder builder =
+ new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+ .setAddress(TEST_URI)
+ .setCsDisconnectCause(SERVICE_OPTION_NOT_AVAILABLE)
+ .setEmergency(true)
+ .setEmergencyRegistrationResult(regResult);
+ attr = builder.build();
+ mResultConsumer = null;
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ // Verify reselection.
+ verify(mWwanSelectorCallback, times(2)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), anyBoolean(), any(), any());
+ assertNotNull(mResultConsumer);
+
+ // mcc is identified but it doesn't start with 00.
+ regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_UNKNOWN,
+ 0, false, false, 0, 0, "999", "");
+ mResultConsumer.accept(regResult);
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(2)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+ mResultConsumer = null;
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ // Verify reselection.
+ verify(mWwanSelectorCallback, times(3)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), anyBoolean(), any(), any());
+ assertNotNull(mResultConsumer);
+
+ // mcc is identified and it starts with 00.
+ regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_UNKNOWN,
+ 0, false, false, 0, 0, "003", "");
+ mResultConsumer.accept(regResult);
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(3)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ // Verify selection termination.
+ verify(mWwanSelectorCallback, times(3)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), anyBoolean(), any(), any());
+ verify(mTransportSelectorCallback)
+ .onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
+ }
+
private void setupForScanListTest(PersistableBundle bundle) throws Exception {
setupForScanListTest(bundle, false);
}