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 b184425b5..bfcf198d0 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -76,7 +76,6 @@ import com.nextcloud.talk.models.json.generic.GenericOverall; import com.nextcloud.talk.models.json.participants.Participant; import com.nextcloud.talk.models.json.participants.ParticipantsOverall; import com.nextcloud.talk.models.json.signaling.DataChannelMessage; -import com.nextcloud.talk.models.json.signaling.DataChannelMessageNick; import com.nextcloud.talk.models.json.signaling.NCMessagePayload; import com.nextcloud.talk.models.json.signaling.NCSignalingMessage; import com.nextcloud.talk.models.json.signaling.Signaling; @@ -264,9 +263,13 @@ public class CallActivity extends CallBaseActivity { private InternalSignalingMessageSender internalSignalingMessageSender = new InternalSignalingMessageSender(); private SignalingMessageSender signalingMessageSender; + private Map offerAnswerNickProviders = new HashMap<>(); + private Map callParticipantMessageListeners = new HashMap<>(); + private Map dataChannelMessageListeners = new HashMap<>(); + private SignalingMessageReceiver.ParticipantListMessageListener participantListMessageListener = new SignalingMessageReceiver.ParticipantListMessageListener() { @Override @@ -2006,6 +2009,19 @@ public class CallActivity extends CallBaseActivity { new CallActivityCallParticipantMessageListener(sessionId); callParticipantMessageListeners.put(sessionId, callParticipantMessageListener); signalingMessageReceiver.addListener(callParticipantMessageListener, sessionId); + + // DataChannel messages are sent only in video peers; (sender) screen peers do not even open them. + PeerConnectionWrapper.DataChannelMessageListener dataChannelMessageListener = + new CallActivityDataChannelMessageListener(sessionId); + dataChannelMessageListeners.put(sessionId, dataChannelMessageListener); + peerConnectionWrapper.addListener(dataChannelMessageListener); + } + + if (!publisher && !hasExternalSignalingServer && offerAnswerNickProviders.get(sessionId) == null) { + OfferAnswerNickProvider offerAnswerNickProvider = new OfferAnswerNickProvider(); + offerAnswerNickProviders.put(sessionId, offerAnswerNickProvider); + signalingMessageReceiver.addListener(offerAnswerNickProvider.getVideoWebRtcMessageListener(), sessionId, "video"); + signalingMessageReceiver.addListener(offerAnswerNickProvider.getScreenWebRtcMessageListener(), sessionId, "screen"); } if (publisher) { @@ -2032,6 +2048,10 @@ public class CallActivity extends CallBaseActivity { if (!(peerConnectionWrappers = getPeerConnectionWrapperListForSessionId(sessionId)).isEmpty()) { for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrappers) { if (peerConnectionWrapper.getSessionId().equals(sessionId)) { + if (!justScreen && VIDEO_STREAM_TYPE_VIDEO.equals(peerConnectionWrapper.getVideoStreamType())) { + PeerConnectionWrapper.DataChannelMessageListener dataChannelMessageListener = dataChannelMessageListeners.remove(sessionId); + peerConnectionWrapper.removeListener(dataChannelMessageListener); + } String videoStreamType = peerConnectionWrapper.getVideoStreamType(); if (VIDEO_STREAM_TYPE_SCREEN.equals(videoStreamType) || !justScreen) { runOnUiThread(() -> removeMediaStream(sessionId, videoStreamType)); @@ -2044,6 +2064,12 @@ public class CallActivity extends CallBaseActivity { if (!justScreen) { SignalingMessageReceiver.CallParticipantMessageListener listener = callParticipantMessageListeners.remove(sessionId); signalingMessageReceiver.removeListener(listener); + + OfferAnswerNickProvider offerAnswerNickProvider = offerAnswerNickProviders.remove(sessionId); + if (offerAnswerNickProvider != null) { + signalingMessageReceiver.removeListener(offerAnswerNickProvider.getVideoWebRtcMessageListener()); + signalingMessageReceiver.removeListener(offerAnswerNickProvider.getScreenWebRtcMessageListener()); + } } } @@ -2149,24 +2175,6 @@ public class CallActivity extends CallBaseActivity { toggleMedia(enableVideo, true); } } - } else if (peerConnectionEvent.getPeerConnectionEventType() == - PeerConnectionEvent.PeerConnectionEventType.NICK_CHANGE) { - if (participantDisplayItems.get(participantDisplayItemId) != null) { - participantDisplayItems.get(participantDisplayItemId).setNick(peerConnectionEvent.getNick()); - participantsAdapter.notifyDataSetChanged(); - } - } else if (peerConnectionEvent.getPeerConnectionEventType() == - PeerConnectionEvent.PeerConnectionEventType.VIDEO_CHANGE && !isVoiceOnlyCall) { - if (participantDisplayItems.get(participantDisplayItemId) != null) { - participantDisplayItems.get(participantDisplayItemId).setStreamEnabled(peerConnectionEvent.getChangeValue()); - participantsAdapter.notifyDataSetChanged(); - } - } else if (peerConnectionEvent.getPeerConnectionEventType() == - PeerConnectionEvent.PeerConnectionEventType.AUDIO_CHANGE) { - if (participantDisplayItems.get(participantDisplayItemId) != null) { - participantDisplayItems.get(participantDisplayItemId).setAudioEnabled(peerConnectionEvent.getChangeValue()); - participantsAdapter.notifyDataSetChanged(); - } } else if (peerConnectionEvent.getPeerConnectionEventType() == PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED) { setCallState(CallStatus.PUBLISHER_FAILED); @@ -2176,12 +2184,12 @@ public class CallActivity extends CallBaseActivity { } private void startSendingNick() { - DataChannelMessageNick dataChannelMessage = new DataChannelMessageNick(); + DataChannelMessage dataChannelMessage = new DataChannelMessage(); dataChannelMessage.setType("nickChanged"); - HashMap nickChangedPayload = new HashMap<>(); + Map nickChangedPayload = new HashMap<>(); nickChangedPayload.put("userid", conversationUser.getUserId()); nickChangedPayload.put("name", conversationUser.getDisplayName()); - dataChannelMessage.setPayload(nickChangedPayload); + dataChannelMessage.setPayloadMap(nickChangedPayload); for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) { if (peerConnectionWrapper.isMCUPublisher()) { Observable @@ -2196,7 +2204,7 @@ public class CallActivity extends CallBaseActivity { @Override public void onNext(@io.reactivex.annotations.NonNull Long aLong) { - peerConnectionWrapper.sendNickChannelData(dataChannelMessage); + peerConnectionWrapper.sendChannelData(dataChannelMessage); } @Override @@ -2265,7 +2273,7 @@ public class CallActivity extends CallBaseActivity { if (hasExternalSignalingServer) { nick = webSocketClient.getDisplayNameForSession(session); } else { - nick = peerConnectionWrapper != null ? peerConnectionWrapper.getNick() : ""; + nick = offerAnswerNickProviders.get(session) != null ? offerAnswerNickProviders.get(session).getNick() : ""; } String userId4Usage = userId; @@ -2278,11 +2286,14 @@ public class CallActivity extends CallBaseActivity { } } + String defaultGuestNick = getResources().getString(R.string.nc_nick_guest); + ParticipantDisplayItem participantDisplayItem = new ParticipantDisplayItem(baseUrl, userId4Usage, session, connected, nick, + defaultGuestNick, mediaStream, videoStreamType, videoStreamEnabled, @@ -2559,6 +2570,47 @@ public class CallActivity extends CallBaseActivity { } } + private static class OfferAnswerNickProvider { + + private class WebRtcMessageListener implements SignalingMessageReceiver.WebRtcMessageListener { + + @Override + public void onOffer(String sdp, String nick) { + (OfferAnswerNickProvider.this).nick = nick; + } + + @Override + public void onAnswer(String sdp, String nick) { + (OfferAnswerNickProvider.this).nick = nick; + } + + @Override + public void onCandidate(String sdpMid, int sdpMLineIndex, String sdp) { + } + + @Override + public void onEndOfCandidates() { + } + } + + private final WebRtcMessageListener videoWebRtcMessageListener = new WebRtcMessageListener(); + private final WebRtcMessageListener screenWebRtcMessageListener = new WebRtcMessageListener(); + + private String nick; + + public WebRtcMessageListener getVideoWebRtcMessageListener() { + return videoWebRtcMessageListener; + } + + public WebRtcMessageListener getScreenWebRtcMessageListener() { + return screenWebRtcMessageListener; + } + + public String getNick() { + return nick; + } + } + private class CallActivityCallParticipantMessageListener implements SignalingMessageReceiver.CallParticipantMessageListener { private final String sessionId; @@ -2573,6 +2625,66 @@ public class CallActivity extends CallBaseActivity { } } + private class CallActivityDataChannelMessageListener implements PeerConnectionWrapper.DataChannelMessageListener { + + private final String participantDisplayItemId; + + private CallActivityDataChannelMessageListener(String sessionId) { + // DataChannel messages are sent only in video peers, so the listener only acts on the "video" items. + this.participantDisplayItemId = sessionId + "-video"; + } + + @Override + public void onAudioOn() { + runOnUiThread(() -> { + if (participantDisplayItems.get(participantDisplayItemId) != null) { + participantDisplayItems.get(participantDisplayItemId).setAudioEnabled(true); + participantsAdapter.notifyDataSetChanged(); + } + }); + } + + @Override + public void onAudioOff() { + runOnUiThread(() -> { + if (participantDisplayItems.get(participantDisplayItemId) != null) { + participantDisplayItems.get(participantDisplayItemId).setAudioEnabled(false); + participantsAdapter.notifyDataSetChanged(); + } + }); + } + + @Override + public void onVideoOn() { + runOnUiThread(() -> { + if (participantDisplayItems.get(participantDisplayItemId) != null) { + participantDisplayItems.get(participantDisplayItemId).setStreamEnabled(true); + participantsAdapter.notifyDataSetChanged(); + } + }); + } + + @Override + public void onVideoOff() { + runOnUiThread(() -> { + if (participantDisplayItems.get(participantDisplayItemId) != null) { + participantDisplayItems.get(participantDisplayItemId).setStreamEnabled(false); + participantsAdapter.notifyDataSetChanged(); + } + }); + } + + @Override + public void onNickChanged(String nick) { + runOnUiThread(() -> { + if (participantDisplayItems.get(participantDisplayItemId) != null) { + participantDisplayItems.get(participantDisplayItemId).setNick(nick); + participantsAdapter.notifyDataSetChanged(); + } + }); + } + } + private class InternalSignalingMessageSender implements SignalingMessageSender { @Override diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java index 3ed18bf76..34fa963ac 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java @@ -13,6 +13,7 @@ public class ParticipantDisplayItem { private String session; private boolean connected; private String nick; + private final String defaultGuestNick; private String urlForAvatar; private MediaStream mediaStream; private String streamType; @@ -20,12 +21,13 @@ public class ParticipantDisplayItem { private EglBase rootEglBase; private boolean isAudioEnabled; - public ParticipantDisplayItem(String baseUrl, String userId, String session, boolean connected, String nick, MediaStream mediaStream, String streamType, boolean streamEnabled, EglBase rootEglBase) { + public ParticipantDisplayItem(String baseUrl, String userId, String session, boolean connected, String nick, String defaultGuestNick, MediaStream mediaStream, String streamType, boolean streamEnabled, EglBase rootEglBase) { this.baseUrl = baseUrl; this.userId = userId; this.session = session; this.connected = connected; this.nick = nick; + this.defaultGuestNick = defaultGuestNick; this.mediaStream = mediaStream; this.streamType = streamType; this.streamEnabled = streamEnabled; @@ -61,6 +63,10 @@ public class ParticipantDisplayItem { } public String getNick() { + if (TextUtils.isEmpty(userId) && TextUtils.isEmpty(nick)) { + return defaultGuestNick; + } + return nick; } @@ -78,7 +84,7 @@ public class ParticipantDisplayItem { if (!TextUtils.isEmpty(userId)) { urlForAvatar = ApiUtils.getUrlForAvatar(baseUrl, userId, true); } else { - urlForAvatar = ApiUtils.getUrlForGuestAvatar(baseUrl, nick, true); + urlForAvatar = ApiUtils.getUrlForGuestAvatar(baseUrl, getNick(), true); } } diff --git a/app/src/main/java/com/nextcloud/talk/events/PeerConnectionEvent.java b/app/src/main/java/com/nextcloud/talk/events/PeerConnectionEvent.java index c6722732e..fd10c30ce 100644 --- a/app/src/main/java/com/nextcloud/talk/events/PeerConnectionEvent.java +++ b/app/src/main/java/com/nextcloud/talk/events/PeerConnectionEvent.java @@ -120,6 +120,6 @@ public class PeerConnectionEvent { } public enum PeerConnectionEventType { - PEER_CONNECTED, PEER_DISCONNECTED, PEER_CLOSED, SENSOR_FAR, SENSOR_NEAR, NICK_CHANGE, AUDIO_CHANGE, VIDEO_CHANGE, PUBLISHER_FAILED + PEER_CONNECTED, PEER_DISCONNECTED, PEER_CLOSED, SENSOR_FAR, SENSOR_NEAR, PUBLISHER_FAILED } } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessage.kt b/app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessage.kt index 1024afc0f..b0ab14457 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessage.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessage.kt @@ -34,10 +34,15 @@ import kotlinx.android.parcel.TypeParceler data class DataChannelMessage( @JsonField(name = ["type"]) var type: String? = null, + /** Can be String or Map + * Use only for received messages */ @JsonField(name = ["payload"]) - var payload: Any? = null + var payload: Any? = null, + /** Use only to send messages */ + @JsonField(name = ["payload"]) + var payloadMap: Map? = null ) : Parcelable { // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' - constructor() : this(null, null) + constructor() : this(null, null, null) constructor(type: String) : this(type, null) } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessageNick.kt b/app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessageNick.kt deleted file mode 100644 index 652106fa0..000000000 --- a/app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessageNick.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Nextcloud Talk application - * - * @author Mario Danic - * @author Andy Scherzinger - * Copyright (C) 2022 Andy Scherzinger - * Copyright (C) 2017 Mario Danic - * - * 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 . - */ -package com.nextcloud.talk.models.json.signaling - -import android.os.Parcelable -import com.bluelinelabs.logansquare.annotation.JsonField -import com.bluelinelabs.logansquare.annotation.JsonObject -import java.util.HashMap -import kotlinx.android.parcel.Parcelize - -@Parcelize -@JsonObject -data class DataChannelMessageNick( - @JsonField(name = ["type"]) - var type: String? = null, - @JsonField(name = ["payload"]) - var payload: HashMap? = null -) : Parcelable { - // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' - constructor() : this(null, null) -} diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/DataChannelMessageNotifier.java b/app/src/main/java/com/nextcloud/talk/webrtc/DataChannelMessageNotifier.java new file mode 100644 index 000000000..c949cc39f --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/webrtc/DataChannelMessageNotifier.java @@ -0,0 +1,77 @@ +/* + * Nextcloud Talk application + * + * @author Daniel Calviño Sánchez + * Copyright (C) 2022 Daniel Calviño Sánchez + * + * 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 . + */ +package com.nextcloud.talk.webrtc; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * Helper class to register and notify DataChannelMessageListeners. + * + * This class is only meant for internal use by PeerConnectionWrapper; listeners must register themselves against + * a PeerConnectionWrapper rather than against a DataChannelMessageNotifier. + */ +public class DataChannelMessageNotifier { + + private final Set dataChannelMessageListeners = new LinkedHashSet<>(); + + public synchronized void addListener(PeerConnectionWrapper.DataChannelMessageListener listener) { + if (listener == null) { + throw new IllegalArgumentException("DataChannelMessageListener can not be null"); + } + + dataChannelMessageListeners.add(listener); + } + + public synchronized void removeListener(PeerConnectionWrapper.DataChannelMessageListener listener) { + dataChannelMessageListeners.remove(listener); + } + + public synchronized void notifyAudioOn() { + for (PeerConnectionWrapper.DataChannelMessageListener listener : new ArrayList<>(dataChannelMessageListeners)) { + listener.onAudioOn(); + } + } + + public synchronized void notifyAudioOff() { + for (PeerConnectionWrapper.DataChannelMessageListener listener : new ArrayList<>(dataChannelMessageListeners)) { + listener.onAudioOff(); + } + } + + public synchronized void notifyVideoOn() { + for (PeerConnectionWrapper.DataChannelMessageListener listener : new ArrayList<>(dataChannelMessageListeners)) { + listener.onVideoOn(); + } + } + + public synchronized void notifyVideoOff() { + for (PeerConnectionWrapper.DataChannelMessageListener listener : new ArrayList<>(dataChannelMessageListeners)) { + listener.onVideoOff(); + } + } + + public synchronized void notifyNickChanged(String nick) { + for (PeerConnectionWrapper.DataChannelMessageListener listener : new ArrayList<>(dataChannelMessageListeners)) { + listener.onNickChanged(nick); + } + } +} diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java index ef965eb3b..49df4b00e 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java @@ -25,7 +25,6 @@ import android.text.TextUtils; import android.util.Log; import com.bluelinelabs.logansquare.LoganSquare; -import com.nextcloud.talk.R; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.data.user.model.User; import com.nextcloud.talk.events.NetworkEvent; @@ -384,7 +383,7 @@ public class MagicWebSocketInstance extends WebSocketListener { } } - return NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_nick_guest); + return ""; } public String getUserIdForSession(String session) { 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 5deafad52..c5b2f66b2 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -24,16 +24,13 @@ package com.nextcloud.talk.webrtc; import android.content.Context; -import android.text.TextUtils; import android.util.Log; import com.bluelinelabs.logansquare.LoganSquare; -import com.nextcloud.talk.R; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.events.MediaStreamEvent; import com.nextcloud.talk.events.PeerConnectionEvent; import com.nextcloud.talk.models.json.signaling.DataChannelMessage; -import com.nextcloud.talk.models.json.signaling.DataChannelMessageNick; import com.nextcloud.talk.models.json.signaling.NCIceCandidate; import com.nextcloud.talk.models.json.signaling.NCMessagePayload; import com.nextcloud.talk.models.json.signaling.NCSignalingMessage; @@ -59,8 +56,8 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import javax.inject.Inject; @@ -68,12 +65,26 @@ import javax.inject.Inject; import androidx.annotation.Nullable; import autodagger.AutoInjector; -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; - @AutoInjector(NextcloudTalkApplication.class) public class PeerConnectionWrapper { + /** + * Listener for data channel messages. + * + * The messages are bound to a specific peer connection, so each listener is expected to handle messages only for + * a single peer connection. + * + * All methods are called on the so called "signaling" thread of WebRTC, which is an internal thread created by the + * WebRTC library and NOT the same thread where signaling messages are received. + */ + public interface DataChannelMessageListener { + void onAudioOn(); + void onAudioOff(); + void onVideoOn(); + void onVideoOff(); + void onNickChanged(String nick); + } + private static final String TAG = PeerConnectionWrapper.class.getCanonicalName(); private final SignalingMessageReceiver signalingMessageReceiver; @@ -81,10 +92,11 @@ public class PeerConnectionWrapper { private final SignalingMessageSender signalingMessageSender; + private final DataChannelMessageNotifier dataChannelMessageNotifier = new DataChannelMessageNotifier(); + private List iceCandidates = new ArrayList<>(); private PeerConnection peerConnection; private String sessionId; - private String nick; private final MediaConstraints mediaConstraints; private DataChannel dataChannel; private final MagicSdpObserver magicSdpObserver; @@ -160,6 +172,21 @@ public class PeerConnectionWrapper { } } + /** + * Adds a listener for data channel messages. + * + * A listener is expected to be added only once. If the same listener is added again it will be notified just once. + * + * @param listener the DataChannelMessageListener + */ + public void addListener(DataChannelMessageListener listener) { + dataChannelMessageNotifier.addListener(listener); + } + + public void removeListener(DataChannelMessageListener listener) { + dataChannelMessageNotifier.removeListener(listener); + } + public String getVideoStreamType() { return videoStreamType; } @@ -203,18 +230,6 @@ public class PeerConnectionWrapper { } } - public void sendNickChannelData(DataChannelMessageNick dataChannelMessage) { - ByteBuffer buffer; - if (dataChannel != null) { - try { - buffer = ByteBuffer.wrap(LoganSquare.serialize(dataChannelMessage).getBytes()); - dataChannel.send(new DataChannel.Buffer(buffer, false)); - } catch (IOException e) { - Log.d(TAG, "Failed to send channel data, attempting regular " + dataChannelMessage); - } - } - } - public void sendChannelData(DataChannelMessage dataChannelMessage) { ByteBuffer buffer; if (dataChannel != null) { @@ -235,18 +250,6 @@ public class PeerConnectionWrapper { return sessionId; } - public String getNick() { - if (!TextUtils.isEmpty(nick)) { - return nick; - } else { - return Objects.requireNonNull(NextcloudTalkApplication.Companion.getSharedApplication()).getString(R.string.nc_nick_guest); - } - } - - private void setNick(String nick) { - this.nick = nick; - } - private void sendInitialMediaStatus() { if (localStream != null) { if (localStream.videoTracks.size() == 1 && localStream.videoTracks.get(0).enabled()) { @@ -288,16 +291,14 @@ public class PeerConnectionWrapper { private class WebRtcMessageListener implements SignalingMessageReceiver.WebRtcMessageListener { public void onOffer(String sdp, String nick) { - onOfferOrAnswer("offer", sdp, nick); + onOfferOrAnswer("offer", sdp); } public void onAnswer(String sdp, String nick) { - onOfferOrAnswer("answer", sdp, nick); + onOfferOrAnswer("answer", sdp); } - private void onOfferOrAnswer(String type, String sdp, String nick) { - setNick(nick); - + private void onOfferOrAnswer(String type, String sdp) { SessionDescription sessionDescriptionWithPreferredCodec; boolean isAudio = false; @@ -350,40 +351,53 @@ public class PeerConnectionWrapper { String strData = new String(bytes); Log.d(TAG, "Got msg: " + strData + " over " + TAG + " " + sessionId); + DataChannelMessage dataChannelMessage; try { - DataChannelMessage dataChannelMessage = LoganSquare.parse(strData, DataChannelMessage.class); - - String internalNick; - if ("nickChanged".equals(dataChannelMessage.getType())) { - if (dataChannelMessage.getPayload() instanceof String) { - internalNick = (String) dataChannelMessage.getPayload(); - if (!internalNick.equals(nick)) { - setNick(internalNick); - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .NICK_CHANGE, sessionId, getNick(), null, videoStreamType)); - } - } else { - if (dataChannelMessage.getPayload() != null) { - HashMap payloadHashMap = (HashMap) dataChannelMessage.getPayload(); - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .NICK_CHANGE, sessionId, payloadHashMap.get("name"), null, videoStreamType)); - } - } - } else if ("audioOn".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .AUDIO_CHANGE, sessionId, null, TRUE, videoStreamType)); - } else if ("audioOff".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .AUDIO_CHANGE, sessionId, null, FALSE, videoStreamType)); - } else if ("videoOn".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .VIDEO_CHANGE, sessionId, null, TRUE, videoStreamType)); - } else if ("videoOff".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .VIDEO_CHANGE, sessionId, null, FALSE, videoStreamType)); - } + dataChannelMessage = LoganSquare.parse(strData, DataChannelMessage.class); } catch (IOException e) { Log.d(TAG, "Failed to parse data channel message"); + + return; + } + + if ("nickChanged".equals(dataChannelMessage.getType())) { + String nick = null; + if (dataChannelMessage.getPayload() instanceof String) { + nick = (String) dataChannelMessage.getPayload(); + } else if (dataChannelMessage.getPayload() instanceof Map) { + Map payloadMap = (Map) dataChannelMessage.getPayload(); + nick = payloadMap.get("name"); + } + + if (nick != null) { + dataChannelMessageNotifier.notifyNickChanged(nick); + } + + return; + } + + if ("audioOn".equals(dataChannelMessage.getType())) { + dataChannelMessageNotifier.notifyAudioOn(); + + return; + } + + if ("audioOff".equals(dataChannelMessage.getType())) { + dataChannelMessageNotifier.notifyAudioOff(); + + return; + } + + if ("videoOn".equals(dataChannelMessage.getType())) { + dataChannelMessageNotifier.notifyVideoOn(); + + return; + } + + if ("videoOff".equals(dataChannelMessage.getType())) { + dataChannelMessageNotifier.notifyVideoOff(); + + return; } } }