summaryrefslogtreecommitdiffstats
path: root/telephony/java
diff options
context:
space:
mode:
authorHung-ying Tyan <tyanh@google.com>2010-10-20 22:49:33 +0800
committerHung-ying Tyan <tyanh@google.com>2010-10-21 03:59:04 +0800
commit6037a056ea0dda27a286ddcb527b323b58a1c7c7 (patch)
treef9854464261707c5e49f61b52a92a322d337670f /telephony/java
parent23392a84bcb961d3fd50142ec40ce6ac6db89018 (diff)
downloadframeworks_base-6037a056ea0dda27a286ddcb527b323b58a1c7c7.zip
frameworks_base-6037a056ea0dda27a286ddcb527b323b58a1c7c7.tar.gz
frameworks_base-6037a056ea0dda27a286ddcb527b323b58a1c7c7.tar.bz2
Fix n-way conf call in SipPhone.
+ Avoid concurrent modification when forming >3-way conf call. + Revise SipConnection.separate() to put the newly separated call to foreground. Bug: 3114987 Change-Id: If6204e7e3cc05f4a516c33657a368b53a0ad014d
Diffstat (limited to 'telephony/java')
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhone.java23
1 files changed, 20 insertions, 3 deletions
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 8f3c458..b154c91 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -481,7 +481,12 @@ public class SipPhone extends SipPhoneBase {
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) {
@@ -798,7 +803,9 @@ public class SipPhone extends SipPhoneBase {
@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: "
@@ -808,10 +815,20 @@ public class SipPhone extends SipPhoneBase {
+ 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);
}
}