am 9404e633: Merge "Add timer to SIP session creation process." into gingerbread
Merge commit '9404e633a55cd325b57732cdd776053b3886b611' into gingerbread-plus-aosp * commit '9404e633a55cd325b57732cdd776053b3886b611': Add timer to SIP session creation process.
This commit is contained in:
@@ -84,7 +84,8 @@ class SipSessionGroup implements SipListener {
|
||||
private static final boolean DEBUG_PING = DEBUG && false;
|
||||
private static final String ANONYMOUS = "anonymous";
|
||||
private static final String SERVER_ERROR_PREFIX = "Response: ";
|
||||
private static final int EXPIRY_TIME = 3600;
|
||||
private static final int EXPIRY_TIME = 3600; // in seconds
|
||||
private static final int CANCEL_CALL_TIMER = 5; // in seconds
|
||||
|
||||
private static final EventObject DEREGISTER = new EventObject("Deregister");
|
||||
private static final EventObject END_CALL = new EventObject("End call");
|
||||
@@ -363,6 +364,40 @@ class SipSessionGroup implements SipListener {
|
||||
String mPeerSessionDescription;
|
||||
boolean mInCall;
|
||||
boolean mReRegisterFlag = false;
|
||||
SessionTimer mTimer;
|
||||
|
||||
// lightweight timer
|
||||
class SessionTimer {
|
||||
private boolean mRunning = true;
|
||||
|
||||
void start(final int timeout) {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
sleep(timeout);
|
||||
if (mRunning) timeout();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
synchronized void cancel() {
|
||||
mRunning = false;
|
||||
this.notify();
|
||||
}
|
||||
|
||||
private void timeout() {
|
||||
synchronized (SipSessionGroup.this) {
|
||||
onError(SipErrorCode.TIME_OUT, "Session timed out!");
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void sleep(int timeout) {
|
||||
try {
|
||||
this.wait(timeout * 1000);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "session timer interrupted!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SipSessionImpl(ISipSessionListener listener) {
|
||||
setListener(listener);
|
||||
@@ -382,6 +417,8 @@ class SipSessionGroup implements SipListener {
|
||||
mServerTransaction = null;
|
||||
mClientTransaction = null;
|
||||
mPeerSessionDescription = null;
|
||||
|
||||
cancelSessionTimer();
|
||||
}
|
||||
|
||||
public boolean isInCall() {
|
||||
@@ -434,16 +471,16 @@ class SipSessionGroup implements SipListener {
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void makeCall(SipProfile peerProfile,
|
||||
String sessionDescription) {
|
||||
doCommandAsync(
|
||||
new MakeCallCommand(peerProfile, sessionDescription));
|
||||
public void makeCall(SipProfile peerProfile, String sessionDescription,
|
||||
int timeout) {
|
||||
doCommandAsync(new MakeCallCommand(peerProfile, sessionDescription,
|
||||
timeout));
|
||||
}
|
||||
|
||||
public void answerCall(String sessionDescription) {
|
||||
public void answerCall(String sessionDescription, int timeout) {
|
||||
try {
|
||||
processCommand(
|
||||
new MakeCallCommand(mPeerProfile, sessionDescription));
|
||||
processCommand(new MakeCallCommand(mPeerProfile,
|
||||
sessionDescription, timeout));
|
||||
} catch (SipException e) {
|
||||
onError(e);
|
||||
}
|
||||
@@ -453,9 +490,15 @@ class SipSessionGroup implements SipListener {
|
||||
doCommandAsync(END_CALL);
|
||||
}
|
||||
|
||||
public void changeCall(String sessionDescription) {
|
||||
doCommandAsync(
|
||||
new MakeCallCommand(mPeerProfile, sessionDescription));
|
||||
public void changeCall(String sessionDescription, int timeout) {
|
||||
doCommandAsync(new MakeCallCommand(mPeerProfile, sessionDescription,
|
||||
timeout));
|
||||
}
|
||||
|
||||
public void changeCallWithTimeout(
|
||||
String sessionDescription, int timeout) {
|
||||
doCommandAsync(new MakeCallCommand(mPeerProfile, sessionDescription,
|
||||
timeout));
|
||||
}
|
||||
|
||||
public void register(int duration) {
|
||||
@@ -800,6 +843,7 @@ class SipSessionGroup implements SipListener {
|
||||
addSipSession(this);
|
||||
mState = SipSessionState.OUTGOING_CALL;
|
||||
mProxy.onCalling(this);
|
||||
startSessionTimer(cmd.getTimeout());
|
||||
return true;
|
||||
} else if (evt instanceof RegisterCommand) {
|
||||
int duration = ((RegisterCommand) evt).getDuration();
|
||||
@@ -831,6 +875,7 @@ class SipSessionGroup implements SipListener {
|
||||
((MakeCallCommand) evt).getSessionDescription(),
|
||||
mServerTransaction);
|
||||
mState = SipSessionState.INCOMING_CALL_ANSWERING;
|
||||
startSessionTimer(((MakeCallCommand) evt).getTimeout());
|
||||
return true;
|
||||
} else if (END_CALL == evt) {
|
||||
mSipHelper.sendInviteBusyHere(mInviteReceived,
|
||||
@@ -873,6 +918,7 @@ class SipSessionGroup implements SipListener {
|
||||
if (mState == SipSessionState.OUTGOING_CALL) {
|
||||
mState = SipSessionState.OUTGOING_CALL_RING_BACK;
|
||||
mProxy.onRingingBack(this);
|
||||
cancelSessionTimer();
|
||||
}
|
||||
return true;
|
||||
case Response.OK:
|
||||
@@ -885,10 +931,10 @@ class SipSessionGroup implements SipListener {
|
||||
if (handleAuthentication(event)) {
|
||||
addSipSession(this);
|
||||
} else if (mLastNonce == null) {
|
||||
endCallOnError(SipErrorCode.SERVER_ERROR,
|
||||
onError(SipErrorCode.SERVER_ERROR,
|
||||
"server does not provide challenge");
|
||||
} else {
|
||||
endCallOnError(SipErrorCode.INVALID_CREDENTIALS,
|
||||
onError(SipErrorCode.INVALID_CREDENTIALS,
|
||||
"incorrect username or password");
|
||||
}
|
||||
return true;
|
||||
@@ -914,6 +960,7 @@ class SipSessionGroup implements SipListener {
|
||||
// response.
|
||||
mSipHelper.sendCancel(mClientTransaction);
|
||||
mState = SipSessionState.OUTGOING_CALL_CANCELING;
|
||||
startSessionTimer(CANCEL_CALL_TIMER);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -926,9 +973,13 @@ class SipSessionGroup implements SipListener {
|
||||
Response response = event.getResponse();
|
||||
int statusCode = response.getStatusCode();
|
||||
if (expectResponse(Request.CANCEL, evt)) {
|
||||
if (statusCode == Response.OK) {
|
||||
// do nothing; wait for REQUEST_TERMINATED
|
||||
return true;
|
||||
switch (statusCode) {
|
||||
case Response.OK:
|
||||
// do nothing; wait for REQUEST_TERMINATED
|
||||
return true;
|
||||
case Response.REQUEST_TERMINATED:
|
||||
endCallNormally();
|
||||
return true;
|
||||
}
|
||||
} else if (expectResponse(Request.INVITE, evt)) {
|
||||
if (statusCode == Response.OK) {
|
||||
@@ -978,11 +1029,27 @@ class SipSessionGroup implements SipListener {
|
||||
mClientTransaction = mSipHelper.sendReinvite(mDialog,
|
||||
((MakeCallCommand) evt).getSessionDescription());
|
||||
mState = SipSessionState.OUTGOING_CALL;
|
||||
startSessionTimer(((MakeCallCommand) evt).getTimeout());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// timeout in seconds
|
||||
private void startSessionTimer(int timeout) {
|
||||
if (timeout > 0) {
|
||||
mTimer = new SessionTimer();
|
||||
mTimer.start(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelSessionTimer() {
|
||||
if (mTimer != null) {
|
||||
mTimer.cancel();
|
||||
mTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private String createErrorMessage(Response response) {
|
||||
return String.format(SERVER_ERROR_PREFIX + "%s (%d)",
|
||||
response.getReasonPhrase(), response.getStatusCode());
|
||||
@@ -991,15 +1058,10 @@ class SipSessionGroup implements SipListener {
|
||||
private void establishCall() {
|
||||
mState = SipSessionState.IN_CALL;
|
||||
mInCall = true;
|
||||
cancelSessionTimer();
|
||||
mProxy.onCallEstablished(this, mPeerSessionDescription);
|
||||
}
|
||||
|
||||
private void fallbackToPreviousInCall(Throwable exception) {
|
||||
exception = getRootCause(exception);
|
||||
fallbackToPreviousInCall(getErrorCode(exception),
|
||||
exception.toString());
|
||||
}
|
||||
|
||||
private void fallbackToPreviousInCall(SipErrorCode errorCode,
|
||||
String message) {
|
||||
mState = SipSessionState.IN_CALL;
|
||||
@@ -1022,6 +1084,7 @@ class SipSessionGroup implements SipListener {
|
||||
}
|
||||
|
||||
private void onError(SipErrorCode errorCode, String message) {
|
||||
cancelSessionTimer();
|
||||
switch (mState) {
|
||||
case REGISTERING:
|
||||
case DEREGISTERING:
|
||||
@@ -1255,11 +1318,18 @@ class SipSessionGroup implements SipListener {
|
||||
|
||||
private class MakeCallCommand extends EventObject {
|
||||
private String mSessionDescription;
|
||||
private int mTimeout; // in seconds
|
||||
|
||||
public MakeCallCommand(SipProfile peerProfile,
|
||||
String sessionDescription) {
|
||||
this(peerProfile, sessionDescription, -1);
|
||||
}
|
||||
|
||||
public MakeCallCommand(SipProfile peerProfile,
|
||||
String sessionDescription, int timeout) {
|
||||
super(peerProfile);
|
||||
mSessionDescription = sessionDescription;
|
||||
mTimeout = timeout;
|
||||
}
|
||||
|
||||
public SipProfile getPeerProfile() {
|
||||
@@ -1269,6 +1339,9 @@ class SipSessionGroup implements SipListener {
|
||||
public String getSessionDescription() {
|
||||
return mSessionDescription;
|
||||
}
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return mTimeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ import java.util.List;
|
||||
public class SipPhone extends SipPhoneBase {
|
||||
private static final String LOG_TAG = "SipPhone";
|
||||
private static final boolean LOCAL_DEBUG = true;
|
||||
private static final int SESSION_TIMEOUT = 8; // in seconds
|
||||
|
||||
// A call that is ringing or (call) waiting
|
||||
private SipCall ringingCall = new SipCall();
|
||||
@@ -675,7 +676,7 @@ public class SipPhone extends SipPhoneBase {
|
||||
|
||||
void acceptCall() throws CallStateException {
|
||||
try {
|
||||
mSipAudioCall.answerCall();
|
||||
mSipAudioCall.answerCall(SESSION_TIMEOUT);
|
||||
} catch (SipException e) {
|
||||
throw new CallStateException("acceptCall(): " + e);
|
||||
}
|
||||
@@ -693,7 +694,7 @@ public class SipPhone extends SipPhoneBase {
|
||||
void dial() throws SipException {
|
||||
setState(Call.State.DIALING);
|
||||
mSipAudioCall = mSipManager.makeAudioCall(mContext, mProfile,
|
||||
mPeer, null);
|
||||
mPeer, null, SESSION_TIMEOUT);
|
||||
mSipAudioCall.setRingbackToneEnabled(false);
|
||||
mSipAudioCall.setListener(mAdapter);
|
||||
}
|
||||
@@ -701,7 +702,7 @@ public class SipPhone extends SipPhoneBase {
|
||||
void hold() throws CallStateException {
|
||||
setState(Call.State.HOLDING);
|
||||
try {
|
||||
mSipAudioCall.holdCall();
|
||||
mSipAudioCall.holdCall(SESSION_TIMEOUT);
|
||||
} catch (SipException e) {
|
||||
throw new CallStateException("hold(): " + e);
|
||||
}
|
||||
@@ -711,7 +712,7 @@ public class SipPhone extends SipPhoneBase {
|
||||
mSipAudioCall.setAudioGroup(audioGroup);
|
||||
setState(Call.State.ACTIVE);
|
||||
try {
|
||||
mSipAudioCall.continueCall();
|
||||
mSipAudioCall.continueCall(SESSION_TIMEOUT);
|
||||
} catch (SipException e) {
|
||||
throw new CallStateException("unhold(): " + e);
|
||||
}
|
||||
|
||||
@@ -112,9 +112,11 @@ interface ISipSession {
|
||||
*
|
||||
* @param callee the SIP profile to make the call to
|
||||
* @param sessionDescription the session description of this call
|
||||
* @param timeout the session will be timed out if the call is not
|
||||
* established within {@code timeout} seconds
|
||||
* @see ISipSessionListener
|
||||
*/
|
||||
void makeCall(in SipProfile callee, String sessionDescription);
|
||||
void makeCall(in SipProfile callee, String sessionDescription, int timeout);
|
||||
|
||||
/**
|
||||
* Answers an incoming call with the specified session description. The
|
||||
@@ -122,8 +124,10 @@ interface ISipSession {
|
||||
* {@link SipSessionState#INCOMING_CALL}.
|
||||
*
|
||||
* @param sessionDescription the session description to answer this call
|
||||
* @param timeout the session will be timed out if the call is not
|
||||
* established within {@code timeout} seconds
|
||||
*/
|
||||
void answerCall(String sessionDescription);
|
||||
void answerCall(String sessionDescription, int timeout);
|
||||
|
||||
/**
|
||||
* Ends an established call, terminates an outgoing call or rejects an
|
||||
@@ -140,6 +144,8 @@ interface ISipSession {
|
||||
* to call when the session state is in {@link SipSessionState#IN_CALL}.
|
||||
*
|
||||
* @param sessionDescription the new session description
|
||||
* @param timeout the session will be timed out if the call is not
|
||||
* established within {@code timeout} seconds
|
||||
*/
|
||||
void changeCall(String sessionDescription);
|
||||
void changeCall(String sessionDescription, int timeout);
|
||||
}
|
||||
|
||||
@@ -158,12 +158,18 @@ public interface SipAudioCall {
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Initiates an audio call to the specified profile.
|
||||
* Initiates an audio call to the specified profile. The attempt will be
|
||||
* timed out if the call is not established within {@code timeout} seconds
|
||||
* and {@code Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
|
||||
* will be called.
|
||||
*
|
||||
* @param callee the SIP profile to make the call to
|
||||
* @param sipManager the {@link SipManager} object to help make call with
|
||||
* @param timeout the timeout value in seconds
|
||||
* @see Listener.onError
|
||||
*/
|
||||
void makeCall(SipProfile callee, SipManager sipManager) throws SipException;
|
||||
void makeCall(SipProfile callee, SipManager sipManager, int timeout)
|
||||
throws SipException;
|
||||
|
||||
/**
|
||||
* Attaches an incoming call to this call object.
|
||||
@@ -179,18 +185,38 @@ public interface SipAudioCall {
|
||||
|
||||
/**
|
||||
* Puts a call on hold. When succeeds, {@link Listener#onCallHeld} is
|
||||
* called.
|
||||
* called. The attempt will be timed out if the call is not established
|
||||
* within {@code timeout} seconds and
|
||||
* {@code Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
|
||||
* will be called.
|
||||
*
|
||||
* @param timeout the timeout value in seconds
|
||||
* @see Listener.onError
|
||||
*/
|
||||
void holdCall() throws SipException;
|
||||
void holdCall(int timeout) throws SipException;
|
||||
|
||||
/** Answers a call. */
|
||||
void answerCall() throws SipException;
|
||||
/**
|
||||
* Answers a call. The attempt will be timed out if the call is not
|
||||
* established within {@code timeout} seconds and
|
||||
* {@code Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
|
||||
* will be called.
|
||||
*
|
||||
* @param timeout the timeout value in seconds
|
||||
* @see Listener.onError
|
||||
*/
|
||||
void answerCall(int timeout) throws SipException;
|
||||
|
||||
/**
|
||||
* Continues a call that's on hold. When succeeds,
|
||||
* {@link Listener#onCallEstablished} is called.
|
||||
* {@link Listener#onCallEstablished} is called. The attempt will be timed
|
||||
* out if the call is not established within {@code timeout} seconds and
|
||||
* {@code Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
|
||||
* will be called.
|
||||
*
|
||||
* @param timeout the timeout value in seconds
|
||||
* @see Listener.onError
|
||||
*/
|
||||
void continueCall() throws SipException;
|
||||
void continueCall(int timeout) throws SipException;
|
||||
|
||||
/** Puts the device to speaker mode. */
|
||||
void setSpeakerMode(boolean speakerMode);
|
||||
|
||||
@@ -55,6 +55,7 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
||||
private static final boolean DONT_RELEASE_SOCKET = false;
|
||||
private static final String AUDIO = "audio";
|
||||
private static final int DTMF = 101;
|
||||
private static final int SESSION_TIMEOUT = 5; // in seconds
|
||||
|
||||
private Context mContext;
|
||||
private SipProfile mLocalProfile;
|
||||
@@ -144,12 +145,21 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
||||
if (closeRtp) stopCall(RELEASE_SOCKET);
|
||||
stopRingbackTone();
|
||||
stopRinging();
|
||||
mSipSession = null;
|
||||
|
||||
mInCall = false;
|
||||
mHold = false;
|
||||
mSessionId = -1L;
|
||||
mErrorCode = null;
|
||||
mErrorMessage = null;
|
||||
|
||||
if (mSipSession != null) {
|
||||
try {
|
||||
mSipSession.setListener(null);
|
||||
} catch (RemoteException e) {
|
||||
// don't care
|
||||
}
|
||||
mSipSession = null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized SipProfile getLocalProfile() {
|
||||
@@ -219,7 +229,7 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
||||
// session changing request
|
||||
try {
|
||||
mPeerSd = new SdpSessionDescription(sessionDescription);
|
||||
answerCall();
|
||||
answerCall(SESSION_TIMEOUT);
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "onRinging()", e);
|
||||
session.endCall();
|
||||
@@ -346,14 +356,15 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
||||
}
|
||||
|
||||
public synchronized void makeCall(SipProfile peerProfile,
|
||||
SipManager sipManager) throws SipException {
|
||||
SipManager sipManager, int timeout) throws SipException {
|
||||
try {
|
||||
mSipSession = sipManager.createSipSession(mLocalProfile, this);
|
||||
if (mSipSession == null) {
|
||||
throw new SipException(
|
||||
"Failed to create SipSession; network available?");
|
||||
}
|
||||
mSipSession.makeCall(peerProfile, createOfferSessionDescription());
|
||||
mSipSession.makeCall(peerProfile, createOfferSessionDescription(),
|
||||
timeout);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof SipException) {
|
||||
throw (SipException) e;
|
||||
@@ -376,10 +387,10 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void holdCall() throws SipException {
|
||||
public synchronized void holdCall(int timeout) throws SipException {
|
||||
if (mHold) return;
|
||||
try {
|
||||
mSipSession.changeCall(createHoldSessionDescription());
|
||||
mSipSession.changeCall(createHoldSessionDescription(), timeout);
|
||||
mHold = true;
|
||||
} catch (Throwable e) {
|
||||
throwSipException(e);
|
||||
@@ -389,21 +400,21 @@ public class SipAudioCallImpl extends SipSessionAdapter
|
||||
if (audioGroup != null) audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
|
||||
}
|
||||
|
||||
public synchronized void answerCall() throws SipException {
|
||||
public synchronized void answerCall(int timeout) throws SipException {
|
||||
try {
|
||||
stopRinging();
|
||||
mSipSession.answerCall(createAnswerSessionDescription());
|
||||
mSipSession.answerCall(createAnswerSessionDescription(), timeout);
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "answerCall()", e);
|
||||
throwSipException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void continueCall() throws SipException {
|
||||
public synchronized void continueCall(int timeout) throws SipException {
|
||||
if (!mHold) return;
|
||||
try {
|
||||
mHold = false;
|
||||
mSipSession.changeCall(createContinueSessionDescription());
|
||||
mSipSession.changeCall(createContinueSessionDescription(), timeout);
|
||||
} catch (Throwable e) {
|
||||
throwSipException(e);
|
||||
}
|
||||
|
||||
@@ -218,44 +218,55 @@ public class SipManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SipAudioCall} to make a call.
|
||||
* Creates a {@link SipAudioCall} to make a call. The attempt will be timed
|
||||
* out if the call is not established within {@code timeout} seconds and
|
||||
* {@code SipAudioCall.Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
|
||||
* will be called.
|
||||
*
|
||||
* @param context context to create a {@link SipAudioCall} object
|
||||
* @param localProfile the SIP profile to make the call from
|
||||
* @param peerProfile the SIP profile to make the call to
|
||||
* @param listener to listen to the call events from {@link SipAudioCall};
|
||||
* can be null
|
||||
* @param timeout the timeout value in seconds
|
||||
* @return a {@link SipAudioCall} object
|
||||
* @throws SipException if calling the SIP service results in an error
|
||||
* @see SipAudioCall.Listener.onError
|
||||
*/
|
||||
public SipAudioCall makeAudioCall(Context context, SipProfile localProfile,
|
||||
SipProfile peerProfile, SipAudioCall.Listener listener)
|
||||
SipProfile peerProfile, SipAudioCall.Listener listener, int timeout)
|
||||
throws SipException {
|
||||
SipAudioCall call = new SipAudioCallImpl(context, localProfile);
|
||||
call.setListener(listener);
|
||||
call.makeCall(peerProfile, this);
|
||||
call.makeCall(peerProfile, this, timeout);
|
||||
return call;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SipAudioCall} to make a call. To use this method, one
|
||||
* must call {@link #open(SipProfile)} first.
|
||||
* must call {@link #open(SipProfile)} first. The attempt will be timed out
|
||||
* if the call is not established within {@code timeout} seconds and
|
||||
* {@code SipAudioCall.Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
|
||||
* will be called.
|
||||
*
|
||||
* @param context context to create a {@link SipAudioCall} object
|
||||
* @param localProfileUri URI of the SIP profile to make the call from
|
||||
* @param peerProfileUri URI of the SIP profile to make the call to
|
||||
* @param listener to listen to the call events from {@link SipAudioCall};
|
||||
* can be null
|
||||
* @param timeout the timeout value in seconds
|
||||
* @return a {@link SipAudioCall} object
|
||||
* @throws SipException if calling the SIP service results in an error
|
||||
* @see SipAudioCall.Listener.onError
|
||||
*/
|
||||
public SipAudioCall makeAudioCall(Context context, String localProfileUri,
|
||||
String peerProfileUri, SipAudioCall.Listener listener)
|
||||
String peerProfileUri, SipAudioCall.Listener listener, int timeout)
|
||||
throws SipException {
|
||||
try {
|
||||
return makeAudioCall(context,
|
||||
new SipProfile.Builder(localProfileUri).build(),
|
||||
new SipProfile.Builder(peerProfileUri).build(), listener);
|
||||
new SipProfile.Builder(peerProfileUri).build(), listener,
|
||||
timeout);
|
||||
} catch (ParseException e) {
|
||||
throw new SipException("build SipProfile", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user