Delay handover tear down due to policy for call
When a handover is not allowed due to handover policy, delay the tear down until the call ends.
Fix: 270895912
Test: basic voice call + data browsing
Test: daily test b/299355154
Change-Id: I104140d448a0c56f50ab7b06adbbca9a3e4d08ee
diff --git a/src/java/com/android/internal/telephony/data/DataEvaluation.java b/src/java/com/android/internal/telephony/data/DataEvaluation.java
index eaaf0a5..310f72a 100644
--- a/src/java/com/android/internal/telephony/data/DataEvaluation.java
+++ b/src/java/com/android/internal/telephony/data/DataEvaluation.java
@@ -145,13 +145,18 @@
}
/**
- * Check if only one disallowed reason prevent data connection.
+ * Check if only the given reasons present in the disallowed reasons if there are any.
*
- * @param reason The given reason to check
- * @return {@code true} if the given reason is the only one that prevents data connection
+ * @param reasons The given reasons to check
+ * @return {@code true} if the disallowed reasons contain no disallowed reasons other than the
+ * given reasons.
*/
- public boolean containsOnly(DataDisallowedReason reason) {
- return mDataDisallowedReasons.size() == 1 && contains(reason);
+ public boolean containsOnly(DataDisallowedReason... reasons) {
+ int matched = 0;
+ for (DataDisallowedReason requestedReason : reasons) {
+ if (mDataDisallowedReasons.contains(requestedReason)) matched++;
+ }
+ return matched == mDataDisallowedReasons.size();
}
/**
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index bd99a0c..bb947db 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -3230,16 +3230,18 @@
logl("Start handover " + dataNetwork + " to "
+ AccessNetworkConstants.transportTypeToString(targetTransport));
dataNetwork.startHandover(targetTransport, dataHandoverRetryEntry);
- } else if (dataEvaluation.containsOnly(DataDisallowedReason.NOT_IN_SERVICE)
- && dataNetwork.shouldDelayImsTearDownDueToInCall()) {
- // We try to preserve voice call in the case of temporary preferred transport mismatch
+ } else if (dataNetwork.shouldDelayImsTearDownDueToInCall()
+ && dataEvaluation.containsOnly(
+ DataDisallowedReason.NOT_IN_SERVICE,
+ DataDisallowedReason.NOT_ALLOWED_BY_POLICY)) {
+ // We try our best to preserve the voice call by retrying later
if (dataHandoverRetryEntry != null) {
dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED);
}
mDataRetryManager.evaluateDataHandoverRetry(dataNetwork,
DataFailCause.HANDOVER_FAILED,
DataCallResponse.RETRY_DURATION_UNDEFINED /* retry mills */);
- logl("tryHandoverDataNetwork: Scheduled retry due to in voice call and target OOS");
+ logl("tryHandoverDataNetwork: Scheduled retry due to in voice call");
} else if (dataEvaluation.containsAny(DataDisallowedReason.NOT_ALLOWED_BY_POLICY,
DataDisallowedReason.NOT_IN_SERVICE,
DataDisallowedReason.VOPS_NOT_SUPPORTED)) {
@@ -3248,8 +3250,7 @@
+ AccessNetworkConstants.transportTypeToString(targetTransport));
tearDownGracefully(dataNetwork,
DataNetwork.TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED);
- } else if (dataEvaluation.containsAny(DataDisallowedReason.ILLEGAL_STATE,
- DataDisallowedReason.RETRY_SCHEDULED)) {
+ } else if (dataEvaluation.containsAny(DataDisallowedReason.ILLEGAL_STATE)) {
logl("tryHandoverDataNetwork: Handover not allowed. " + dataNetwork
+ " will remain on " + AccessNetworkConstants.transportTypeToString(
dataNetwork.getTransport()));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index a6ccf28..7dd010d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -2431,9 +2431,7 @@
new String[]{"source=EUTRAN, target=IWLAN, type=disallowed, capabilities=MMS|IMS",
"source=IWLAN, target=EUTRAN, type=disallowed, capabilities=MMS"});
// Force data config manager to reload the carrier config.
- mDataNetworkControllerUT.getDataConfigManager().obtainMessage(
- 1/*EVENT_CARRIER_CONFIG_CHANGED*/).sendToTarget();
- processAllMessages();
+ carrierConfigChanged();
testSetupImsDataNetwork();
@@ -2473,6 +2471,35 @@
}
@Test
+ public void testHandoverDataNetworkNotAllowedByPolicyDelayDueToVoiceCall() throws Exception {
+ // Config delay IMS tear down enabled
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
+ true);
+ mCarrierConfig.putStringArray(CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY,
+ new String[]{"source=EUTRAN, target=IWLAN, type=disallowed, capabilities=MMS|IMS"});
+ carrierConfigChanged();
+
+ testSetupImsDataNetwork();
+
+ // Ringing an active call, should delay handover tear down
+ doReturn(PhoneConstants.State.RINGING).when(mCT).getState();
+ updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+
+ // Verify network is still connected due to active voice call
+ verify(mMockedWwanDataServiceManager, never()).deactivateDataCall(anyInt(),
+ eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
+
+ // Verify tear down after call ends
+ doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
+ mDataNetworkControllerUT.obtainMessage(EVENT_VOICE_CALL_ENDED).sendToTarget();
+ processAllFutureMessages();
+
+ verify(mMockedWwanDataServiceManager).deactivateDataCall(anyInt(),
+ eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
+ }
+
+ @Test
public void testHandoverDataNetworkNotAllowedByRoamingPolicy() throws Exception {
mCarrierConfig.putStringArray(CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY,
new String[]{"source=EUTRAN|NGRAN|IWLAN, target=EUTRAN|NGRAN|IWLAN, roaming=true, "