SipAudioCall: expose startAudio()
so that apps can start audio when time is right. Change-Id: I7ae96689d3a8006b34097533bc2434bc3814b82a
This commit is contained in:
@@ -626,6 +626,7 @@ public class SipPhone extends SipPhoneBase {
|
|||||||
if (newState == Call.State.INCOMING) {
|
if (newState == Call.State.INCOMING) {
|
||||||
setState(mOwner.getState()); // INCOMING or WAITING
|
setState(mOwner.getState()); // INCOMING or WAITING
|
||||||
} else {
|
} else {
|
||||||
|
if (newState == Call.State.ACTIVE) call.startAudio();
|
||||||
setState(newState);
|
setState(newState);
|
||||||
}
|
}
|
||||||
mOwner.onConnectionStateChanged(SipConnection.this);
|
mOwner.onConnectionStateChanged(SipConnection.this);
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ public interface SipAudioCall {
|
|||||||
void setListener(Listener listener, boolean callbackImmediately);
|
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();
|
void close();
|
||||||
|
|
||||||
@@ -171,6 +171,12 @@ public interface SipAudioCall {
|
|||||||
void makeCall(SipProfile callee, SipManager sipManager, int timeout)
|
void makeCall(SipProfile callee, SipManager sipManager, int timeout)
|
||||||
throws SipException;
|
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.
|
* Attaches an incoming call to this call object.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
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
|
@Override
|
||||||
public void onCallEstablished(ISipSession session,
|
public void onCallEstablished(ISipSession session,
|
||||||
String sessionDescription) {
|
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;
|
Listener listener = mListener;
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
try {
|
try {
|
||||||
@@ -609,10 +604,23 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
|||||||
return copies;
|
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);
|
stopCall(DONT_RELEASE_SOCKET);
|
||||||
|
mInCall = true;
|
||||||
|
SdpSessionDescription peerSd = mPeerSd;
|
||||||
if (isWifiOn()) grabWifiHighPerfLock();
|
if (isWifiOn()) grabWifiHighPerfLock();
|
||||||
mPeerSd = peerSd;
|
|
||||||
String peerMediaAddress = peerSd.getPeerMediaAddress(AUDIO);
|
String peerMediaAddress = peerSd.getPeerMediaAddress(AUDIO);
|
||||||
// TODO: handle multiple media fields
|
// TODO: handle multiple media fields
|
||||||
int peerMediaPort = peerSd.getPeerMediaPort(AUDIO);
|
int peerMediaPort = peerSd.getPeerMediaPort(AUDIO);
|
||||||
@@ -621,58 +629,55 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
|||||||
int localPort = getLocalMediaPort();
|
int localPort = getLocalMediaPort();
|
||||||
int sampleRate = 8000;
|
int sampleRate = 8000;
|
||||||
int frameSize = sampleRate / 50; // 160
|
int frameSize = sampleRate / 50; // 160
|
||||||
try {
|
|
||||||
// TODO: get sample rate from sdp
|
|
||||||
mCodec = getCodec(peerSd);
|
|
||||||
|
|
||||||
AudioStream audioStream = mAudioStream;
|
// TODO: get sample rate from sdp
|
||||||
audioStream.associate(InetAddress.getByName(peerMediaAddress),
|
mCodec = getCodec(peerSd);
|
||||||
peerMediaPort);
|
|
||||||
audioStream.setCodec(convert(mCodec), mCodec.payloadType);
|
|
||||||
audioStream.setDtmfType(DTMF);
|
|
||||||
Log.d(TAG, "start media: localPort=" + localPort + ", peer="
|
|
||||||
+ peerMediaAddress + ":" + peerMediaPort);
|
|
||||||
|
|
||||||
audioStream.setMode(RtpStream.MODE_NORMAL);
|
AudioStream audioStream = mAudioStream;
|
||||||
if (!mHold) {
|
audioStream.associate(InetAddress.getByName(peerMediaAddress),
|
||||||
// FIXME: won't work if peer is not sending nor receiving
|
peerMediaPort);
|
||||||
if (!peerSd.isSending(AUDIO)) {
|
audioStream.setCodec(convert(mCodec), mCodec.payloadType);
|
||||||
Log.d(TAG, " not receiving");
|
audioStream.setDtmfType(DTMF);
|
||||||
audioStream.setMode(RtpStream.MODE_SEND_ONLY);
|
Log.d(TAG, "start media: localPort=" + localPort + ", peer="
|
||||||
}
|
+ peerMediaAddress + ":" + peerMediaPort);
|
||||||
if (!peerSd.isReceiving(AUDIO)) {
|
|
||||||
Log.d(TAG, " not sending");
|
|
||||||
audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The recorder volume will be very low if the device is in
|
audioStream.setMode(RtpStream.MODE_NORMAL);
|
||||||
* IN_CALL mode. Therefore, we have to set the mode to NORMAL
|
if (!mHold) {
|
||||||
* in order to have the normal microphone level.
|
// FIXME: won't work if peer is not sending nor receiving
|
||||||
*/
|
if (!peerSd.isSending(AUDIO)) {
|
||||||
((AudioManager) mContext.getSystemService
|
Log.d(TAG, " not receiving");
|
||||||
(Context.AUDIO_SERVICE))
|
audioStream.setMode(RtpStream.MODE_SEND_ONLY);
|
||||||
.setMode(AudioManager.MODE_NORMAL);
|
}
|
||||||
|
if (!peerSd.isReceiving(AUDIO)) {
|
||||||
|
Log.d(TAG, " not sending");
|
||||||
|
audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AudioGroup logic:
|
/* The recorder volume will be very low if the device is in
|
||||||
AudioGroup audioGroup = getAudioGroup();
|
* IN_CALL mode. Therefore, we have to set the mode to NORMAL
|
||||||
if (mHold) {
|
* in order to have the normal microphone level.
|
||||||
if (audioGroup != null) {
|
*/
|
||||||
audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
|
((AudioManager) mContext.getSystemService
|
||||||
}
|
(Context.AUDIO_SERVICE))
|
||||||
// don't create an AudioGroup here; doing so will fail if
|
.setMode(AudioManager.MODE_NORMAL);
|
||||||
// there's another AudioGroup out there that's active
|
}
|
||||||
|
|
||||||
|
// 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 {
|
} else {
|
||||||
if (audioGroup == null) audioGroup = new AudioGroup();
|
audioGroup.setMode(AudioGroup.MODE_NORMAL);
|
||||||
audioStream.join(audioGroup);
|
|
||||||
if (mMuted) {
|
|
||||||
audioGroup.setMode(AudioGroup.MODE_MUTED);
|
|
||||||
} else {
|
|
||||||
audioGroup.setMode(AudioGroup.MODE_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "call()", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user