mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-06 06:15:12 +00:00
Add listener for call participant messages
Although "unshareScreen" is technically bound to a specific peer connection it is instead treated as a general message on the call participant. Nevertheless, call participant messages will make possible (at a later point) to listen to events like "raise hand" or "mute" (which, again, could be technically bound to a specific peer connection, but at least for now are treated as a general message on the call participant). Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
parent
d42fe61e89
commit
bda7d2719b
app/src
main/java/com/nextcloud/talk
activities
signaling
test/java/com/nextcloud/talk/signaling
@ -266,6 +266,9 @@ public class CallActivity extends CallBaseActivity {
|
||||
|
||||
private CallActivitySignalingMessageReceiver signalingMessageReceiver = new CallActivitySignalingMessageReceiver();
|
||||
|
||||
private Map<String, SignalingMessageReceiver.CallParticipantMessageListener> callParticipantMessageListeners =
|
||||
new HashMap<>();
|
||||
|
||||
private SignalingMessageReceiver.OfferMessageListener offerMessageListener = new SignalingMessageReceiver.OfferMessageListener() {
|
||||
@Override
|
||||
public void onOffer(String sessionId, String roomType, String sdp, String nick) {
|
||||
@ -1675,14 +1678,6 @@ public class CallActivity extends CallBaseActivity {
|
||||
|
||||
private void processMessage(NCSignalingMessage ncSignalingMessage) {
|
||||
if ("video".equals(ncSignalingMessage.getRoomType()) || "screen".equals(ncSignalingMessage.getRoomType())) {
|
||||
String type = ncSignalingMessage.getType();
|
||||
|
||||
if ("unshareScreen".equals(type)) {
|
||||
endPeerConnection(ncSignalingMessage.getFrom(), true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
signalingMessageReceiver.process(ncSignalingMessage);
|
||||
} else {
|
||||
Log.e(TAG, "unexpected RoomType while processing NCSignalingMessage");
|
||||
@ -2028,6 +2023,15 @@ public class CallActivity extends CallBaseActivity {
|
||||
|
||||
peerConnectionWrapperList.add(peerConnectionWrapper);
|
||||
|
||||
// Currently there is no separation between call participants and peer connections, so any video peer
|
||||
// connection (except the own publisher connection) is treated as a call participant.
|
||||
if (!publisher && "video".equals(type)) {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener callParticipantMessageListener =
|
||||
new CallActivityCallParticipantMessageListener(sessionId);
|
||||
callParticipantMessageListeners.put(sessionId, callParticipantMessageListener);
|
||||
signalingMessageReceiver.addListener(callParticipantMessageListener, sessionId);
|
||||
}
|
||||
|
||||
if (publisher) {
|
||||
startSendingNick();
|
||||
}
|
||||
@ -2060,6 +2064,11 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!justScreen) {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener listener = callParticipantMessageListeners.remove(sessionId);
|
||||
signalingMessageReceiver.removeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeMediaStream(String sessionId, String videoStreamType) {
|
||||
@ -2642,6 +2651,20 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private class CallActivityCallParticipantMessageListener implements SignalingMessageReceiver.CallParticipantMessageListener {
|
||||
|
||||
private final String sessionId;
|
||||
|
||||
public CallActivityCallParticipantMessageListener(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnshareScreen() {
|
||||
endPeerConnection(sessionId, true);
|
||||
}
|
||||
}
|
||||
|
||||
private class MicrophoneButtonTouchListener implements View.OnTouchListener {
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Daniel Calviño Sánchez
|
||||
* Copyright (C) 2022 Daniel Calviño Sánchez <danxuliu@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.nextcloud.talk.signaling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper class to register and notify CallParticipantMessageListeners.
|
||||
*
|
||||
* This class is only meant for internal use by SignalingMessageReceiver; listeners must register themselves against
|
||||
* a SignalingMessageReceiver rather than against a CallParticipantMessageNotifier.
|
||||
*/
|
||||
class CallParticipantMessageNotifier {
|
||||
|
||||
/**
|
||||
* Helper class to associate a CallParticipantMessageListener with a session ID.
|
||||
*/
|
||||
private static class CallParticipantMessageListenerFrom {
|
||||
public final SignalingMessageReceiver.CallParticipantMessageListener listener;
|
||||
public final String sessionId;
|
||||
|
||||
private CallParticipantMessageListenerFrom(SignalingMessageReceiver.CallParticipantMessageListener listener,
|
||||
String sessionId) {
|
||||
this.listener = listener;
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<CallParticipantMessageListenerFrom> callParticipantMessageListenersFrom = new ArrayList<>();
|
||||
|
||||
public synchronized void addListener(SignalingMessageReceiver.CallParticipantMessageListener listener, String sessionId) {
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("CallParticipantMessageListener can not be null");
|
||||
}
|
||||
|
||||
if (sessionId == null) {
|
||||
throw new IllegalArgumentException("sessionId can not be null");
|
||||
}
|
||||
|
||||
removeListener(listener);
|
||||
|
||||
callParticipantMessageListenersFrom.add(new CallParticipantMessageListenerFrom(listener, sessionId));
|
||||
}
|
||||
|
||||
public synchronized void removeListener(SignalingMessageReceiver.CallParticipantMessageListener listener) {
|
||||
Iterator<CallParticipantMessageListenerFrom> it = callParticipantMessageListenersFrom.iterator();
|
||||
while (it.hasNext()) {
|
||||
CallParticipantMessageListenerFrom listenerFrom = it.next();
|
||||
|
||||
if (listenerFrom.listener == listener) {
|
||||
it.remove();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<SignalingMessageReceiver.CallParticipantMessageListener> getListenersFor(String sessionId) {
|
||||
List<SignalingMessageReceiver.CallParticipantMessageListener> callParticipantMessageListeners =
|
||||
new ArrayList<>(callParticipantMessageListenersFrom.size());
|
||||
|
||||
for (CallParticipantMessageListenerFrom listenerFrom : callParticipantMessageListenersFrom) {
|
||||
if (listenerFrom.sessionId.equals(sessionId)) {
|
||||
callParticipantMessageListeners.add(listenerFrom.listener);
|
||||
}
|
||||
}
|
||||
|
||||
return callParticipantMessageListeners;
|
||||
}
|
||||
|
||||
public synchronized void notifyUnshareScreen(String sessionId) {
|
||||
for (SignalingMessageReceiver.CallParticipantMessageListener listener : getListenersFor(sessionId)) {
|
||||
listener.onUnshareScreen();
|
||||
}
|
||||
}
|
||||
}
|
@ -44,6 +44,19 @@ import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||
*/
|
||||
public abstract class SignalingMessageReceiver {
|
||||
|
||||
/**
|
||||
* Listener for call participant messages.
|
||||
*
|
||||
* The messages are bound to a specific call participant (or, rather, session), so each listener is expected to
|
||||
* handle messages only for a single call participant.
|
||||
*
|
||||
* Although "unshareScreen" is technically bound to a specific peer connection it is instead treated as a general
|
||||
* message on the call participant.
|
||||
*/
|
||||
public interface CallParticipantMessageListener {
|
||||
void onUnshareScreen();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for WebRTC offers.
|
||||
*
|
||||
@ -70,10 +83,29 @@ public abstract class SignalingMessageReceiver {
|
||||
void onEndOfCandidates();
|
||||
}
|
||||
|
||||
private final CallParticipantMessageNotifier callParticipantMessageNotifier = new CallParticipantMessageNotifier();
|
||||
|
||||
private final OfferMessageNotifier offerMessageNotifier = new OfferMessageNotifier();
|
||||
|
||||
private final WebRtcMessageNotifier webRtcMessageNotifier = new WebRtcMessageNotifier();
|
||||
|
||||
/**
|
||||
* Adds a listener for call participant messages.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param listener the CallParticipantMessageListener
|
||||
* @param sessionId the ID of the session that messages come from
|
||||
*/
|
||||
public void addListener(CallParticipantMessageListener listener, String sessionId) {
|
||||
callParticipantMessageNotifier.addListener(listener, sessionId);
|
||||
}
|
||||
|
||||
public void removeListener(CallParticipantMessageListener listener) {
|
||||
callParticipantMessageNotifier.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener for all offer messages.
|
||||
*
|
||||
@ -116,6 +148,43 @@ public abstract class SignalingMessageReceiver {
|
||||
String sessionId = signalingMessage.getFrom();
|
||||
String roomType = signalingMessage.getRoomType();
|
||||
|
||||
// "unshareScreen" messages are directly sent to the screen peer connection when the internal signaling
|
||||
// server is used, and to the room when the external signaling server is used. However, the (relevant) data
|
||||
// of the received message ("from" and "type") is the same in both cases.
|
||||
if ("unshareScreen".equals(type)) {
|
||||
// Message schema (external signaling server):
|
||||
// {
|
||||
// "type": "message",
|
||||
// "message": {
|
||||
// "sender": {
|
||||
// ...
|
||||
// },
|
||||
// "data": {
|
||||
// "roomType": "screen",
|
||||
// "type": "unshareScreen",
|
||||
// "from": #STRING#,
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// Message schema (internal signaling server):
|
||||
// {
|
||||
// "type": "message",
|
||||
// "data": {
|
||||
// "to": #STRING#,
|
||||
// "sid": #STRING#,
|
||||
// "broadcaster": #STRING#,
|
||||
// "roomType": "screen",
|
||||
// "type": "unshareScreen",
|
||||
// "from": #STRING#,
|
||||
// },
|
||||
// }
|
||||
|
||||
callParticipantMessageNotifier.notifyUnshareScreen(sessionId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ("offer".equals(type)) {
|
||||
// Message schema (external signaling server):
|
||||
// {
|
||||
|
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Daniel Calviño Sánchez
|
||||
* Copyright (C) 2022 Daniel Calviño Sánchez <danxuliu@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.nextcloud.talk.signaling;
|
||||
|
||||
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.only;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
public class SignalingMessageReceiverCallParticipantTest {
|
||||
|
||||
private SignalingMessageReceiver signalingMessageReceiver;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// SignalingMessageReceiver is abstract to prevent direct instantiation without calling the appropriate
|
||||
// protected methods.
|
||||
signalingMessageReceiver = new SignalingMessageReceiver() {
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddCallParticipantMessageListenerWithNullListener() {
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> {
|
||||
signalingMessageReceiver.addListener(null, "theSessionId");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddCallParticipantMessageListenerWithNullSessionId() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> {
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener, null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallParticipantMessageUnshareScreen() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener, "theSessionId");
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("theSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verify(mockedCallParticipantMessageListener, only()).onUnshareScreen();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallParticipantMessageSeveralListenersSameFrom() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener1 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener2 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener1, "theSessionId");
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener2, "theSessionId");
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("theSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verify(mockedCallParticipantMessageListener1, only()).onUnshareScreen();
|
||||
verify(mockedCallParticipantMessageListener2, only()).onUnshareScreen();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallParticipantMessageNotMatchingSessionId() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener, "theSessionId");
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("notMatchingSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verifyNoInteractions(mockedCallParticipantMessageListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallParticipantMessageAfterRemovingListener() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener, "theSessionId");
|
||||
signalingMessageReceiver.removeListener(mockedCallParticipantMessageListener);
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("theSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verifyNoInteractions(mockedCallParticipantMessageListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallParticipantMessageAfterRemovingSingleListenerOfSeveral() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener1 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener2 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener3 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener1, "theSessionId");
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener2, "theSessionId");
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener3, "theSessionId");
|
||||
signalingMessageReceiver.removeListener(mockedCallParticipantMessageListener2);
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("theSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verify(mockedCallParticipantMessageListener1, only()).onUnshareScreen();
|
||||
verify(mockedCallParticipantMessageListener3, only()).onUnshareScreen();
|
||||
verifyNoInteractions(mockedCallParticipantMessageListener2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallParticipantMessageAfterAddingListenerAgainForDifferentFrom() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener, "theSessionId");
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener, "theSessionId2");
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("theSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verifyNoInteractions(mockedCallParticipantMessageListener);
|
||||
|
||||
signalingMessage.setFrom("theSessionId2");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verify(mockedCallParticipantMessageListener, only()).onUnshareScreen();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddCallParticipantMessageListenerWhenHandlingCallParticipantMessage() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener1 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener2 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
doAnswer((invocation) -> {
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener2, "theSessionId");
|
||||
return null;
|
||||
}).when(mockedCallParticipantMessageListener1).onUnshareScreen();
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener1, "theSessionId");
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("theSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
verify(mockedCallParticipantMessageListener1, only()).onUnshareScreen();
|
||||
verifyNoInteractions(mockedCallParticipantMessageListener2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveCallParticipantMessageListenerWhenHandlingCallParticipantMessage() {
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener1 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
SignalingMessageReceiver.CallParticipantMessageListener mockedCallParticipantMessageListener2 =
|
||||
mock(SignalingMessageReceiver.CallParticipantMessageListener.class);
|
||||
|
||||
doAnswer((invocation) -> {
|
||||
signalingMessageReceiver.removeListener(mockedCallParticipantMessageListener2);
|
||||
return null;
|
||||
}).when(mockedCallParticipantMessageListener1).onUnshareScreen();
|
||||
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener1, "theSessionId");
|
||||
signalingMessageReceiver.addListener(mockedCallParticipantMessageListener2, "theSessionId");
|
||||
|
||||
NCSignalingMessage signalingMessage = new NCSignalingMessage();
|
||||
signalingMessage.setFrom("theSessionId");
|
||||
signalingMessage.setType("unshareScreen");
|
||||
signalingMessage.setRoomType("theRoomType");
|
||||
signalingMessageReceiver.processSignalingMessage(signalingMessage);
|
||||
|
||||
InOrder inOrder = inOrder(mockedCallParticipantMessageListener1, mockedCallParticipantMessageListener2);
|
||||
|
||||
inOrder.verify(mockedCallParticipantMessageListener1).onUnshareScreen();
|
||||
inOrder.verify(mockedCallParticipantMessageListener2).onUnshareScreen();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user