Prevent switchHoldingAndActive() from being called twice.

There's a big old comment in the code that I added that has much more
information that I'm going to put here. This fixes an issue where we
were calling switchHoldingAndActive() too many times.

Bug: 17209905
Change-Id: I4aa1f2174f897f2f4d9f5464915b98a892b51618
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index adb430c..d9c1dea 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -289,8 +289,26 @@
         Log.v(this, "performUnhold");
         if (Call.State.HOLDING == mOriginalConnectionState) {
             try {
-                // TODO: This doesn't handle multiple calls across connection services yet
-                mOriginalConnection.getCall().getPhone().switchHoldingAndActive();
+                // Here's the deal--Telephony hold/unhold is weird because whenever there exists
+                // more than one call, one of them must always be active. In other words, if you
+                // have an active call and holding call, and you put the active call on hold, it
+                // will automatically activate the holding call. This is weird with how Telecomm
+                // sends its commands. When a user opts to "unhold" a background call, telecomm
+                // issues hold commands to all active calls, and then the unhold command to the
+                // background call. This means that we get two commands...each of which reduces to
+                // switchHoldingAndActive(). The result is that they simply cancel each other out.
+                // To fix this so that it works well with telecomm we add a minor hack. If we
+                // have one telephony call, everything works as normally expected. But if we have
+                // two or more calls, we will ignore all requests to "unhold" knowing that the hold
+                // requests already do what we want. If you've read up to this point, I'm very sorry
+                // that we are doing this. I didn't think of a better solution that wouldn't also
+                // make the Telecomm APIs very ugly.
+
+                if (!hasMultipleTopLevelCalls()) {
+                    mOriginalConnection.getCall().getPhone().switchHoldingAndActive();
+                } else {
+                    Log.i(this, "Skipping unhold command for %s", this);
+                }
             } catch (CallStateException e) {
                 Log.e(this, e, "Exception occurred while trying to release call from hold.");
             }
@@ -391,6 +409,23 @@
         return null;
     }
 
+    private boolean hasMultipleTopLevelCalls() {
+        int numCalls = 0;
+        Phone phone = getPhone();
+        if (phone != null) {
+            if (!phone.getRingingCall().isIdle()) {
+                numCalls++;
+            }
+            if (!phone.getForegroundCall().isIdle()) {
+                numCalls++;
+            }
+            if (!phone.getBackgroundCall().isIdle()) {
+                numCalls++;
+            }
+        }
+        return numCalls > 1;
+    }
+
     private com.android.internal.telephony.Connection getForegroundConnection() {
         if (getPhone() != null) {
             return getPhone().getForegroundCall().getEarliestConnection();