From faf25f8071ed1d9177b043a85cfe4a23861241a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 23 Oct 2022 22:01:31 +0200 Subject: [PATCH 01/10] Replace concrete implementation with interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../com/nextcloud/talk/webrtc/PeerConnectionWrapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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..e5bea1847 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -59,8 +59,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; @@ -364,9 +364,9 @@ public class PeerConnectionWrapper { } } else { if (dataChannelMessage.getPayload() != null) { - HashMap payloadHashMap = (HashMap) dataChannelMessage.getPayload(); + Map payloadMap = (Map) dataChannelMessage.getPayload(); EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .NICK_CHANGE, sessionId, payloadHashMap.get("name"), null, videoStreamType)); + .NICK_CHANGE, sessionId, payloadMap.get("name"), null, videoStreamType)); } } } else if ("audioOn".equals(dataChannelMessage.getType())) { From 68cf4ee02855d65945bc4fb84ba156432c91adc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 23 Oct 2022 22:01:31 +0200 Subject: [PATCH 02/10] Use generic data channel message instead of nick specific one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generic data channel message works fine for receiving, but it could not be used for sending, because the serialization of the payload failed (the generated JsonMapper did not call 'writeFieldName("payload")', apparently because the payload was defined as "Any", so there was no field name set when serializing the payload contents). It is very likely that the nick data channel message, which has an explicit payload type and was used only for sending but not for receiving, was added back in the day just to work around that limitation. However, due to how the JsonMappers are generated if several properties with the same name are defined only the first one will be parsed, and only those with a value will be serialized. This makes possible to define first a generic payload property and then a payload property with an explicit type to have a single data channel message class that can be used both for sending and receiving. As the nick data channel message is now no longer needed it was removed. Signed-off-by: Daniel Calviño Sánchez --- .../talk/activities/CallActivity.java | 9 ++--- .../json/signaling/DataChannelMessage.kt | 9 ++++- .../json/signaling/DataChannelMessageNick.kt | 40 ------------------- .../talk/webrtc/PeerConnectionWrapper.java | 13 ------ 4 files changed, 11 insertions(+), 60 deletions(-) delete mode 100644 app/src/main/java/com/nextcloud/talk/models/json/signaling/DataChannelMessageNick.kt 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..22f490ef5 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; @@ -2176,12 +2175,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 +2195,7 @@ public class CallActivity extends CallBaseActivity { @Override public void onNext(@io.reactivex.annotations.NonNull Long aLong) { - peerConnectionWrapper.sendNickChannelData(dataChannelMessage); + peerConnectionWrapper.sendChannelData(dataChannelMessage); } @Override 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/PeerConnectionWrapper.java b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java index e5bea1847..d55b85d24 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -33,7 +33,6 @@ 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; @@ -203,18 +202,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) { From 2eac8c2cba431bae1fe12c6dd1b8881b000131d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 7 Nov 2022 01:29:37 +0100 Subject: [PATCH 03/10] Move default nick out of PeerConnectionWrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the nick is not known whether "Guest" or something else needs to be shown is a responsability of the UI, so now the PeerConnectionWrapper just returns an empty string and the UI shows the default guest nick if needed. Moreover, the nick stored in the PeerConnectionWrapper was not always correct, as if no nick was received it was returned as "Guest" even if the connection belonged to a user. Now "Guest" is used only for actual guests. Signed-off-by: Daniel Calviño Sánchez --- .../com/nextcloud/talk/activities/CallActivity.java | 3 +++ .../talk/adapters/ParticipantDisplayItem.java | 10 ++++++++-- .../nextcloud/talk/webrtc/PeerConnectionWrapper.java | 8 +------- 3 files changed, 12 insertions(+), 9 deletions(-) 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 22f490ef5..08d051efd 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -2277,11 +2277,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, 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/webrtc/PeerConnectionWrapper.java b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java index d55b85d24..c91c8b222 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -24,11 +24,9 @@ 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; @@ -223,11 +221,7 @@ public class PeerConnectionWrapper { } public String getNick() { - if (!TextUtils.isEmpty(nick)) { - return nick; - } else { - return Objects.requireNonNull(NextcloudTalkApplication.Companion.getSharedApplication()).getString(R.string.nc_nick_guest); - } + return nick; } private void setNick(String nick) { From 0dcdd6161f6c12549894619c4b600df79aa2b35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 7 Nov 2022 01:29:37 +0100 Subject: [PATCH 04/10] Move nick handling out of PeerConnectionWrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PeerConnectionWrappers should not be concerned with the nick of participants. Moreover, the nick is included in offers and answers due to legacy reasons and only when the internal signaling server is used. Due to that the nick was moved out of PeerConnectionWrapper; although the handling is now different the end result should be the same (there might be some differences in very specific sequences of events, but in any case all this is just a temporary step and any leftover issue should be addressed once call participants and peer connections are split). As the PeerConnectionWrapper does not keep track of the nick now the nick changed event is always emitted when a nick changed data channel message is received, even if the nick did not actually change. Nevertheless, before it was anyway always emitted if it was for a user and only when it was for a guest it was emitted only on real changes. In any case this is not expected to cause any issue (other than some unneeded view updates, but that will be addressed at a later point by updating the views only when the model actually changed). Signed-off-by: Daniel Calviño Sánchez --- .../talk/activities/CallActivity.java | 58 ++++++++++++++++++- .../talk/webrtc/PeerConnectionWrapper.java | 26 ++------- 2 files changed, 62 insertions(+), 22 deletions(-) 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 08d051efd..c79d81774 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -263,6 +263,8 @@ public class CallActivity extends CallBaseActivity { private InternalSignalingMessageSender internalSignalingMessageSender = new InternalSignalingMessageSender(); private SignalingMessageSender signalingMessageSender; + private Map offerAnswerNickProviders = new HashMap<>(); + private Map callParticipantMessageListeners = new HashMap<>(); @@ -2007,6 +2009,13 @@ public class CallActivity extends CallBaseActivity { signalingMessageReceiver.addListener(callParticipantMessageListener, sessionId); } + 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) { startSendingNick(); } @@ -2043,6 +2052,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()); + } } } @@ -2264,7 +2279,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; @@ -2561,6 +2576,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; 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 c91c8b222..944bbf8f8 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -81,7 +81,6 @@ public class PeerConnectionWrapper { 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; @@ -220,14 +219,6 @@ public class PeerConnectionWrapper { return sessionId; } - public String getNick() { - return nick; - } - - private void setNick(String nick) { - this.nick = nick; - } - private void sendInitialMediaStatus() { if (localStream != null) { if (localStream.videoTracks.size() == 1 && localStream.videoTracks.get(0).enabled()) { @@ -269,16 +260,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; @@ -334,15 +323,10 @@ public class PeerConnectionWrapper { 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)); - } + EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType + .NICK_CHANGE, sessionId, (String) dataChannelMessage.getPayload(), null, videoStreamType)); } else { if (dataChannelMessage.getPayload() != null) { Map payloadMap = (Map) dataChannelMessage.getPayload(); From 81f353f7f0277ab5597033755b6dbaace06e28f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 25 Nov 2022 12:18:12 +0100 Subject: [PATCH 05/10] Return empty display name rather than default nick from web socket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the display name is not known whether "Guest" or something else needs to be shown is not a responsibility of the web socket, so now an empty string is returned instead. In practice this should not make any difference, though, as the display name of users is always known as soon as the user joined, and if the nick of a guest is not known the UI will set it to "Guest". Signed-off-by: Daniel Calviño Sánchez --- .../java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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) { From af514b142a1ec62c3a514eabde4bbe0135f04b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 7 Nov 2022 01:36:02 +0100 Subject: [PATCH 06/10] Reorder code that handles nick changed events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../talk/webrtc/PeerConnectionWrapper.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) 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 944bbf8f8..18371cf95 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -324,15 +324,17 @@ public class PeerConnectionWrapper { DataChannelMessage dataChannelMessage = LoganSquare.parse(strData, DataChannelMessage.class); 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) { EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .NICK_CHANGE, sessionId, (String) dataChannelMessage.getPayload(), null, videoStreamType)); - } else { - if (dataChannelMessage.getPayload() != null) { - Map payloadMap = (Map) dataChannelMessage.getPayload(); - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .NICK_CHANGE, sessionId, payloadMap.get("name"), null, videoStreamType)); - } + .NICK_CHANGE, sessionId, nick, null, videoStreamType)); } } else if ("audioOn".equals(dataChannelMessage.getType())) { EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType From ac4be52b843387faa63a1ac62a6d03a2f4d8c86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 7 Nov 2022 01:39:11 +0100 Subject: [PATCH 07/10] Do not guard code that can not throw the caught exception MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../talk/webrtc/PeerConnectionWrapper.java | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) 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 18371cf95..e3452f7aa 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -320,37 +320,40 @@ 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); - - 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) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .NICK_CHANGE, sessionId, nick, 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) { + EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType + .NICK_CHANGE, sessionId, nick, 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)); } } } From a65e56a9ceaa30069d92f8141339d99b2efb3be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 7 Nov 2022 02:12:35 +0100 Subject: [PATCH 08/10] Remove unneeded condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the call is a voice only call there will be no received video tracks (they would have been stopped when each connection is established), so changing the enabled state has no effect (as the adapter only tries to show the received video if it is available). Signed-off-by: Daniel Calviño Sánchez --- .../main/java/com/nextcloud/talk/activities/CallActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c79d81774..22fe59dc4 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -2170,7 +2170,7 @@ public class CallActivity extends CallBaseActivity { participantsAdapter.notifyDataSetChanged(); } } else if (peerConnectionEvent.getPeerConnectionEventType() == - PeerConnectionEvent.PeerConnectionEventType.VIDEO_CHANGE && !isVoiceOnlyCall) { + PeerConnectionEvent.PeerConnectionEventType.VIDEO_CHANGE) { if (participantDisplayItems.get(participantDisplayItemId) != null) { participantDisplayItems.get(participantDisplayItemId).setStreamEnabled(peerConnectionEvent.getChangeValue()); participantsAdapter.notifyDataSetChanged(); From dceb4a6d7973bd109b1102f66b4a403325b1e3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 7 Nov 2022 08:56:20 +0100 Subject: [PATCH 09/10] Add listener for data channel messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For now only the same data channel messages that were already handled are taken into account, but at a later point the missing messages ("speaking" and "stoppedSpeaking") could be added too. Note that the thread used to handle the data channel messages has changed; the EventBus subscriber mode was "MAIN", but as the messages were posted from a DataChannel observer, which run in a worker thread rather than in the main thread, the subscriber was executed in the main thread rather than in the same thread as the poster. Due to this the actions performed by the handler now must be explicitly run in the main thread. Signed-off-by: Daniel Calviño Sánchez --- .../talk/activities/CallActivity.java | 90 +++++++++++++++---- .../talk/events/PeerConnectionEvent.java | 2 +- .../webrtc/DataChannelMessageNotifier.java | 77 ++++++++++++++++ .../talk/webrtc/PeerConnectionWrapper.java | 52 ++++++++--- 4 files changed, 189 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/webrtc/DataChannelMessageNotifier.java 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 22fe59dc4..bfcf198d0 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -268,6 +268,8 @@ public class CallActivity extends CallBaseActivity { private Map callParticipantMessageListeners = new HashMap<>(); + private Map dataChannelMessageListeners = new HashMap<>(); + private SignalingMessageReceiver.ParticipantListMessageListener participantListMessageListener = new SignalingMessageReceiver.ParticipantListMessageListener() { @Override @@ -2007,6 +2009,12 @@ 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) { @@ -2040,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)); @@ -2163,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) { - 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); @@ -2631,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/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/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/PeerConnectionWrapper.java b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java index e3452f7aa..bb5e57540 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -65,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; @@ -78,6 +92,8 @@ public class PeerConnectionWrapper { private final SignalingMessageSender signalingMessageSender; + private final DataChannelMessageNotifier dataChannelMessageNotifier = new DataChannelMessageNotifier(); + private List iceCandidates = new ArrayList<>(); private PeerConnection peerConnection; private String sessionId; @@ -156,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; } @@ -339,21 +370,16 @@ public class PeerConnectionWrapper { } if (nick != null) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .NICK_CHANGE, sessionId, nick, null, videoStreamType)); + dataChannelMessageNotifier.notifyNickChanged(nick); } } else if ("audioOn".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .AUDIO_CHANGE, sessionId, null, TRUE, videoStreamType)); + dataChannelMessageNotifier.notifyAudioOn(); } else if ("audioOff".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .AUDIO_CHANGE, sessionId, null, FALSE, videoStreamType)); + dataChannelMessageNotifier.notifyAudioOff(); } else if ("videoOn".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .VIDEO_CHANGE, sessionId, null, TRUE, videoStreamType)); + dataChannelMessageNotifier.notifyVideoOn(); } else if ("videoOff".equals(dataChannelMessage.getType())) { - EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .VIDEO_CHANGE, sessionId, null, FALSE, videoStreamType)); + dataChannelMessageNotifier.notifyVideoOff(); } } } From 3762526318e97b0ac4296722701892bee1062373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 13 Nov 2022 18:14:10 +0100 Subject: [PATCH 10/10] Rewrite if/else chain as if/return blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just a matter of preference :-) Signed-off-by: Daniel Calviño Sánchez --- .../talk/webrtc/PeerConnectionWrapper.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) 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 bb5e57540..c5b2f66b2 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -372,14 +372,32 @@ public class PeerConnectionWrapper { if (nick != null) { dataChannelMessageNotifier.notifyNickChanged(nick); } - } else if ("audioOn".equals(dataChannelMessage.getType())) { + + return; + } + + if ("audioOn".equals(dataChannelMessage.getType())) { dataChannelMessageNotifier.notifyAudioOn(); - } else if ("audioOff".equals(dataChannelMessage.getType())) { + + return; + } + + if ("audioOff".equals(dataChannelMessage.getType())) { dataChannelMessageNotifier.notifyAudioOff(); - } else if ("videoOn".equals(dataChannelMessage.getType())) { + + return; + } + + if ("videoOn".equals(dataChannelMessage.getType())) { dataChannelMessageNotifier.notifyVideoOn(); - } else if ("videoOff".equals(dataChannelMessage.getType())) { + + return; + } + + if ("videoOff".equals(dataChannelMessage.getType())) { dataChannelMessageNotifier.notifyVideoOff(); + + return; } } }