소스 검색

Extract interface to send signaling messages

Like done with SignalingMessageReceiver, an implementation specific to
each signaling server type (internal or external) is added.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Daniel Calviño Sánchez 2 년 전
부모
커밋
473b8b238d

+ 71 - 52
app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

@@ -85,6 +85,7 @@ import com.nextcloud.talk.models.json.signaling.SignalingOverall;
 import com.nextcloud.talk.models.json.signaling.settings.IceServer;
 import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
 import com.nextcloud.talk.signaling.SignalingMessageReceiver;
+import com.nextcloud.talk.signaling.SignalingMessageSender;
 import com.nextcloud.talk.ui.dialog.AudioOutputDialog;
 import com.nextcloud.talk.users.UserManager;
 import com.nextcloud.talk.utils.ApiUtils;
@@ -261,6 +262,9 @@ public class CallActivity extends CallBaseActivity {
     private InternalSignalingMessageReceiver internalSignalingMessageReceiver = new InternalSignalingMessageReceiver();
     private SignalingMessageReceiver signalingMessageReceiver;
 
+    private InternalSignalingMessageSender internalSignalingMessageSender = new InternalSignalingMessageSender();
+    private SignalingMessageSender signalingMessageSender;
+
     private Map<String, SignalingMessageReceiver.CallParticipantMessageListener> callParticipantMessageListeners =
         new HashMap<>();
 
@@ -1368,6 +1372,7 @@ public class CallActivity extends CallBaseActivity {
                         signalingMessageReceiver = internalSignalingMessageReceiver;
                         signalingMessageReceiver.addListener(participantListMessageListener);
                         signalingMessageReceiver.addListener(offerMessageListener);
+                        signalingMessageSender = internalSignalingMessageSender;
                         joinRoomAndCall();
                     }
                 }
@@ -1571,6 +1576,7 @@ public class CallActivity extends CallBaseActivity {
             signalingMessageReceiver = webSocketClient.getSignalingMessageReceiver();
             signalingMessageReceiver.addListener(participantListMessageListener);
             signalingMessageReceiver.addListener(offerMessageListener);
+            signalingMessageSender = webSocketClient.getSignalingMessageSender();
         } else {
             if (webSocketClient.isConnected() && currentCallStatus == CallStatus.PUBLISHER_FAILED) {
                 webSocketClient.restartWebSocket();
@@ -1624,7 +1630,7 @@ public class CallActivity extends CallBaseActivity {
                 ncSignalingMessage.setRoomType("video");
                 ncSignalingMessage.setType("requestoffer");
 
-                webSocketClient.sendCallMessage(ncSignalingMessage);
+                signalingMessageSender.send(ncSignalingMessage);
                 break;
         }
     }
@@ -2241,7 +2247,7 @@ public class CallActivity extends CallBaseActivity {
     }
 
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
-    public void onMessageEvent(SessionDescriptionSendEvent sessionDescriptionSend) throws IOException {
+    public void onMessageEvent(SessionDescriptionSendEvent sessionDescriptionSend) {
         NCSignalingMessage ncSignalingMessage = new NCSignalingMessage();
         ncSignalingMessage.setTo(sessionDescriptionSend.getPeerId());
         ncSignalingMessage.setRoomType(sessionDescriptionSend.getVideoStreamType());
@@ -2258,56 +2264,7 @@ public class CallActivity extends CallBaseActivity {
 
         ncSignalingMessage.setPayload(ncMessagePayload);
 
-        if (!hasExternalSignalingServer) {
-            // The message wrapper can not be defined in a JSON model to be directly serialized, as sent messages
-            // need to be serialized twice; first the signaling message, and then the wrapper as a whole. Received
-            // messages, on the other hand, just need to be deserialized once.
-            StringBuilder stringBuilder = new StringBuilder();
-            stringBuilder.append('{')
-                .append("\"fn\":\"")
-                .append(StringEscapeUtils.escapeJson(LoganSquare.serialize(ncSignalingMessage)))
-                .append('\"')
-                .append(',')
-                .append("\"sessionId\":")
-                .append('\"').append(StringEscapeUtils.escapeJson(callSession)).append('\"')
-                .append(',')
-                .append("\"ev\":\"message\"")
-                .append('}');
-
-            List<String> strings = new ArrayList<>();
-            String stringToSend = stringBuilder.toString();
-            strings.add(stringToSend);
-
-            int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[]{ApiUtils.APIv3, 2, 1});
-
-            ncApi.sendSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, baseUrl, roomToken),
-                                        strings.toString())
-                .retry(3)
-                .subscribeOn(Schedulers.io())
-                .subscribe(new Observer<SignalingOverall>() {
-                    @Override
-                    public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
-                        // unused atm
-                    }
-
-                    @Override
-                    public void onNext(@io.reactivex.annotations.NonNull SignalingOverall signalingOverall) {
-                        receivedSignalingMessages(signalingOverall.getOcs().getSignalings());
-                    }
-
-                    @Override
-                    public void onError(@io.reactivex.annotations.NonNull Throwable e) {
-                        Log.e(TAG, "", e);
-                    }
-
-                    @Override
-                    public void onComplete() {
-                        // unused atm
-                    }
-                });
-        } else {
-            webSocketClient.sendCallMessage(ncSignalingMessage);
-        }
+        signalingMessageSender.send(ncSignalingMessage);
     }
 
     @Override
@@ -2646,6 +2603,68 @@ public class CallActivity extends CallBaseActivity {
         }
     }
 
+    private class InternalSignalingMessageSender implements SignalingMessageSender {
+
+        @Override
+        public void send(NCSignalingMessage ncSignalingMessage) {
+            String serializedNcSignalingMessage;
+            try {
+                serializedNcSignalingMessage = LoganSquare.serialize(ncSignalingMessage);
+            } catch (IOException e) {
+                Log.e(TAG, "Failed to serialize signaling message", e);
+                return;
+            }
+
+            // The message wrapper can not be defined in a JSON model to be directly serialized, as sent messages
+            // need to be serialized twice; first the signaling message, and then the wrapper as a whole. Received
+            // messages, on the other hand, just need to be deserialized once.
+            StringBuilder stringBuilder = new StringBuilder();
+            stringBuilder.append('{')
+                .append("\"fn\":\"")
+                .append(StringEscapeUtils.escapeJson(serializedNcSignalingMessage))
+                .append('\"')
+                .append(',')
+                .append("\"sessionId\":")
+                .append('\"').append(StringEscapeUtils.escapeJson(callSession)).append('\"')
+                .append(',')
+                .append("\"ev\":\"message\"")
+                .append('}');
+
+            List<String> strings = new ArrayList<>();
+            String stringToSend = stringBuilder.toString();
+            strings.add(stringToSend);
+
+            int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[]{ApiUtils.APIv3, 2, 1});
+
+            ncApi.sendSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, baseUrl, roomToken),
+                                        strings.toString())
+                .retry(3)
+                .subscribeOn(Schedulers.io())
+                .subscribe(new Observer<SignalingOverall>() {
+                    @Override
+                    public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
+                    }
+
+                    @Override
+                    public void onNext(@io.reactivex.annotations.NonNull SignalingOverall signalingOverall) {
+                        // When sending messages to the internal signaling server the response has been empty since
+                        // Talk v2.9.0, so it is not really needed to process it, but there is no harm either in
+                        // doing that, as technically messages could be returned.
+                        receivedSignalingMessages(signalingOverall.getOcs().getSignalings());
+                    }
+
+                    @Override
+                    public void onError(@io.reactivex.annotations.NonNull Throwable e) {
+                        Log.e(TAG, "", e);
+                    }
+
+                    @Override
+                    public void onComplete() {
+                    }
+                });
+        }
+    }
+
     private class MicrophoneButtonTouchListener implements View.OnTouchListener {
 
         @SuppressLint("ClickableViewAccessibility")

+ 36 - 0
app/src/main/java/com/nextcloud/talk/signaling/SignalingMessageSender.java

@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * Interface to send signaling messages.
+ */
+public interface SignalingMessageSender {
+
+    /**
+     * Sends the given signaling message.
+     *
+     * @param ncSignalingMessage the message to send
+     */
+    void send(NCSignalingMessage ncSignalingMessage);
+
+}

+ 15 - 1
app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java

@@ -40,6 +40,7 @@ import com.nextcloud.talk.models.json.websocket.EventOverallWebSocketMessage;
 import com.nextcloud.talk.models.json.websocket.HelloResponseOverallWebSocketMessage;
 import com.nextcloud.talk.models.json.websocket.JoinedRoomOverallWebSocketMessage;
 import com.nextcloud.talk.signaling.SignalingMessageReceiver;
+import com.nextcloud.talk.signaling.SignalingMessageSender;
 import com.nextcloud.talk.utils.bundle.BundleKeys;
 
 import org.greenrobot.eventbus.EventBus;
@@ -101,6 +102,8 @@ public class MagicWebSocketInstance extends WebSocketListener {
 
     private final ExternalSignalingMessageReceiver signalingMessageReceiver = new ExternalSignalingMessageReceiver();
 
+    private final ExternalSignalingMessageSender signalingMessageSender = new ExternalSignalingMessageSender();
+
     MagicWebSocketInstance(User conversationUser, String connectionUrl, String webSocketTicket) {
         NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
 
@@ -343,7 +346,7 @@ public class MagicWebSocketInstance extends WebSocketListener {
         }
     }
 
-    public void sendCallMessage(NCSignalingMessage ncSignalingMessage) {
+    private void sendCallMessage(NCSignalingMessage ncSignalingMessage) {
         try {
             String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledCallMessageModel(ncSignalingMessage));
             if (!connected || reconnecting) {
@@ -406,6 +409,10 @@ public class MagicWebSocketInstance extends WebSocketListener {
         return signalingMessageReceiver;
     }
 
+    public SignalingMessageSender getSignalingMessageSender() {
+        return signalingMessageSender;
+    }
+
     /**
      * Temporary implementation of SignalingMessageReceiver until signaling related code is extracted to a Signaling
      * class.
@@ -422,4 +429,11 @@ public class MagicWebSocketInstance extends WebSocketListener {
             processSignalingMessage(message);
         }
     }
+
+    private class ExternalSignalingMessageSender implements SignalingMessageSender {
+        @Override
+        public void send(NCSignalingMessage ncSignalingMessage) {
+            sendCallMessage(ncSignalingMessage);
+        }
+    }
 }