diff options
Diffstat (limited to 'voip/java/android/net/sip/SipAudioCall.java')
-rw-r--r-- | voip/java/android/net/sip/SipAudioCall.java | 60 |
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 = |