From c72a86a0a4ff4c9116ed25034f3ffba57135d054 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 14 Nov 2023 08:57:22 +0100 Subject: [PATCH] add timeout to ICE gathering --- .../xmpp/jingle/JingleRtpConnection.java | 6 +-- .../xmpp/jingle/WebRTCWrapper.java | 51 +++++++++++++------ 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index d7cb77de3..a7d781840 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -1528,11 +1528,10 @@ public class JingleRtpConnection extends AbstractJingleConnection + candidates.size() + " candidates in session accept"); sendSessionAccept(outgoingContentMap.withCandidates(candidates)); - webRTCWrapper.resetPendingCandidates(); } else { sendSessionAccept(outgoingContentMap); - webRTCWrapper.setIsReadyToReceiveIceCandidates(true); } + webRTCWrapper.setIsReadyToReceiveIceCandidates(true); } @Override @@ -1994,11 +1993,10 @@ public class JingleRtpConnection extends AbstractJingleConnection + " candidates in session initiate"); sendSessionInitiate( outgoingContentMap.withCandidates(candidates), targetState); - webRTCWrapper.resetPendingCandidates(); } else { sendSessionInitiate(outgoingContentMap, targetState); - webRTCWrapper.setIsReadyToReceiveIceCandidates(true); } + webRTCWrapper.setIsReadyToReceiveIceCandidates(true); } @Override diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java index e09d7d242..2e53e4252 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java @@ -44,6 +44,8 @@ import java.util.Queue; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.Nonnull; @@ -456,11 +458,6 @@ public class WebRTCWrapper { "setIsReadyToReceiveCandidates(" + ready + ") was=" + was + " is=" + is); } - public void resetPendingCandidates() { - this.readyToReceivedIceCandidates.set(true); - this.iceCandidates.clear(); - } - synchronized void close() { final PeerConnection peerConnection = this.peerConnection; final PeerConnectionFactory peerConnectionFactory = this.peerConnectionFactory; @@ -579,7 +576,8 @@ public class WebRTCWrapper { throw new IllegalStateException("Local video track does not exist"); } - synchronized ListenableFuture setLocalDescription(final boolean waitForCandidates) { + synchronized ListenableFuture setLocalDescription( + final boolean waitForCandidates) { this.setIsReadyToReceiveIceCandidates(false); return Futures.transformAsync( getPeerConnectionFuture(), @@ -593,16 +591,20 @@ public class WebRTCWrapper { new SetSdpObserver() { @Override public void onSetSuccess() { - final var delay = - waitForCandidates - ? iceGatheringComplete - : Futures.immediateVoidFuture(); - final var delayedSessionDescription = - Futures.transformAsync( - delay, - v -> getLocalDescriptionFuture(), - MoreExecutors.directExecutor()); - future.setFuture(delayedSessionDescription); + if (waitForCandidates) { + final var delay = getIceGatheringCompleteOrTimeout(); + final var delayedSessionDescription = + Futures.transformAsync( + delay, + v -> { + iceCandidates.clear(); + return getLocalDescriptionFuture(); + }, + MoreExecutors.directExecutor()); + future.setFuture(delayedSessionDescription); + } else { + future.setFuture(getLocalDescriptionFuture()); + } } @Override @@ -616,6 +618,23 @@ public class WebRTCWrapper { MoreExecutors.directExecutor()); } + private ListenableFuture getIceGatheringCompleteOrTimeout() { + return Futures.catching( + Futures.withTimeout( + iceGatheringComplete, + 2, + TimeUnit.SECONDS, + JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE), + TimeoutException.class, + ex -> { + Log.d( + EXTENDED_LOGGING_TAG, + "timeout while waiting for ICE gathering to complete"); + return null; + }, + MoreExecutors.directExecutor()); + } + private ListenableFuture getLocalDescriptionFuture() { return Futures.submit( () -> {