diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 05f678829..63b4a1537 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -291,8 +291,15 @@ public class CallActivity extends CallBaseActivity { private SignalingMessageReceiver.OfferMessageListener offerMessageListener = new SignalingMessageReceiver.OfferMessageListener() { @Override - public void onOffer(String sessionId, String roomType, String sdp, String nick) { - getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, roomType, false); + public void onOffer(String sessionId, String roomType, String sid, String sdp, String nick) { + // If there is already a peer connection but a new offer is received with a different sid the existing + // peer connection is stale, so it needs to be removed and a new one created instead. + PeerConnectionWrapper peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(sessionId, roomType); + if (peerConnectionWrapper != null && sid != null && !sid.equals(peerConnectionWrapper.getSid())) { + endPeerConnection(sessionId, roomType); + } + + getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, roomType, sid, false); } }; @@ -1850,7 +1857,7 @@ public class CallActivity extends CallBaseActivity { if (hasMCU) { // Ensure that own publishing peer is set up. - getOrCreatePeerConnectionWrapperForSessionIdAndType(webSocketClient.getSessionId(), VIDEO_STREAM_TYPE_VIDEO, true); + getOrCreatePeerConnectionWrapperForSessionIdAndType(webSocketClient.getSessionId(), VIDEO_STREAM_TYPE_VIDEO, null, true); } boolean selfJoined = false; @@ -1894,7 +1901,7 @@ public class CallActivity extends CallBaseActivity { // higher session ID but is not publishing media. if ((hasMCU && participantHasAudioOrVideo) || (!hasMCU && selfParticipantHasAudioOrVideo && (!participantHasAudioOrVideo || sessionId.compareTo(currentSessionId) < 0))) { - getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false); + getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, null, false); } } @@ -1934,6 +1941,7 @@ public class CallActivity extends CallBaseActivity { private PeerConnectionWrapper getOrCreatePeerConnectionWrapperForSessionIdAndType(String sessionId, String type, + String sid, boolean publisher) { PeerConnectionWrapper peerConnectionWrapper; if ((peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(sessionId, type)) != null) { @@ -1952,6 +1960,7 @@ public class CallActivity extends CallBaseActivity { iceServers, sdpConstraintsForMCU, sessionId, + sid, callSession, localStream, true, @@ -1965,6 +1974,7 @@ public class CallActivity extends CallBaseActivity { iceServers, sdpConstraints, sessionId, + sid, callSession, null, false, @@ -1978,6 +1988,7 @@ public class CallActivity extends CallBaseActivity { iceServers, sdpConstraints, sessionId, + sid, callSession, localStream, false, @@ -1990,6 +2001,7 @@ public class CallActivity extends CallBaseActivity { iceServers, sdpConstraints, sessionId, + sid, callSession, null, false, @@ -2018,10 +2030,10 @@ public class CallActivity extends CallBaseActivity { OfferAnswerNickProvider offerAnswerNickProvider = offerAnswerNickProviders.get(sessionId); if ("screen".equals(type)) { signalingMessageReceiver.addListener(offerAnswerNickProvider.getScreenWebRtcMessageListener(), - sessionId, "screen"); + sessionId, "screen", peerConnectionWrapper.getSid()); } else { signalingMessageReceiver.addListener(offerAnswerNickProvider.getVideoWebRtcMessageListener(), - sessionId, "video"); + sessionId, "video", peerConnectionWrapper.getSid()); } } } diff --git a/app/src/main/java/com/nextcloud/talk/signaling/OfferMessageNotifier.java b/app/src/main/java/com/nextcloud/talk/signaling/OfferMessageNotifier.java index e0c3842cd..adbefa2c9 100644 --- a/app/src/main/java/com/nextcloud/talk/signaling/OfferMessageNotifier.java +++ b/app/src/main/java/com/nextcloud/talk/signaling/OfferMessageNotifier.java @@ -45,9 +45,9 @@ class OfferMessageNotifier { offerMessageListeners.remove(listener); } - public synchronized void notifyOffer(String sessionId, String roomType, String sdp, String nick) { + public synchronized void notifyOffer(String sessionId, String roomType, String sid, String sdp, String nick) { for (SignalingMessageReceiver.OfferMessageListener listener : new ArrayList<>(offerMessageListeners)) { - listener.onOffer(sessionId, roomType, sdp, nick); + listener.onOffer(sessionId, roomType, sid, sdp, nick); } } } diff --git a/app/src/main/java/com/nextcloud/talk/signaling/SignalingMessageReceiver.java b/app/src/main/java/com/nextcloud/talk/signaling/SignalingMessageReceiver.java index 161dae555..6f586c020 100644 --- a/app/src/main/java/com/nextcloud/talk/signaling/SignalingMessageReceiver.java +++ b/app/src/main/java/com/nextcloud/talk/signaling/SignalingMessageReceiver.java @@ -141,7 +141,7 @@ public abstract class SignalingMessageReceiver { * When an offer is received all OfferMessageListeners are notified before any WebRtcMessageListener is notified. */ public interface OfferMessageListener { - void onOffer(String sessionId, String roomType, String sdp, String nick); + void onOffer(String sessionId, String roomType, String sid, String sdp, String nick); } /** @@ -218,12 +218,19 @@ public abstract class SignalingMessageReceiver { * A listener is expected to be added only once. If the same listener is added again it will no longer be notified * for the messages from the previous session ID or room type. * + * At any given time there will be just one peer connection with the same session ID and room type. The peer + * connection ID is an additional guarantee to ensure that both ends are using the same peer connection. However, + * in some cases (older external signaling server or app versions) the WebRTC messages may not contain a peer + * connection ID. In those cases the listener will still receive the messages, even if it was registered against + * a specific peer connection ID. + * * @param listener the WebRtcMessageListener * @param sessionId the ID of the session that messages come from * @param roomType the room type that messages come from + * @param sid the ID of the peer connection */ - public void addListener(WebRtcMessageListener listener, String sessionId, String roomType) { - webRtcMessageNotifier.addListener(listener, sessionId, roomType); + public void addListener(WebRtcMessageListener listener, String sessionId, String roomType, String sid) { + webRtcMessageNotifier.addListener(listener, sessionId, roomType, sid); } public void removeListener(WebRtcMessageListener listener) { @@ -452,6 +459,8 @@ public abstract class SignalingMessageReceiver { return; } + String sid = signalingMessage.getSid(); + if ("offer".equals(type)) { // Message schema (external signaling server): // { @@ -504,8 +513,8 @@ public abstract class SignalingMessageReceiver { // although extremely unlikely, that the WebRtcMessageListeners for the second offer are notified before the // WebRtcMessageListeners for the first offer. This should not be a problem, though, so for simplicity // the statements are not synchronized. - offerMessageNotifier.notifyOffer(sessionId, roomType, sdp, nick); - webRtcMessageNotifier.notifyOffer(sessionId, roomType, sdp, nick); + offerMessageNotifier.notifyOffer(sessionId, roomType, sid, sdp, nick); + webRtcMessageNotifier.notifyOffer(sessionId, roomType, sid, sdp, nick); return; } @@ -522,7 +531,7 @@ public abstract class SignalingMessageReceiver { String sdp = payload.getSdp(); String nick = payload.getNick(); - webRtcMessageNotifier.notifyAnswer(sessionId, roomType, sdp, nick); + webRtcMessageNotifier.notifyAnswer(sessionId, roomType, sid, sdp, nick); return; } @@ -585,6 +594,7 @@ public abstract class SignalingMessageReceiver { webRtcMessageNotifier.notifyCandidate(sessionId, roomType, + sid, ncIceCandidate.getSdpMid(), ncIceCandidate.getSdpMLineIndex(), ncIceCandidate.getCandidate()); @@ -593,7 +603,7 @@ public abstract class SignalingMessageReceiver { } if ("endOfCandidates".equals(type)) { - webRtcMessageNotifier.notifyEndOfCandidates(sessionId, roomType); + webRtcMessageNotifier.notifyEndOfCandidates(sessionId, roomType, sid); return; } diff --git a/app/src/main/java/com/nextcloud/talk/signaling/WebRtcMessageNotifier.java b/app/src/main/java/com/nextcloud/talk/signaling/WebRtcMessageNotifier.java index 9dbe6cb38..768e6c371 100644 --- a/app/src/main/java/com/nextcloud/talk/signaling/WebRtcMessageNotifier.java +++ b/app/src/main/java/com/nextcloud/talk/signaling/WebRtcMessageNotifier.java @@ -38,19 +38,22 @@ class WebRtcMessageNotifier { public final SignalingMessageReceiver.WebRtcMessageListener listener; public final String sessionId; public final String roomType; + public final String sid; private WebRtcMessageListenerFrom(SignalingMessageReceiver.WebRtcMessageListener listener, String sessionId, - String roomType) { + String roomType, + String sid) { this.listener = listener; this.sessionId = sessionId; this.roomType = roomType; + this.sid = sid; } } private final List webRtcMessageListenersFrom = new ArrayList<>(); - public synchronized void addListener(SignalingMessageReceiver.WebRtcMessageListener listener, String sessionId, String roomType) { + public synchronized void addListener(SignalingMessageReceiver.WebRtcMessageListener listener, String sessionId, String roomType, String sid) { if (listener == null) { throw new IllegalArgumentException("WebRtcMessageListener can not be null"); } @@ -63,9 +66,13 @@ class WebRtcMessageNotifier { throw new IllegalArgumentException("roomType can not be null"); } + if (sid == null) { + throw new IllegalArgumentException("sid can not be null"); + } + removeListener(listener); - webRtcMessageListenersFrom.add(new WebRtcMessageListenerFrom(listener, sessionId, roomType)); + webRtcMessageListenersFrom.add(new WebRtcMessageListenerFrom(listener, sessionId, roomType, sid)); } public synchronized void removeListener(SignalingMessageReceiver.WebRtcMessageListener listener) { @@ -81,12 +88,13 @@ class WebRtcMessageNotifier { } } - private List getListenersFor(String sessionId, String roomType) { + private List getListenersFor(String sessionId, String roomType, String sid) { List webRtcMessageListeners = new ArrayList<>(webRtcMessageListenersFrom.size()); for (WebRtcMessageListenerFrom listenerFrom : webRtcMessageListenersFrom) { - if (listenerFrom.sessionId.equals(sessionId) && listenerFrom.roomType.equals(roomType)) { + if (listenerFrom.sessionId.equals(sessionId) && listenerFrom.roomType.equals(roomType) && + (sid == null || listenerFrom.sid.equals(sid))) { webRtcMessageListeners.add(listenerFrom.listener); } } @@ -94,26 +102,26 @@ class WebRtcMessageNotifier { return webRtcMessageListeners; } - public synchronized void notifyOffer(String sessionId, String roomType, String sdp, String nick) { - for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType)) { + public synchronized void notifyOffer(String sessionId, String roomType, String sid, String sdp, String nick) { + for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType, sid)) { listener.onOffer(sdp, nick); } } - public synchronized void notifyAnswer(String sessionId, String roomType, String sdp, String nick) { - for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType)) { + public synchronized void notifyAnswer(String sessionId, String roomType, String sid, String sdp, String nick) { + for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType, sid)) { listener.onAnswer(sdp, nick); } } - public synchronized void notifyCandidate(String sessionId, String roomType, String sdpMid, int sdpMLineIndex, String sdp) { - for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType)) { + public synchronized void notifyCandidate(String sessionId, String roomType, String sid, String sdpMid, int sdpMLineIndex, String sdp) { + for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType, sid)) { listener.onCandidate(sdpMid, sdpMLineIndex, sdp); } } - public synchronized void notifyEndOfCandidates(String sessionId, String roomType) { - for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType)) { + public synchronized void notifyEndOfCandidates(String sessionId, String roomType, String sid) { + for (SignalingMessageReceiver.WebRtcMessageListener listener : getListenersFor(sessionId, roomType, sid)) { listener.onEndOfCandidates(); } } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java index d040d033c..1da81d7bc 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -111,6 +111,7 @@ public class PeerConnectionWrapper { private List iceCandidates = new ArrayList<>(); private PeerConnection peerConnection; private String sessionId; + private final String sid; private final MediaConstraints mediaConstraints; private DataChannel dataChannel; private final MagicSdpObserver magicSdpObserver; @@ -130,7 +131,8 @@ public class PeerConnectionWrapper { public PeerConnectionWrapper(PeerConnectionFactory peerConnectionFactory, List iceServerList, MediaConstraints mediaConstraints, - String sessionId, String localSession, @Nullable MediaStream localStream, + String sessionId, @Nullable String sid, String localSession, + @Nullable MediaStream localStream, boolean isMCUPublisher, boolean hasMCU, String videoStreamType, SignalingMessageReceiver signalingMessageReceiver, SignalingMessageSender signalingMessageSender) { @@ -141,6 +143,7 @@ public class PeerConnectionWrapper { this.videoStreamType = videoStreamType; this.sessionId = sessionId; + this.sid = sid != null ? sid : Long.toString(System.currentTimeMillis()); this.mediaConstraints = mediaConstraints; magicSdpObserver = new MagicSdpObserver(); @@ -152,7 +155,7 @@ public class PeerConnectionWrapper { peerConnection = peerConnectionFactory.createPeerConnection(configuration, new MagicPeerConnectionObserver()); this.signalingMessageReceiver = signalingMessageReceiver; - this.signalingMessageReceiver.addListener(webRtcMessageListener, sessionId, videoStreamType); + this.signalingMessageReceiver.addListener(webRtcMessageListener, sessionId, videoStreamType, this.sid); this.signalingMessageSender = signalingMessageSender; @@ -174,7 +177,9 @@ public class PeerConnectionWrapper { dataChannel.registerObserver(new MagicDataChannelObserver()); if (isMCUPublisher) { peerConnection.createOffer(magicSdpObserver, mediaConstraints); - } else if (hasMCU && "video".equals(this.videoStreamType)) { + } else if (hasMCU && "video".equals(this.videoStreamType) && sid == null) { + // If no sid is provided during creation then the PeerConnectionWrapper is a dummy one that just + // requests an offer and then gets replaced with a new one once the offer with the sid is received. // If the connection type is "screen" the client sharing the screen will send an // offer; offers should be requested only for videos. // "to" property is not actually needed in the "requestoffer" signaling message, but it is used to @@ -285,6 +290,10 @@ public class PeerConnectionWrapper { return sessionId; } + public String getSid() { + return sid; + } + private void sendInitialMediaStatus() { if (localStream != null) { if (localStream.videoTracks.size() == 1 && localStream.videoTracks.get(0).enabled()) { @@ -318,6 +327,7 @@ public class PeerConnectionWrapper { NCSignalingMessage ncSignalingMessage = new NCSignalingMessage(); ncSignalingMessage.setTo(sessionId); ncSignalingMessage.setRoomType(videoStreamType); + ncSignalingMessage.setSid(sid); ncSignalingMessage.setType(type); return ncSignalingMessage; diff --git a/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverOfferTest.java b/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverOfferTest.java index 2163b6852..f6f5ee3e8 100644 --- a/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverOfferTest.java +++ b/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverOfferTest.java @@ -70,7 +70,28 @@ public class SignalingMessageReceiverOfferTest { signalingMessage.setPayload(messagePayload); signalingMessageReceiver.processSignalingMessage(signalingMessage); - verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSdp", null); + verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", null, "theSdp", null); + } + + @Test + public void testOfferMessageWithSid() { + SignalingMessageReceiver.OfferMessageListener mockedOfferMessageListener = + mock(SignalingMessageReceiver.OfferMessageListener.class); + + signalingMessageReceiver.addListener(mockedOfferMessageListener); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("offer"); + signalingMessage.setRoomType("theRoomType"); + NCMessagePayload messagePayload = new NCMessagePayload(); + messagePayload.setType("offer"); + messagePayload.setSdp("theSdp"); + signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", null); } @Test @@ -91,7 +112,29 @@ public class SignalingMessageReceiverOfferTest { signalingMessage.setPayload(messagePayload); signalingMessageReceiver.processSignalingMessage(signalingMessage); - verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", null, "theSdp", "theNick"); + } + + @Test + public void testOfferMessageWithSidAndNick() { + SignalingMessageReceiver.OfferMessageListener mockedOfferMessageListener = + mock(SignalingMessageReceiver.OfferMessageListener.class); + + signalingMessageReceiver.addListener(mockedOfferMessageListener); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("offer"); + signalingMessage.setRoomType("theRoomType"); + NCMessagePayload messagePayload = new NCMessagePayload(); + messagePayload.setType("offer"); + messagePayload.setSdp("theSdp"); + messagePayload.setNick("theNick"); + signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); } @Test @@ -139,10 +182,11 @@ public class SignalingMessageReceiverOfferTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); - verify(mockedOfferMessageListener1, only()).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); - verify(mockedOfferMessageListener3, only()).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + verify(mockedOfferMessageListener1, only()).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); + verify(mockedOfferMessageListener3, only()).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); verifyNoInteractions(mockedOfferMessageListener2); } @@ -163,9 +207,10 @@ public class SignalingMessageReceiverOfferTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); - verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); } @Test @@ -178,7 +223,7 @@ public class SignalingMessageReceiverOfferTest { doAnswer((invocation) -> { signalingMessageReceiver.addListener(mockedOfferMessageListener2); return null; - }).when(mockedOfferMessageListener1).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + }).when(mockedOfferMessageListener1).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); signalingMessageReceiver.addListener(mockedOfferMessageListener1); @@ -191,9 +236,10 @@ public class SignalingMessageReceiverOfferTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); - verify(mockedOfferMessageListener1, only()).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + verify(mockedOfferMessageListener1, only()).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); verifyNoInteractions(mockedOfferMessageListener2); } @@ -207,7 +253,7 @@ public class SignalingMessageReceiverOfferTest { doAnswer((invocation) -> { signalingMessageReceiver.removeListener(mockedOfferMessageListener2); return null; - }).when(mockedOfferMessageListener1).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + }).when(mockedOfferMessageListener1).onOffer("theSessionId", "theRoomType", "theSid", "theSdpd", "theNick"); signalingMessageReceiver.addListener(mockedOfferMessageListener1); signalingMessageReceiver.addListener(mockedOfferMessageListener2); @@ -221,11 +267,12 @@ public class SignalingMessageReceiverOfferTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); InOrder inOrder = inOrder(mockedOfferMessageListener1, mockedOfferMessageListener2); - inOrder.verify(mockedOfferMessageListener1).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); - inOrder.verify(mockedOfferMessageListener2).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + inOrder.verify(mockedOfferMessageListener1).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); + inOrder.verify(mockedOfferMessageListener2).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); } } diff --git a/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverTest.java b/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverTest.java index bf00a31c9..7eda12d98 100644 --- a/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverTest.java +++ b/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverTest.java @@ -53,7 +53,7 @@ public class SignalingMessageReceiverTest { mock(SignalingMessageReceiver.WebRtcMessageListener.class); signalingMessageReceiver.addListener(mockedOfferMessageListener); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -64,11 +64,12 @@ public class SignalingMessageReceiverTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); InOrder inOrder = inOrder(mockedOfferMessageListener, mockedWebRtcMessageListener); - inOrder.verify(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + inOrder.verify(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); inOrder.verify(mockedWebRtcMessageListener).onOffer("theSdp", "theNick"); } @@ -80,9 +81,9 @@ public class SignalingMessageReceiverTest { mock(SignalingMessageReceiver.WebRtcMessageListener.class); doAnswer((invocation) -> { - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); return null; - }).when(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + }).when(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); signalingMessageReceiver.addListener(mockedOfferMessageListener); @@ -95,11 +96,12 @@ public class SignalingMessageReceiverTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); InOrder inOrder = inOrder(mockedOfferMessageListener, mockedWebRtcMessageListener); - inOrder.verify(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + inOrder.verify(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); inOrder.verify(mockedWebRtcMessageListener).onOffer("theSdp", "theNick"); } @@ -113,10 +115,10 @@ public class SignalingMessageReceiverTest { doAnswer((invocation) -> { signalingMessageReceiver.removeListener(mockedWebRtcMessageListener); return null; - }).when(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + }).when(mockedOfferMessageListener).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); signalingMessageReceiver.addListener(mockedOfferMessageListener); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -127,9 +129,10 @@ public class SignalingMessageReceiverTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); - verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSdp", "theNick"); + verify(mockedOfferMessageListener, only()).onOffer("theSessionId", "theRoomType", "theSid", "theSdp", "theNick"); verifyNoInteractions(mockedWebRtcMessageListener); } } diff --git a/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverWebRtcTest.java b/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverWebRtcTest.java index da85f8493..47c92b0e3 100644 --- a/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverWebRtcTest.java +++ b/app/src/test/java/com/nextcloud/talk/signaling/SignalingMessageReceiverWebRtcTest.java @@ -50,7 +50,7 @@ public class SignalingMessageReceiverWebRtcTest { @Test public void testAddWebRtcMessageListenerWithNullListener() { Assert.assertThrows(IllegalArgumentException.class, () -> { - signalingMessageReceiver.addListener(null, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(null, "theSessionId", "theRoomType", "theSid"); }); } @@ -60,7 +60,7 @@ public class SignalingMessageReceiverWebRtcTest { mock(SignalingMessageReceiver.WebRtcMessageListener.class); Assert.assertThrows(IllegalArgumentException.class, () -> { - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, null, "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, null, "theRoomType", "theSid"); }); } @@ -70,7 +70,17 @@ public class SignalingMessageReceiverWebRtcTest { mock(SignalingMessageReceiver.WebRtcMessageListener.class); Assert.assertThrows(IllegalArgumentException.class, () -> { - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", null); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", null, "theSid"); + }); + } + + @Test + public void testAddWebRtcMessageListenerWithNullSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", null); }); } @@ -79,7 +89,28 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("offer"); + signalingMessage.setRoomType("theRoomType"); + NCMessagePayload messagePayload = new NCMessagePayload(); + messagePayload.setType("offer"); + messagePayload.setSdp("theSdp"); + signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedWebRtcMessageListener, only()).onOffer("theSdp", null); + } + + @Test + public void testWebRtcMessageOfferWithoutSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -99,7 +130,7 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -110,6 +141,7 @@ public class SignalingMessageReceiverWebRtcTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verify(mockedWebRtcMessageListener, only()).onOffer("theSdp", "theNick"); @@ -120,7 +152,28 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("answer"); + signalingMessage.setRoomType("theRoomType"); + NCMessagePayload messagePayload = new NCMessagePayload(); + messagePayload.setType("answer"); + messagePayload.setSdp("theSdp"); + signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedWebRtcMessageListener, only()).onAnswer("theSdp", null); + } + + @Test + public void testWebRtcMessageAnswerWithoutSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -140,7 +193,7 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -151,6 +204,7 @@ public class SignalingMessageReceiverWebRtcTest { messagePayload.setSdp("theSdp"); messagePayload.setNick("theNick"); signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verify(mockedWebRtcMessageListener, only()).onAnswer("theSdp", "theNick"); @@ -161,7 +215,31 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("candidate"); + signalingMessage.setRoomType("theRoomType"); + NCMessagePayload messagePayload = new NCMessagePayload(); + NCIceCandidate iceCandidate = new NCIceCandidate(); + iceCandidate.setSdpMid("theSdpMid"); + iceCandidate.setSdpMLineIndex(42); + iceCandidate.setCandidate("theSdp"); + messagePayload.setIceCandidate(iceCandidate); + signalingMessage.setPayload(messagePayload); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedWebRtcMessageListener, only()).onCandidate("theSdpMid", 42, "theSdp"); + } + + @Test + public void testWebRtcMessageCandidateWithoutSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -184,7 +262,24 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("endOfCandidates"); + signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedWebRtcMessageListener, only()).onEndOfCandidates(); + } + + @Test + public void testWebRtcMessageEndOfCandidatesWithoutSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -202,8 +297,29 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener2 = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType"); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType", "theSid"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType", "theSid"); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("endOfCandidates"); + signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedWebRtcMessageListener1, only()).onEndOfCandidates(); + verify(mockedWebRtcMessageListener2, only()).onEndOfCandidates(); + } + + @Test + public void testWebRtcMessageSeveralListenersSameFromDifferentSidWithoutSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener1 = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener2 = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType", "theSid"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType", "theSid2"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); @@ -220,12 +336,13 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("notMatchingSessionId"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verifyNoInteractions(mockedWebRtcMessageListener); @@ -236,12 +353,30 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("notMatchingRoomType"); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verifyNoInteractions(mockedWebRtcMessageListener); + } + + @Test + public void testWebRtcMessageNotMatchingSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("endOfCandidates"); + signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("notMatchingSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verifyNoInteractions(mockedWebRtcMessageListener); @@ -252,13 +387,14 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); signalingMessageReceiver.removeListener(mockedWebRtcMessageListener); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verifyNoInteractions(mockedWebRtcMessageListener); @@ -273,15 +409,16 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener3 = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType"); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType"); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener3, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType", "theSid"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType", "theSid"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener3, "theSessionId", "theRoomType", "theSid"); signalingMessageReceiver.removeListener(mockedWebRtcMessageListener2); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verify(mockedWebRtcMessageListener1, only()).onEndOfCandidates(); @@ -294,13 +431,14 @@ public class SignalingMessageReceiverWebRtcTest { SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = mock(SignalingMessageReceiver.WebRtcMessageListener.class); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType"); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId2", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId2", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verifyNoInteractions(mockedWebRtcMessageListener); @@ -308,6 +446,33 @@ public class SignalingMessageReceiverWebRtcTest { signalingMessage.setFrom("theSessionId2"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verify(mockedWebRtcMessageListener, only()).onEndOfCandidates(); + } + + @Test + public void testWebRtcMessageAfterAddingListenerAgainForSameFromDifferentSid() { + SignalingMessageReceiver.WebRtcMessageListener mockedWebRtcMessageListener = + mock(SignalingMessageReceiver.WebRtcMessageListener.class); + + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener, "theSessionId", "theRoomType", "theSid2"); + + NCSignalingMessage signalingMessage = new NCSignalingMessage(); + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("endOfCandidates"); + signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); + signalingMessageReceiver.processSignalingMessage(signalingMessage); + + verifyNoInteractions(mockedWebRtcMessageListener); + + signalingMessage.setFrom("theSessionId"); + signalingMessage.setType("endOfCandidates"); + signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid2"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verify(mockedWebRtcMessageListener, only()).onEndOfCandidates(); @@ -321,16 +486,17 @@ public class SignalingMessageReceiverWebRtcTest { mock(SignalingMessageReceiver.WebRtcMessageListener.class); doAnswer((invocation) -> { - signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType", "theSid"); return null; }).when(mockedWebRtcMessageListener1).onEndOfCandidates(); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); verify(mockedWebRtcMessageListener1, only()).onEndOfCandidates(); @@ -349,13 +515,14 @@ public class SignalingMessageReceiverWebRtcTest { return null; }).when(mockedWebRtcMessageListener1).onEndOfCandidates(); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType"); - signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener1, "theSessionId", "theRoomType", "theSid"); + signalingMessageReceiver.addListener(mockedWebRtcMessageListener2, "theSessionId", "theRoomType", "theSid"); NCSignalingMessage signalingMessage = new NCSignalingMessage(); signalingMessage.setFrom("theSessionId"); signalingMessage.setType("endOfCandidates"); signalingMessage.setRoomType("theRoomType"); + signalingMessage.setSid("theSid"); signalingMessageReceiver.processSignalingMessage(signalingMessage); InOrder inOrder = inOrder(mockedWebRtcMessageListener1, mockedWebRtcMessageListener2);