summaryrefslogtreecommitdiffstats
path: root/voip/java/android/net/sip/SipAudioCall.java
diff options
context:
space:
mode:
Diffstat (limited to 'voip/java/android/net/sip/SipAudioCall.java')
-rw-r--r--voip/java/android/net/sip/SipAudioCall.java60
1 files changed, 59 insertions, 1 deletions
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
index b46f826..c1affa6 100644
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ b/voip/java/android/net/sip/SipAudioCall.java
@@ -26,6 +26,7 @@ import android.net.sip.SimpleSessionDescription.Media;
import android.net.wifi.WifiManager;
import android.os.Message;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.Log;
import java.io.IOException;
@@ -170,6 +171,7 @@ public class SipAudioCall {
private SipProfile mLocalProfile;
private SipAudioCall.Listener mListener;
private SipSession mSipSession;
+ private SipSession mTransferringSession;
private long mSessionId = System.currentTimeMillis();
private String mPeerSd;
@@ -347,6 +349,27 @@ public class SipAudioCall {
}
}
+ private synchronized void transferToNewSession() {
+ if (mTransferringSession == null) return;
+ SipSession origin = mSipSession;
+ mSipSession = mTransferringSession;
+ mTransferringSession = null;
+
+ // stop the replaced call.
+ if (mAudioStream != null) {
+ mAudioStream.join(null);
+ } else {
+ try {
+ mAudioStream = new AudioStream(InetAddress.getByName(
+ getLocalIp()));
+ } catch (Throwable t) {
+ Log.i(TAG, "transferToNewSession(): " + t);
+ }
+ }
+ if (origin != null) origin.endCall();
+ startAudio();
+ }
+
private SipSession.Listener createListener() {
return new SipSession.Listener() {
@Override
@@ -378,6 +401,7 @@ public class SipAudioCall {
@Override
public void onRinging(SipSession session,
SipProfile peerProfile, String sessionDescription) {
+ // this callback is triggered only for reinvite.
synchronized (SipAudioCall.this) {
if ((mSipSession == null) || !mInCall
|| !session.getCallId().equals(
@@ -404,6 +428,13 @@ public class SipAudioCall {
mPeerSd = sessionDescription;
Log.v(TAG, "onCallEstablished()" + mPeerSd);
+ // TODO: how to notify the UI that the remote party is changed
+ if ((mTransferringSession != null)
+ && (session == mTransferringSession)) {
+ transferToNewSession();
+ return;
+ }
+
Listener listener = mListener;
if (listener != null) {
try {
@@ -420,7 +451,17 @@ public class SipAudioCall {
@Override
public void onCallEnded(SipSession session) {
- Log.d(TAG, "sip call ended: " + session);
+ Log.d(TAG, "sip call ended: " + session + " mSipSession:" + mSipSession);
+ // reset the trasnferring session if it is the one.
+ if (session == mTransferringSession) {
+ mTransferringSession = null;
+ return;
+ }
+ // or ignore the event if the original session is being
+ // transferred to the new one.
+ if ((mTransferringSession != null) ||
+ (session != mSipSession)) return;
+
Listener listener = mListener;
if (listener != null) {
try {
@@ -489,6 +530,22 @@ public class SipAudioCall {
public void onRegistrationDone(SipSession session, int duration) {
// irrelevant
}
+
+ @Override
+ public void onCallTransferring(SipSession newSession,
+ String sessionDescription) {
+ Log.v(TAG, "onCallTransferring mSipSession:"
+ + mSipSession + " newSession:" + newSession);
+ mTransferringSession = newSession;
+ // session changing request
+ try {
+ String answer = createAnswer(sessionDescription).encode();
+ newSession.answerCall(answer, SESSION_TIMEOUT);
+ } catch (Throwable e) {
+ Log.e(TAG, "onCallTransferring()", e);
+ newSession.endCall();
+ }
+ }
};
}
@@ -675,6 +732,7 @@ public class SipAudioCall {
}
private SimpleSessionDescription createAnswer(String offerSd) {
+ if (TextUtils.isEmpty(offerSd)) return createOffer();
SimpleSessionDescription offer =
new SimpleSessionDescription(offerSd);
SimpleSessionDescription answer =