synchronize setDescription calls

This commit is contained in:
Daniel Gultsch 2021-11-16 15:17:12 +01:00
parent 297a843b9c
commit abb671616c
3 changed files with 34 additions and 30 deletions

View file

@ -54,7 +54,6 @@ import javax.net.ssl.X509TrustManager;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.DomainHostnameVerifier;
import eu.siacs.conversations.crypto.XmppDomainVerifier;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.sasl.Anonymous;

View file

@ -311,7 +311,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
restartContentMap = existing.modifiedCredentials(newCredentials, IceUdpTransportInfo.Setup.ACTPASS);
} else {
final IceUdpTransportInfo.Setup setup = getPeerDtlsSetup();
Log.d(Config.LOGTAG, "received confirmation of ICE restart" + newCredentials.values()+" peer_setup="+setup);
Log.d(Config.LOGTAG, "received confirmation of ICE restart" + newCredentials.values() + " peer_setup=" + setup);
// DTLS setup attribute needs to be rewritten to reflect current peer state
// https://groups.google.com/g/discuss-webrtc/c/DfpIMwvUfeM
restartContentMap = existing.modifiedCredentials(newCredentials, setup);
@ -319,12 +319,18 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
if (applyIceRestart(jinglePacket, restartContentMap, isOffer)) {
return isOffer;
} else {
Log.d(Config.LOGTAG,"ignored ice restart. offer="+isOffer);
respondWithTieBreak(jinglePacket);
return true;
}
} catch (final Exception exception) {
respondOk(jinglePacket);
final Throwable rootCause = Throwables.getRootCause(exception);
if (rootCause instanceof WebRTCWrapper.PeerConnectionNotInitialized) {
Log.d(Config.LOGTAG,"ignoring PeerConnectionNotInitialized");
//TODO dont respond OK but respond with out-of-order
return true;
}
Log.d(Config.LOGTAG, "failure to apply ICE restart", rootCause);
webRTCWrapper.close();
sendSessionTerminate(Reason.ofThrowable(rootCause), rootCause.getMessage());
@ -1466,21 +1472,18 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
}
final boolean neverConnected = !this.stateHistory.contains(PeerConnection.PeerConnectionState.CONNECTED);
final boolean failedOrDisconnected = Arrays.asList(
PeerConnection.PeerConnectionState.FAILED,
PeerConnection.PeerConnectionState.DISCONNECTED
).contains(newState);
if (neverConnected && failedOrDisconnected) {
if (isTerminated()) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not sending session-terminate after connectivity error because session is already in state " + this.state);
if (newState == PeerConnection.PeerConnectionState.FAILED) {
if (neverConnected) {
if (isTerminated()) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not sending session-terminate after connectivity error because session is already in state " + this.state);
return;
}
webRTCWrapper.execute(this::closeWebRTCSessionAfterFailedConnection);
return;
} else {
webRTCWrapper.restartIce();
}
webRTCWrapper.execute(this::closeWebRTCSessionAfterFailedConnection);
} else if (newState == PeerConnection.PeerConnectionState.FAILED) {
Log.d(Config.LOGTAG, "attempting to restart ICE");
webRTCWrapper.restartIce();
}
updateEndUserState();
}
@ -1491,6 +1494,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
}
private void initiateIceRestart() {
this.stateHistory.clear();
this.webRTCWrapper.setIsReadyToReceiveIceCandidates(false);
final SessionDescription sessionDescription;
try {

View file

@ -431,7 +431,7 @@ public class WebRTCWrapper {
videoTrack.setEnabled(enabled);
}
ListenableFuture<SessionDescription> setLocalDescription() {
synchronized ListenableFuture<SessionDescription> setLocalDescription() {
return Futures.transformAsync(getPeerConnectionFuture(), peerConnection -> {
final SettableFuture<SessionDescription> future = SettableFuture.create();
peerConnection.setLocalDescription(new SetSdpObserver() {
@ -458,7 +458,7 @@ public class WebRTCWrapper {
}
}
ListenableFuture<Void> setRemoteDescription(final SessionDescription sessionDescription) {
synchronized ListenableFuture<Void> setRemoteDescription(final SessionDescription sessionDescription) {
Log.d(EXTENDED_LOGGING_TAG, "setting remote description:");
logDescription(sessionDescription);
return Futures.transformAsync(getPeerConnectionFuture(), peerConnection -> {
@ -482,12 +482,20 @@ public class WebRTCWrapper {
private ListenableFuture<PeerConnection> getPeerConnectionFuture() {
final PeerConnection peerConnection = this.peerConnection;
if (peerConnection == null) {
return Futures.immediateFailedFuture(new IllegalStateException("initialize PeerConnection first"));
return Futures.immediateFailedFuture(new PeerConnectionNotInitialized());
} else {
return Futures.immediateFuture(peerConnection);
}
}
private PeerConnection requirePeerConnection() {
final PeerConnection peerConnection = this.peerConnection;
if (peerConnection == null) {
throw new PeerConnectionNotInitialized();
}
return peerConnection;
}
void addIceCandidate(IceCandidate iceCandidate) {
requirePeerConnection().addIceCandidate(iceCandidate);
}
@ -512,10 +520,15 @@ public class WebRTCWrapper {
}
}
public PeerConnection.PeerConnectionState getState() {
PeerConnection.PeerConnectionState getState() {
return requirePeerConnection().connectionState();
}
public PeerConnection.SignalingState getSignalingState() {
return requirePeerConnection().signalingState();
}
EglBase.Context getEglBaseContext() {
return this.eglBase.getEglBaseContext();
}
@ -528,14 +541,6 @@ public class WebRTCWrapper {
return Optional.fromNullable(this.remoteVideoTrack);
}
private PeerConnection requirePeerConnection() {
final PeerConnection peerConnection = this.peerConnection;
if (peerConnection == null) {
throw new PeerConnectionNotInitialized();
}
return peerConnection;
}
private Context requireContext() {
final Context context = this.context;
if (context == null) {
@ -552,10 +557,6 @@ public class WebRTCWrapper {
executorService.execute(command);
}
public PeerConnection.SignalingState getSignalingState() {
return requirePeerConnection().signalingState();
}
public interface EventCallback {
void onIceCandidate(IceCandidate iceCandidate);