Fix issue with concurrent call disconnect code in Telecom.

The method holdActiveCallForNewCall is used to ensure that an active call
is either held or disconnected when there is a new incoming call.
There is a special case logic block which applies for Telephony calls
where there is an active call and a held call, and a new incoming call
comes in which the user answers.  The special case is intended to
drop the held call so that the current active call can be held so that
the ringing call can be answered.

There was a flaw in that code which was causing the self-managed CS
CTS verifier test to fail.  Essentially the special case logic block was
being invoked, and as a result when there was another active call which
could not be held from a different connection service, the call would be
held instead of disconnected.

Test: Ran CTS Verifier test and ensures it passes.
Test: Manually reproduce the telephony scenario which the special case
block is intended to handle.
Bug: 80407839
Merged-In: I348da7de84f83b1749af41d6985526bcefcc606a
Change-Id: I348da7de84f83b1749af41d6985526bcefcc606a
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 6287bb8..20ac66d 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1924,12 +1924,28 @@
             if (canHold(activeCall)) {
                 activeCall.hold();
                 return true;
-            } else if (supportsHold(call)) {
+            } else if (supportsHold(activeCall)
+                    && activeCall.getConnectionService() == call.getConnectionService()) {
+
+                // Handle the case where the active call and the new call are from the same CS, and
+                // the currently active call supports hold but cannot currently be held.
+                // In this case we'll look for the other held call for this connectionService and
+                // disconnect it prior to holding the active call.
+                // E.g.
+                // Call A - Held   (Supports hold, can't hold)
+                // Call B - Active (Supports hold, can't hold)
+                // Call C - Incoming
+                // Here we need to disconnect A prior to holding B so that C can be answered.
+                // This case is driven by telephony requirements ultimately.
                 Call heldCall = getHeldCallByConnectionService(call.getConnectionService());
                 if (heldCall != null) {
                     heldCall.disconnect();
-                    Log.i(this, "Disconnecting held call %s before holding active call.", heldCall);
+                    Log.i(this, "holdActiveCallForNewCall: Disconnect held call %s before "
+                                    + "holding active call %s.",
+                            heldCall.getId(), activeCall.getId());
                 }
+                Log.i(this, "holdActiveCallForNewCall: Holding active %s before making %s active.",
+                        activeCall.getId(), call.getId());
                 activeCall.hold();
                 return true;
             } else {
@@ -1937,6 +1953,8 @@
                 // service, then disconnect it, otherwise allow the connection service to
                 // figure out the right states.
                 if (activeCall.getConnectionService() != call.getConnectionService()) {
+                    Log.i(this, "holdActiveCallForNewCall: disconnecting %s so that %s can be "
+                            + "made active.", activeCall.getId(), call.getId());
                     activeCall.disconnect();
                 }
             }