diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java index d7dc4abcd1d45..3e8867b7a242b 100755 --- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java +++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java @@ -626,6 +626,7 @@ public class SipPhone extends SipPhoneBase { if (newState == Call.State.INCOMING) { setState(mOwner.getState()); // INCOMING or WAITING } else { + if (newState == Call.State.ACTIVE) call.startAudio(); setState(newState); } mOwner.onConnectionStateChanged(SipConnection.this); diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java index 2a9a65b50d160..4abea205c6d3e 100644 --- a/voip/java/android/net/sip/SipAudioCall.java +++ b/voip/java/android/net/sip/SipAudioCall.java @@ -153,7 +153,7 @@ public interface SipAudioCall { void setListener(Listener listener, boolean callbackImmediately); /** - * Closes this object. The object is not usable after being closed. + * Closes this object. This object is not usable after being closed. */ void close(); @@ -171,6 +171,12 @@ public interface SipAudioCall { void makeCall(SipProfile callee, SipManager sipManager, int timeout) throws SipException; + /** + * Starts the audio for the established call. This method should be called + * after {@link Listener#onCallEstablished} is called. + */ + void startAudio(); + /** * Attaches an incoming call to this call object. * diff --git a/voip/java/android/net/sip/SipAudioCallImpl.java b/voip/java/android/net/sip/SipAudioCallImpl.java index fcabcc4d2274b..e61e8789b9723 100644 --- a/voip/java/android/net/sip/SipAudioCallImpl.java +++ b/voip/java/android/net/sip/SipAudioCallImpl.java @@ -37,6 +37,7 @@ import android.util.Log; import java.io.IOException; import java.net.InetAddress; +import java.net.UnknownHostException; import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; @@ -239,24 +240,18 @@ public class SipAudioCallImpl extends SipSessionAdapter } } - private synchronized void establishCall(String sessionDescription) { - stopRingbackTone(); - stopRinging(); - try { - SdpSessionDescription sd = - new SdpSessionDescription(sessionDescription); - Log.d(TAG, "sip call established: " + sd); - startCall(sd); - mInCall = true; - } catch (SdpException e) { - Log.e(TAG, "createSessionDescription()", e); - } - } - @Override public void onCallEstablished(ISipSession session, String sessionDescription) { - establishCall(sessionDescription); + stopRingbackTone(); + stopRinging(); + try { + mPeerSd = new SdpSessionDescription(sessionDescription); + Log.d(TAG, "sip call established: " + mPeerSd); + } catch (SdpException e) { + Log.e(TAG, "createSessionDescription()", e); + } + Listener listener = mListener; if (listener != null) { try { @@ -609,10 +604,23 @@ public class SipAudioCallImpl extends SipSessionAdapter return copies; } - private void startCall(SdpSessionDescription peerSd) { + public void startAudio() { + try { + startAudioInternal(); + } catch (UnknownHostException e) { + onError(mSipSession, SipErrorCode.PEER_NOT_REACHABLE.toString(), + e.getMessage()); + } catch (Throwable e) { + onError(mSipSession, SipErrorCode.CLIENT_ERROR.toString(), + e.getMessage()); + } + } + + private synchronized void startAudioInternal() throws UnknownHostException { stopCall(DONT_RELEASE_SOCKET); + mInCall = true; + SdpSessionDescription peerSd = mPeerSd; if (isWifiOn()) grabWifiHighPerfLock(); - mPeerSd = peerSd; String peerMediaAddress = peerSd.getPeerMediaAddress(AUDIO); // TODO: handle multiple media fields int peerMediaPort = peerSd.getPeerMediaPort(AUDIO); @@ -621,58 +629,55 @@ public class SipAudioCallImpl extends SipSessionAdapter int localPort = getLocalMediaPort(); int sampleRate = 8000; int frameSize = sampleRate / 50; // 160 - try { - // TODO: get sample rate from sdp - mCodec = getCodec(peerSd); - AudioStream audioStream = mAudioStream; - audioStream.associate(InetAddress.getByName(peerMediaAddress), - peerMediaPort); - audioStream.setCodec(convert(mCodec), mCodec.payloadType); - audioStream.setDtmfType(DTMF); - Log.d(TAG, "start media: localPort=" + localPort + ", peer=" - + peerMediaAddress + ":" + peerMediaPort); + // TODO: get sample rate from sdp + mCodec = getCodec(peerSd); - audioStream.setMode(RtpStream.MODE_NORMAL); - if (!mHold) { - // FIXME: won't work if peer is not sending nor receiving - if (!peerSd.isSending(AUDIO)) { - Log.d(TAG, " not receiving"); - audioStream.setMode(RtpStream.MODE_SEND_ONLY); - } - if (!peerSd.isReceiving(AUDIO)) { - Log.d(TAG, " not sending"); - audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY); - } + AudioStream audioStream = mAudioStream; + audioStream.associate(InetAddress.getByName(peerMediaAddress), + peerMediaPort); + audioStream.setCodec(convert(mCodec), mCodec.payloadType); + audioStream.setDtmfType(DTMF); + Log.d(TAG, "start media: localPort=" + localPort + ", peer=" + + peerMediaAddress + ":" + peerMediaPort); - /* The recorder volume will be very low if the device is in - * IN_CALL mode. Therefore, we have to set the mode to NORMAL - * in order to have the normal microphone level. - */ - ((AudioManager) mContext.getSystemService - (Context.AUDIO_SERVICE)) - .setMode(AudioManager.MODE_NORMAL); + audioStream.setMode(RtpStream.MODE_NORMAL); + if (!mHold) { + // FIXME: won't work if peer is not sending nor receiving + if (!peerSd.isSending(AUDIO)) { + Log.d(TAG, " not receiving"); + audioStream.setMode(RtpStream.MODE_SEND_ONLY); + } + if (!peerSd.isReceiving(AUDIO)) { + Log.d(TAG, " not sending"); + audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY); } - // AudioGroup logic: - AudioGroup audioGroup = getAudioGroup(); - if (mHold) { - if (audioGroup != null) { - audioGroup.setMode(AudioGroup.MODE_ON_HOLD); - } - // don't create an AudioGroup here; doing so will fail if - // there's another AudioGroup out there that's active + /* The recorder volume will be very low if the device is in + * IN_CALL mode. Therefore, we have to set the mode to NORMAL + * in order to have the normal microphone level. + */ + ((AudioManager) mContext.getSystemService + (Context.AUDIO_SERVICE)) + .setMode(AudioManager.MODE_NORMAL); + } + + // AudioGroup logic: + AudioGroup audioGroup = getAudioGroup(); + if (mHold) { + if (audioGroup != null) { + audioGroup.setMode(AudioGroup.MODE_ON_HOLD); + } + // don't create an AudioGroup here; doing so will fail if + // there's another AudioGroup out there that's active + } else { + if (audioGroup == null) audioGroup = new AudioGroup(); + audioStream.join(audioGroup); + if (mMuted) { + audioGroup.setMode(AudioGroup.MODE_MUTED); } else { - if (audioGroup == null) audioGroup = new AudioGroup(); - audioStream.join(audioGroup); - if (mMuted) { - audioGroup.setMode(AudioGroup.MODE_MUTED); - } else { - audioGroup.setMode(AudioGroup.MODE_NORMAL); - } + audioGroup.setMode(AudioGroup.MODE_NORMAL); } - } catch (Exception e) { - Log.e(TAG, "call()", e); } }