Detailed changes
@@ -2,13 +2,13 @@ package eu.siacs.conversations.xmpp.jingle;
import im.conversations.android.xmpp.model.disco.external.Services;
import im.conversations.android.xmpp.model.stanza.Iq;
+import java.util.Collection;
import java.util.Collections;
-import java.util.Set;
import org.webrtc.PeerConnection;
public final class IceServers {
- public static Set<PeerConnection.IceServer> parse(final Iq response) {
+ public static Collection<PeerConnection.IceServer> parse(final Iq response) {
if (response.getType() != Iq.Type.RESULT) {
return Collections.emptySet();
}
@@ -1340,7 +1340,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
private synchronized void sendSessionAccept(
final Set<Media> media,
final SessionDescription offer,
- final Set<PeerConnection.IceServer> iceServers) {
+ final Collection<PeerConnection.IceServer> iceServers) {
if (isTerminated()) {
Log.w(
Config.LOGTAG,
@@ -1824,7 +1824,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
private synchronized void sendSessionInitiate(
final Set<Media> media,
final State targetState,
- final Set<PeerConnection.IceServer> iceServers) {
+ final Collection<PeerConnection.IceServer> iceServers) {
if (isTerminated()) {
Log.w(
Config.LOGTAG,
@@ -2321,7 +2321,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
private void setupWebRTC(
final Set<Media> media,
- final Set<PeerConnection.IceServer> iceServers,
+ final Collection<PeerConnection.IceServer> iceServers,
final boolean trickle)
throws WebRTCWrapper.InitializationException {
this.jingleConnectionManager.ensureConnectionIsRegistered(this);
@@ -2957,6 +2957,6 @@ public class JingleRtpConnection extends AbstractJingleConnection
}
private interface OnIceServersDiscovered {
- void onIceServersDiscovered(Set<PeerConnection.IceServer> iceServers);
+ void onIceServersDiscovered(Collection<PeerConnection.IceServer> iceServers);
}
}
@@ -13,6 +13,7 @@ import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.services.XmppConnectionService;
+import java.util.Collection;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
@@ -230,7 +231,7 @@ public class WebRTCWrapper {
synchronized void initializePeerConnection(
final Set<Media> media,
- final Set<PeerConnection.IceServer> iceServers,
+ final Collection<PeerConnection.IceServer> iceServers,
final boolean trickle)
throws InitializationException {
Preconditions.checkState(this.eglBase != null);
@@ -373,7 +374,7 @@ public class WebRTCWrapper {
}
public static PeerConnection.RTCConfiguration buildConfiguration(
- final Set<PeerConnection.IceServer> iceServers, final boolean trickle) {
+ final Collection<PeerConnection.IceServer> iceServers, final boolean trickle) {
final PeerConnection.RTCConfiguration rtcConfig =
new PeerConnection.RTCConfiguration(ImmutableList.copyOf(iceServers));
rtcConfig.tcpCandidatePolicy =
@@ -749,7 +750,7 @@ public class WebRTCWrapper {
}
}
- static class InitializationException extends Exception {
+ public static class InitializationException extends Exception {
private InitializationException(final String message, final Throwable throwable) {
super(message, throwable);
@@ -30,11 +30,11 @@ import java.io.PipedOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
+import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
-import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@@ -224,12 +224,12 @@ public class WebRTCDataChannelTransport implements Transport {
}
}
- private ListenableFuture<Set<PeerConnection.IceServer>> getIceServers() {
+ private ListenableFuture<Collection<PeerConnection.IceServer>> getIceServers() {
if (Config.DISABLE_PROXY_LOOKUP) {
return Futures.immediateFuture(Collections.emptySet());
}
if (xmppConnection.getFeatures().externalServiceDiscovery()) {
- final SettableFuture<Set<PeerConnection.IceServer>> iceServerFuture =
+ final SettableFuture<Collection<PeerConnection.IceServer>> iceServerFuture =
SettableFuture.create();
final Iq request = new Iq(Iq.Type.GET);
request.setTo(this.account.getDomain());
@@ -254,7 +254,7 @@ public class WebRTCDataChannelTransport implements Transport {
}
private PeerConnection createPeerConnection(
- final Set<PeerConnection.IceServer> iceServers, final boolean trickle) {
+ final Collection<PeerConnection.IceServer> iceServers, final boolean trickle) {
final PeerConnection.RTCConfiguration rtcConfig = buildConfiguration(iceServers, trickle);
final PeerConnection peerConnection =
requirePeerConnectionFactory()
@@ -1,7 +1,12 @@
package im.conversations.android.xmpp.model.disco.external;
import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.base.Objects;
import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import eu.siacs.conversations.Config;
@@ -10,7 +15,6 @@ import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xmpp.model.Extension;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Set;
import org.webrtc.PeerConnection;
@XmlElement
@@ -24,8 +28,8 @@ public class Services extends Extension {
return this.getExtensions(Service.class);
}
- public Set<PeerConnection.IceServer> getIceServers() {
- final var builder = new ImmutableSet.Builder<PeerConnection.IceServer>();
+ public Collection<PeerConnection.IceServer> getIceServers() {
+ final var builder = new ImmutableSet.Builder<IceServerWrapper>();
for (final var service : this.getServices()) {
final String type = service.getAttribute("type");
final String host = service.getAttribute("host");
@@ -70,8 +74,7 @@ public class Services extends Extension {
iceServerBuilder.setPassword(password);
} else if (Arrays.asList("turn", "turns").contains(type)) {
// The WebRTC spec requires throwing an
- // InvalidAccessError when username (from libwebrtc
- // source coder)
+ // InvalidAccessError on empty username or password
// https://chromium.googlesource.com/external/webrtc/+/master/pc/ice_server_parsing.cc
Log.w(
Config.LOGTAG,
@@ -82,11 +85,42 @@ public class Services extends Extension {
+ " without username and password");
continue;
}
- final PeerConnection.IceServer iceServer = iceServerBuilder.createIceServer();
+ final var iceServer = new IceServerWrapper(iceServerBuilder.createIceServer());
Log.w(Config.LOGTAG, "discovered ICE Server: " + iceServer);
builder.add(iceServer);
}
}
- return builder.build();
+ final var set = builder.build();
+ Log.d(Config.LOGTAG, "discovered " + set.size() + " ice servers");
+ return Collections2.transform(set, i -> i.iceServer);
+ }
+
+ private static class IceServerWrapper {
+
+ private final PeerConnection.IceServer iceServer;
+
+ private IceServerWrapper(final PeerConnection.IceServer iceServer) {
+ this.iceServer = iceServer;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof IceServerWrapper that)) return false;
+ return Objects.equal(iceServer.urls, that.iceServer.urls)
+ && Objects.equal(iceServer.username, that.iceServer.username)
+ && Objects.equal(iceServer.password, that.iceServer.password);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(iceServer.urls, iceServer.urls, iceServer.password);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ return this.iceServer.toString();
+ }
}
}