am 803bf856: am db6ead53: am 3c326af8: am 595787d0: Merge "Fix issue where GSM conference is held in makeRoomForOutgoingCall." into mnc-dev

* commit '803bf8565ed3599183f83feea22d9e4cbb1c9070':
  Fix issue where GSM conference is held in makeRoomForOutgoingCall.
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index cebd6bc..8ec5202 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1504,10 +1504,27 @@
 
             // We have room for at least one more holding call at this point.
 
+            // TODO: Remove once b/23035408 has been corrected.
+            // If the live call is a conference, it will not have a target phone account set.  This
+            // means the check to see if the live call has the same target phone account as the new
+            // call will not cause us to bail early.  As a result, we'll end up holding the
+            // ongoing conference call.  However, the ConnectionService is already doing that.  This
+            // has caused problems with some carriers.  As a workaround until b/23035408 is
+            // corrected, we will try and get the target phone account for one of the conference's
+            // children and use that instead.
+            PhoneAccountHandle liveCallPhoneAccount = liveCall.getTargetPhoneAccount();
+            if (liveCallPhoneAccount == null && liveCall.isConference() &&
+                    !liveCall.getChildCalls().isEmpty()) {
+                liveCallPhoneAccount = getFirstChildPhoneAccount(liveCall);
+                Log.i(this, "makeRoomForOutgoingCall: using child call PhoneAccount = " +
+                        liveCallPhoneAccount);
+            }
+
             // First thing, if we are trying to make a call with the same phone account as the live
             // call, then allow it so that the connection service can make its own decision about
             // how to handle the new call relative to the current one.
-            if (Objects.equals(liveCall.getTargetPhoneAccount(), call.getTargetPhoneAccount())) {
+            if (Objects.equals(liveCallPhoneAccount, call.getTargetPhoneAccount())) {
+                Log.i(this, "makeRoomForOutgoingCall: phoneAccount matches.");
                 return true;
             } else if (call.getTargetPhoneAccount() == null) {
                 // Without a phone account, we can't say reliably that the call will fail.
@@ -1521,6 +1538,7 @@
 
             // Try to hold the live call before attempting the new outgoing call.
             if (liveCall.can(Connection.CAPABILITY_HOLD)) {
+                Log.i(this, "makeRoomForOutgoingCall: holding live call.");
                 liveCall.hold();
                 return true;
             }
@@ -1532,6 +1550,22 @@
     }
 
     /**
+     * Given a call, find the first non-null phone account handle of its children.
+     *
+     * @param parentCall The parent call.
+     * @return The first non-null phone account handle of the children, or {@code null} if none.
+     */
+    private PhoneAccountHandle getFirstChildPhoneAccount(Call parentCall) {
+        for (Call childCall : parentCall.getChildCalls()) {
+            PhoneAccountHandle childPhoneAccount = childCall.getTargetPhoneAccount();
+            if (childPhoneAccount != null) {
+                return childPhoneAccount;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Checks to see if the call should be on speakerphone and if so, set it.
      */
     private void maybeMoveToSpeakerPhone(Call call) {