DO NOT MERGE DSDA: Set call EXTRA if either sub doesn't allow hold am: 3e51fb3a50
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telephony/+/25662765
Change-Id: I2972774a15d5e6bbe028a0c802b797b12c8dc667
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 7aa0e7b..e048c0a 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -1304,12 +1304,20 @@
originalConnection.sendRttModifyResponse(textStream);
}
+ private boolean answeringDropsFgCalls() {
+ Bundle extras = getExtras();
+ if (extras != null) {
+ return extras.getBoolean(Connection.EXTRA_ANSWERING_DROPS_FG_CALL);
+ }
+ return false;
+ }
+
public void performAnswer(int videoState) {
Log.v(this, "performAnswer");
if (isValidRingingCall() && getPhone() != null) {
try {
mTelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
- getPhoneAccountHandle());
+ getPhoneAccountHandle(), answeringDropsFgCalls());
getPhone().acceptCall(videoState);
} catch (CallStateException e) {
Log.e(this, e, "Failed to accept call.");
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 61b661b..f37b8a1 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -3819,10 +3819,31 @@
return origAccountHandle;
}
+ /*
+ * Returns true if both existing connections on-device and the incoming connection support HOLD,
+ * false otherwise. Assumes that a TelephonyConference supports HOLD.
+ */
+ private boolean allCallsSupportHold(@NonNull TelephonyConnection incomingConnection) {
+ if (getAllConnections().stream()
+ .filter(c ->
+ // Exclude multiendpoint calls as they're not on this device.
+ (c.getConnectionProperties() & Connection.PROPERTY_IS_EXTERNAL_CALL) == 0
+ && (c.getConnectionCapabilities()
+ & Connection.CAPABILITY_SUPPORT_HOLD) != 0).count() == 0) {
+ return false;
+ }
+ if ((incomingConnection.getConnectionCapabilities()
+ & Connection.CAPABILITY_SUPPORT_HOLD) == 0) {
+ return false;
+ }
+ return true;
+ }
+
/**
- * For the passed in incoming {@link TelephonyConnection}, for non- dual active voice devices,
+ * For the passed in incoming {@link TelephonyConnection}, for non-dual active voice devices,
* adds {@link Connection#EXTRA_ANSWERING_DROPS_FG_CALL} if there are ongoing calls on another
- * subscription (ie phone account handle) than the one passed in.
+ * subscription (ie phone account handle) than the one passed in. For dual active voice devices,
+ * still sets the EXTRA if either subscription has connections that don't support hold.
* @param connection The connection.
* @param phoneAccountHandle The {@link PhoneAccountHandle} the incoming call originated on;
* this is passed in because
@@ -3832,10 +3853,11 @@
*/
public void maybeIndicateAnsweringWillDisconnect(@NonNull TelephonyConnection connection,
@NonNull PhoneAccountHandle phoneAccountHandle) {
- if (mTelephonyManagerProxy.isConcurrentCallsPossible()) {
- return;
- }
if (isCallPresentOnOtherSub(phoneAccountHandle)) {
+ if (mTelephonyManagerProxy.isConcurrentCallsPossible()
+ && allCallsSupportHold(connection)) {
+ return;
+ }
Log.i(this, "maybeIndicateAnsweringWillDisconnect; answering call %s will cause a call "
+ "on another subscription to drop.", connection.getTelecomCallId());
Bundle extras = new Bundle();
@@ -3860,13 +3882,16 @@
/**
* Where there are ongoing calls on another subscription other than the one specified,
- * disconnect these calls for non-DSDA devices. This is used where there is an incoming call on
- * one sub, but there are ongoing calls on another sub which need to be disconnected.
+ * disconnect these calls. This is used where there is an incoming call on one sub, but there
+ * are ongoing calls on another sub which need to be disconnected.
* @param incomingHandle The incoming {@link PhoneAccountHandle}.
+ * @param answeringDropsFgCall Whether for dual-SIM dual active devices, answering the incoming
+ * call should drop the second call.
*/
- public void maybeDisconnectCallsOnOtherSubs(@NonNull PhoneAccountHandle incomingHandle) {
+ public void maybeDisconnectCallsOnOtherSubs(
+ @NonNull PhoneAccountHandle incomingHandle, boolean answeringDropsFgCall) {
Log.i(this, "maybeDisconnectCallsOnOtherSubs: check for calls not on %s", incomingHandle);
- maybeDisconnectCallsOnOtherSubs(getAllConnections(), incomingHandle,
+ maybeDisconnectCallsOnOtherSubs(getAllConnections(), incomingHandle, answeringDropsFgCall,
mTelephonyManagerProxy);
}
@@ -3876,13 +3901,16 @@
* the core functionality.
* @param connections the calls to check.
* @param incomingHandle the incoming handle.
+ * @param answeringDropsFgCall Whether for dual-SIM dual active devices, answering the incoming
+ * call should drop the second call.
* @param telephonyManagerProxy the proxy to the {@link TelephonyManager} instance.
*/
@VisibleForTesting
public static void maybeDisconnectCallsOnOtherSubs(@NonNull Collection<Connection> connections,
@NonNull PhoneAccountHandle incomingHandle,
+ boolean answeringDropsFgCall,
TelephonyManagerProxy telephonyManagerProxy) {
- if (telephonyManagerProxy.isConcurrentCallsPossible()) {
+ if (telephonyManagerProxy.isConcurrentCallsPossible() && !answeringDropsFgCall) {
return;
}
connections.stream()
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index c143c31..0bfcb5c 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -1709,7 +1709,7 @@
SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false);
tcs.add(tc1);
TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
- tcs, SUB1_HANDLE, mTelephonyManagerProxy);
+ tcs, SUB1_HANDLE, false, mTelephonyManagerProxy);
// Would've preferred to use mockito, but can't mock out TelephonyConnection/Connection
// easily.
assertFalse(tc1.wasDisconnected);
@@ -1722,7 +1722,7 @@
SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, true);
tcs.add(tc1);
TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
- tcs, SUB2_HANDLE, mTelephonyManagerProxy);
+ tcs, SUB2_HANDLE, false, mTelephonyManagerProxy);
// Other call is an emergency call, so don't disconnect it.
assertFalse(tc1.wasDisconnected);
}
@@ -1735,7 +1735,7 @@
android.telecom.Connection.PROPERTY_IS_EXTERNAL_CALL, false);
tcs.add(tc1);
TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
- tcs, SUB2_HANDLE, mTelephonyManagerProxy);
+ tcs, SUB2_HANDLE, false, mTelephonyManagerProxy);
// Other call is an external call, so don't disconnect it.
assertFalse(tc1.wasDisconnected);
}
@@ -1747,7 +1747,7 @@
SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false);
tcs.add(tc1);
TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
- tcs, SUB2_HANDLE, mTelephonyManagerProxy);
+ tcs, SUB2_HANDLE, false, mTelephonyManagerProxy);
assertTrue(tc1.wasDisconnected);
}
@@ -1761,14 +1761,14 @@
tcs.add(tc1);
tcs.add(tc2);
TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
- tcs, SUB2_HANDLE, mTelephonyManagerProxy);
+ tcs, SUB2_HANDLE, false, mTelephonyManagerProxy);
assertTrue(tc1.wasDisconnected);
assertTrue(tc2.wasDisconnected);
}
/**
* Verifies that DSDA or virtual DSDA-enabled devices can support active non-emergency calls on
- * separate subs.
+ * separate subs, when the extra EXTRA_ANSWERING_DROPS_FG_CALL is not set on the incoming call.
*/
@Test
@SmallTest
@@ -1779,10 +1779,26 @@
SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false);
tcs.add(tc1);
TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
- tcs, SUB2_HANDLE, mTelephonyManagerProxy);
+ tcs, SUB2_HANDLE, false, mTelephonyManagerProxy);
assertFalse(tc1.wasDisconnected);
}
+ /**
+ * Verifies that DSDA or virtual DSDA-enabled devices will disconnect the existing call when the
+ * call extra EXTRA_ANSWERING_DROPS_FG_CALL is set on the incoming call on a different sub.
+ */
+ @Test
+ @SmallTest
+ public void testDisconnectDifferentSubForVirtualDsdaDevice_ifCallExtraSet() {
+ when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true);
+
+ ArrayList<android.telecom.Connection> tcs = new ArrayList<>();
+ SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false);
+ tcs.add(tc1);
+ TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs(
+ tcs, SUB2_HANDLE, true, mTelephonyManagerProxy);
+ assertTrue(tc1.wasDisconnected);
+ }
/**
* For calls on the same sub, the Dialer implements the 'swap' functionality to perform hold and