am 8eac20ea: SIP: implement conference call

Merge commit '8eac20eacd088793547c56e14d602b28d62fb278' into gingerbread-plus-aosp

* commit '8eac20eacd088793547c56e14d602b28d62fb278':
  SIP: implement conference call
This commit is contained in:
Hung-ying Tyan
2010-08-18 13:37:25 -07:00
committed by Android Git Automerger
2 changed files with 51 additions and 5 deletions

View File

@@ -16,6 +16,8 @@
package com.android.internal.telephony; package com.android.internal.telephony;
import com.android.internal.telephony.sip.SipPhone;
import android.content.Context; import android.content.Context;
import android.os.AsyncResult; import android.os.AsyncResult;
import android.os.Handler; import android.os.Handler;
@@ -453,7 +455,7 @@ public final class CallManager {
heldPhone = heldCall.getPhone(); heldPhone = heldCall.getPhone();
} }
return (heldPhone == activePhone); return heldPhone.getClass().equals(activePhone.getClass());
} }
/** /**
@@ -466,10 +468,14 @@ public final class CallManager {
* In these cases, this operation may not be performed. * In these cases, this operation may not be performed.
*/ */
public void conference(Call heldCall) throws CallStateException { public void conference(Call heldCall) throws CallStateException {
if (canConference(heldCall)) Phone fgPhone = getFgPhone();
if (fgPhone instanceof SipPhone) {
((SipPhone) fgPhone).conference(heldCall);
} else if (canConference(heldCall)) {
fgPhone.conference();
} else {
throw(new CallStateException("Can't conference foreground and selected background call")); throw(new CallStateException("Can't conference foreground and selected background call"));
}
heldCall.getPhone().conference();
} }
/** /**

View File

@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.net.rtp.AudioGroup; import android.net.rtp.AudioGroup;
import android.net.rtp.AudioStream;
import android.net.sip.SipAudioCall; import android.net.sip.SipAudioCall;
import android.net.sip.SipManager; import android.net.sip.SipManager;
import android.net.sip.SipProfile; import android.net.sip.SipProfile;
@@ -221,7 +222,21 @@ public class SipPhone extends SipPhoneBase {
} }
public void conference() throws CallStateException { public void conference() throws CallStateException {
// TODO if ((foregroundCall.getState() != SipCall.State.ACTIVE)
|| (foregroundCall.getState() != SipCall.State.ACTIVE)) {
throw new CallStateException("wrong state to merge calls: fg="
+ foregroundCall.getState() + ", bg="
+ backgroundCall.getState());
}
foregroundCall.merge(backgroundCall);
}
public void conference(Call that) throws CallStateException {
if (!(that instanceof SipCall)) {
throw new CallStateException("expect " + SipCall.class
+ ", cannot merge with " + that.getClass());
}
foregroundCall.merge((SipCall) that);
} }
public boolean canTransfer() { public boolean canTransfer() {
@@ -467,6 +482,18 @@ public class SipPhone extends SipPhoneBase {
return (audioGroup.getMode() == AudioGroup.MODE_MUTED); return (audioGroup.getMode() == AudioGroup.MODE_MUTED);
} }
void merge(SipCall that) throws CallStateException {
AudioGroup myGroup = getAudioGroup();
for (Connection c : that.connections) {
SipConnection conn = (SipConnection) c;
conn.mergeTo(myGroup);
connections.add(conn);
conn.changeOwner(this);
}
that.connections.clear();
that.setState(Call.State.IDLE);
}
void sendDtmf(char c) { void sendDtmf(char c) {
AudioGroup audioGroup = getAudioGroup(); AudioGroup audioGroup = getAudioGroup();
if (audioGroup == null) return; if (audioGroup == null) return;
@@ -541,6 +568,7 @@ public class SipPhone extends SipPhoneBase {
private class SipConnection extends SipConnectionBase { private class SipConnection extends SipConnectionBase {
private SipCall mOwner; private SipCall mOwner;
private SipAudioCall mSipAudioCall; private SipAudioCall mSipAudioCall;
private AudioGroup mOriginalGroup;
private Call.State mState = Call.State.IDLE; private Call.State mState = Call.State.IDLE;
private SipProfile mPeer; private SipProfile mPeer;
private boolean mIncoming = false; private boolean mIncoming = false;
@@ -660,6 +688,16 @@ public class SipPhone extends SipPhoneBase {
} }
} }
void mergeTo(AudioGroup group) throws CallStateException {
AudioStream stream = mSipAudioCall.getAudioStream();
if (stream == null) {
throw new CallStateException("wrong state to merge: "
+ mSipAudioCall.getState());
}
if (mOriginalGroup == null) mOriginalGroup = getAudioGroup();
stream.join(group);
}
@Override @Override
protected void setState(Call.State state) { protected void setState(Call.State state) {
if (state == mState) return; if (state == mState) return;
@@ -694,6 +732,8 @@ public class SipPhone extends SipPhoneBase {
@Override @Override
public void hangup() throws CallStateException { public void hangup() throws CallStateException {
// TODO: need to pull AudioStream out of the AudioGroup in case
// this conn was part of a conf call
Log.v(LOG_TAG, "hangup conn: " + mPeer.getUriString() + ": " Log.v(LOG_TAG, "hangup conn: " + mPeer.getUriString() + ": "
+ ": on phone " + getPhone()); + ": on phone " + getPhone());
try { try {