am 940b4d1c: am 6037a056: Fix n-way conf call in SipPhone.

Merge commit '940b4d1c4548d3296ac9fc66cce0cc213b5aa8a8'

* commit '940b4d1c4548d3296ac9fc66cce0cc213b5aa8a8':
  Fix n-way conf call in SipPhone.
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index a25b3ca..ef31ddd 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -484,7 +484,12 @@
 
         void merge(SipCall that) throws CallStateException {
             AudioGroup audioGroup = getAudioGroup();
-            for (Connection c : that.connections) {
+
+            // copy to an array to avoid concurrent modification as connections
+            // in that.connections will be removed in add(SipConnection).
+            Connection[] cc = that.connections.toArray(
+                    new Connection[that.connections.size()]);
+            for (Connection c : cc) {
                 SipConnection conn = (SipConnection) c;
                 add(conn);
                 if (conn.getState() == Call.State.HOLDING) {
@@ -801,7 +806,9 @@
         @Override
         public void separate() throws CallStateException {
             synchronized (SipPhone.class) {
-                SipCall call = (SipCall) SipPhone.this.getBackgroundCall();
+                SipCall call = (getPhone() == SipPhone.this)
+                        ? (SipCall) SipPhone.this.getBackgroundCall()
+                        : (SipCall) SipPhone.this.getForegroundCall();
                 if (call.getState() != Call.State.IDLE) {
                     throw new CallStateException(
                             "cannot put conn back to a call in non-idle state: "
@@ -811,10 +818,20 @@
                         + mPeer.getUriString() + " from " + mOwner + " back to "
                         + call);
 
+                // separate the AudioGroup and connection from the original call
+                Phone originalPhone = getPhone();
                 AudioGroup audioGroup = call.getAudioGroup(); // may be null
                 call.add(this);
                 mSipAudioCall.setAudioGroup(audioGroup);
-                call.hold();
+
+                // put the original call to bg; and the separated call becomes
+                // fg if it was in bg
+                originalPhone.switchHoldingAndActive();
+
+                // start audio and notify the phone app of the state change
+                call = (SipCall) SipPhone.this.getForegroundCall();
+                mSipAudioCall.startAudio();
+                call.onConnectionStateChanged(this);
             }
         }