Browse Source

Lots of progress on WebSocket implementation

Mario Danic 6 years ago
parent
commit
5e546734cd

+ 0 - 5
app/build.gradle

@@ -190,11 +190,6 @@ dependencies {
     implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
     implementation 'com.kevalpatel2106:emoticongifkeyboard:1.1'
 
-    implementation 'com.github.tinder.scarlet:scarlet:0.1.5'
-    implementation 'com.github.tinder.scarlet:scarlet-stream-adapter-rxjava2:0.1.5'
-    implementation 'com.github.tinder.scarlet:scarlet-message-adapter-moshi:0.1.5'
-    implementation 'com.github.tinder.scarlet:scarlet-websocket-okhttp:0.1.5'
-
     testImplementation 'junit:junit:4.12'
     androidTestImplementation ('androidx.test.espresso:espresso-core:3.1.0-alpha4', {
         exclude group: 'com.android.support', module: 'support-annotations'

+ 134 - 0
app/src/main/java/com/nextcloud/talk/activities/BaseActivity.java

@@ -0,0 +1,134 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.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.activities;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.util.Log;
+import android.webkit.SslErrorHandler;
+
+import com.nextcloud.talk.R;
+
+import com.nextcloud.talk.application.NextcloudTalkApplication;
+import com.nextcloud.talk.events.CertificateEvent;
+import com.nextcloud.talk.utils.ssl.MagicTrustManager;
+import com.yarolegovich.lovelydialog.LovelyStandardDialog;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import autodagger.AutoInjector;
+
+@AutoInjector(NextcloudTalkApplication.class)
+public class BaseActivity extends AppCompatActivity {
+    private static final String TAG = "BaseActivity";
+
+    @Inject
+    EventBus eventBus;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
+    }
+
+    public void showCertificateDialog(X509Certificate cert, MagicTrustManager magicTrustManager,
+                                      @Nullable SslErrorHandler sslErrorHandler) {
+        DateFormat formatter = DateFormat.getDateInstance(DateFormat.LONG);
+        String validFrom = formatter.format(cert.getNotBefore());
+        String validUntil = formatter.format(cert.getNotAfter());
+
+        String issuedBy = cert.getIssuerDN().toString();
+        String issuedFor;
+
+        try {
+            if (cert.getSubjectAlternativeNames() != null) {
+                StringBuilder stringBuilder = new StringBuilder();
+                for (Object o : cert.getSubjectAlternativeNames()) {
+                    List list = (List) o;
+                    int type = (Integer) list.get(0);
+                    if (type == 2) {
+                        String name = (String) list.get(1);
+                        stringBuilder.append("[").append(type).append("]").append(name).append(" ");
+                    }
+                }
+                issuedFor = stringBuilder.toString();
+            } else {
+                issuedFor = cert.getSubjectDN().getName();
+            }
+
+            @SuppressLint("StringFormatMatches") String dialogText = String.format(getResources()
+                            .getString(R.string.nc_certificate_dialog_text),
+                    issuedBy, issuedFor, validFrom, validUntil);
+
+            new LovelyStandardDialog(this)
+                    .setTopColorRes(R.color.nc_darkRed)
+                    .setNegativeButtonColorRes(R.color.nc_darkRed)
+                    .setPositiveButtonColorRes(R.color.colorPrimaryDark)
+                    .setIcon(R.drawable.ic_security_white_24dp)
+                    .setTitle(R.string.nc_certificate_dialog_title)
+                    .setMessage(dialogText)
+                    .setPositiveButton(R.string.nc_yes, v -> {
+                        magicTrustManager.addCertInTrustStore(cert);
+                        if (sslErrorHandler != null) {
+                            sslErrorHandler.proceed();
+                        }
+                    })
+                    .setNegativeButton(R.string.nc_no, view1 -> {
+                        if (sslErrorHandler != null) {
+                            sslErrorHandler.cancel();
+                        }
+                    })
+                    .show();
+
+        } catch (CertificateParsingException e) {
+            Log.d(TAG, "Failed to parse the certificate");
+        }
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onMessageEvent(CertificateEvent event) {
+        showCertificateDialog(event.getX509Certificate(), event.getMagicTrustManager(), event.getSslErrorHandler());
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        eventBus.register(this);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        eventBus.unregister(this);
+    }
+
+}

+ 1 - 2
app/src/main/java/com/nextcloud/talk/activities/MagicCallActivity.java

@@ -22,7 +22,6 @@ package com.nextcloud.talk.activities;
 
 import android.content.res.Configuration;
 import android.os.Bundle;
-import androidx.appcompat.app.AppCompatActivity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -48,7 +47,7 @@ import butterknife.BindView;
 import butterknife.ButterKnife;
 
 @AutoInjector(NextcloudTalkApplication.class)
-public class MagicCallActivity extends AppCompatActivity {
+public class MagicCallActivity extends BaseActivity {
     private static final String TAG = "MagicCallActivity";
 
     @Inject

+ 4 - 94
app/src/main/java/com/nextcloud/talk/activities/MainActivity.java

@@ -20,17 +20,9 @@
  */
 package com.nextcloud.talk.activities;
 
-import android.annotation.SuppressLint;
 import android.content.Intent;
 import android.os.Bundle;
-import androidx.annotation.Nullable;
-import androidx.emoji.text.EmojiCompat;
-import androidx.emoji.bundled.BundledEmojiCompatConfig;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
-import android.util.Log;
 import android.view.ViewGroup;
-import android.webkit.SslErrorHandler;
 
 import com.bluelinelabs.conductor.Conductor;
 import com.bluelinelabs.conductor.Router;
@@ -43,23 +35,14 @@ import com.nextcloud.talk.controllers.ChatController;
 import com.nextcloud.talk.controllers.MagicBottomNavigationController;
 import com.nextcloud.talk.controllers.ServerSelectionController;
 import com.nextcloud.talk.controllers.base.providers.ActionBarProvider;
-import com.nextcloud.talk.events.CertificateEvent;
 import com.nextcloud.talk.utils.bundle.BundleKeys;
 import com.nextcloud.talk.utils.database.user.UserUtils;
-import com.nextcloud.talk.utils.ssl.MagicTrustManager;
-import com.yarolegovich.lovelydialog.LovelyStandardDialog;
-
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.text.DateFormat;
-import java.util.List;
 
 import javax.inject.Inject;
 
+import androidx.appcompat.widget.Toolbar;
+import androidx.emoji.bundled.BundledEmojiCompatConfig;
+import androidx.emoji.text.EmojiCompat;
 import autodagger.AutoInjector;
 import butterknife.BindView;
 import butterknife.ButterKnife;
@@ -68,7 +51,7 @@ import io.requery.android.sqlcipher.SqlCipherDatabaseSource;
 import io.requery.reactivex.ReactiveEntityStore;
 
 @AutoInjector(NextcloudTalkApplication.class)
-public final class MainActivity extends AppCompatActivity implements ActionBarProvider {
+public final class MainActivity extends BaseActivity implements ActionBarProvider {
 
     private static final String TAG = "MainActivity";
 
@@ -84,9 +67,6 @@ public final class MainActivity extends AppCompatActivity implements ActionBarPr
     @Inject
     SqlCipherDatabaseSource sqlCipherDatabaseSource;
 
-    @Inject
-    EventBus eventBus;
-
     private Router router;
 
     @Override
@@ -164,74 +144,4 @@ public final class MainActivity extends AppCompatActivity implements ActionBarPr
         }
     }
 
-    public void showCertificateDialog(X509Certificate cert, MagicTrustManager magicTrustManager,
-                                      @Nullable SslErrorHandler sslErrorHandler) {
-        DateFormat formatter = DateFormat.getDateInstance(DateFormat.LONG);
-        String validFrom = formatter.format(cert.getNotBefore());
-        String validUntil = formatter.format(cert.getNotAfter());
-
-        String issuedBy = cert.getIssuerDN().toString();
-        String issuedFor;
-
-        try {
-            if (cert.getSubjectAlternativeNames() != null) {
-                StringBuilder stringBuilder = new StringBuilder();
-                for (Object o : cert.getSubjectAlternativeNames()) {
-                    List list = (List) o;
-                    int type = (Integer) list.get(0);
-                    if (type == 2) {
-                        String name = (String) list.get(1);
-                        stringBuilder.append("[").append(type).append("]").append(name).append(" ");
-                    }
-                }
-                issuedFor = stringBuilder.toString();
-            } else {
-                issuedFor = cert.getSubjectDN().getName();
-            }
-
-            @SuppressLint("StringFormatMatches") String dialogText = String.format(getResources()
-                            .getString(R.string.nc_certificate_dialog_text),
-                    issuedBy, issuedFor, validFrom, validUntil);
-
-            new LovelyStandardDialog(this)
-                    .setTopColorRes(R.color.nc_darkRed)
-                    .setNegativeButtonColorRes(R.color.nc_darkRed)
-                    .setPositiveButtonColorRes(R.color.colorPrimaryDark)
-                    .setIcon(R.drawable.ic_security_white_24dp)
-                    .setTitle(R.string.nc_certificate_dialog_title)
-                    .setMessage(dialogText)
-                    .setPositiveButton(R.string.nc_yes, v -> {
-                        magicTrustManager.addCertInTrustStore(cert);
-                        if (sslErrorHandler != null) {
-                            sslErrorHandler.proceed();
-                        }
-                    })
-                    .setNegativeButton(R.string.nc_no, view1 -> {
-                        if (sslErrorHandler != null) {
-                            sslErrorHandler.cancel();
-                        }
-                    })
-                    .show();
-
-        } catch (CertificateParsingException e) {
-            Log.d(TAG, "Failed to parse the certificate");
-        }
-    }
-
-    @Subscribe(threadMode = ThreadMode.MAIN)
-    public void onMessageEvent(CertificateEvent event) {
-        showCertificateDialog(event.getX509Certificate(), event.getMagicTrustManager(), event.getSslErrorHandler());
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        eventBus.register(this);
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        eventBus.unregister(this);
-    }
 }

+ 0 - 61
app/src/main/java/com/nextcloud/talk/api/ExternalSignaling.java

@@ -1,61 +0,0 @@
-/*
- * Nextcloud Talk application
- *
- * @author Mario Danic
- * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.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.api;
-
-import com.nextcloud.talk.models.json.websocket.CallOverallWebSocketMessage;
-import com.nextcloud.talk.models.json.websocket.HelloOverallWebSocketMessage;
-import com.nextcloud.talk.models.json.websocket.HelloResponseWebSocketMessage;
-import com.nextcloud.talk.models.json.websocket.RequestOfferOverallWebSocketMessage;
-import com.nextcloud.talk.models.json.websocket.RoomOverallWebSocketMessage;
-import com.tinder.scarlet.WebSocket;
-import com.tinder.scarlet.ws.Receive;
-import com.tinder.scarlet.ws.Send;
-
-import io.reactivex.Flowable;
-
-public interface ExternalSignaling {
-    @Receive
-    Flowable<WebSocket.Event.OnMessageReceived> observeOnMessageReceived();
-
-    @Receive
-    Flowable<WebSocket.Event.OnConnectionOpened> observeOnConnectionOpenedEvent();
-
-    @Receive
-    Flowable<WebSocket.Event.OnConnectionFailed> observeOnConnectionFailedEvent();
-
-    @Receive
-    Flowable<WebSocket.Event.OnConnectionClosed> observeOnConnectionClosedEvent();
-
-    @Send
-    void sendHello(HelloOverallWebSocketMessage helloOverallWebSocketMessage);
-
-    @Send
-    void sendResumeHello(RoomOverallWebSocketMessage roomOverallWebSocketMessage);
-
-    @Send
-    void sendOfferRequest(RequestOfferOverallWebSocketMessage requestOfferOverallWebSocketMessage);
-
-    @Send
-    void sendCallMessage(CallOverallWebSocketMessage callOverallWebSocketMessage);
-
-    @Receive
-    Flowable<HelloResponseWebSocketMessage> observeOnHelloBackEvent();
-}

+ 9 - 58
app/src/main/java/com/nextcloud/talk/controllers/CallController.java

@@ -50,7 +50,6 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
 import com.bumptech.glide.load.resource.bitmap.CircleCrop;
 import com.bumptech.glide.request.RequestOptions;
 import com.nextcloud.talk.R;
-import com.nextcloud.talk.api.ExternalSignaling;
 import com.nextcloud.talk.api.NcApi;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.controllers.base.BaseController;
@@ -76,7 +75,6 @@ import com.nextcloud.talk.models.json.signaling.Signaling;
 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.models.json.websocket.HelloResponseWebSocketMessage;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.MagicFlipView;
 import com.nextcloud.talk.utils.NotificationUtils;
@@ -89,8 +87,7 @@ import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
 import com.nextcloud.talk.webrtc.MagicAudioManager;
 import com.nextcloud.talk.webrtc.MagicPeerConnectionWrapper;
 import com.nextcloud.talk.webrtc.MagicWebRTCUtils;
-import com.nextcloud.talk.webrtc.ScarletHelper;
-import com.tinder.scarlet.WebSocket;
+import com.nextcloud.talk.webrtc.WebSocketConnectionHelper;
 import com.wooplr.spotlight.SpotlightView;
 
 import org.apache.commons.lang3.StringEscapeUtils;
@@ -98,7 +95,6 @@ import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.Subscribe;
 import org.greenrobot.eventbus.ThreadMode;
 import org.parceler.Parcels;
-import org.reactivestreams.Subscription;
 import org.webrtc.AudioSource;
 import org.webrtc.AudioTrack;
 import org.webrtc.Camera1Enumerator;
@@ -135,7 +131,6 @@ import butterknife.BindView;
 import butterknife.OnClick;
 import butterknife.OnLongClick;
 import eu.davidea.flipview.FlipView;
-import io.reactivex.FlowableSubscriber;
 import io.reactivex.Observer;
 import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.disposables.Disposable;
@@ -249,8 +244,8 @@ public class CallController extends BaseController {
     private SpotlightView spotlightView;
 
     private ExternalSignalingServer externalSignalingServer;
-    private ExternalSignaling externalSignaling;
-    private ScarletHelper scarletHelper;
+    private okhttp3.WebSocket webSocketClient;
+    private WebSocketConnectionHelper webSocketConnectionHelper;
 
     public CallController(Bundle args) {
         super(args);
@@ -1158,7 +1153,7 @@ public class CallController extends BaseController {
 
 
                         } else {
-                            setUpAndInitiateScarletConnection();
+                            setupAndInitiateWebSocketsConnection();
                         }
                     }
 
@@ -1173,55 +1168,11 @@ public class CallController extends BaseController {
                 });
     }
 
-    private void setUpAndInitiateScarletConnection() {
-        scarletHelper = new ScarletHelper();
-        externalSignaling = scarletHelper.getExternalSignalingInstanceForServer(
-                externalSignalingServer.getExternalSignalingServer(), false);
-
-        externalSignaling.observeOnHelloBackEvent().subscribe(new FlowableSubscriber<HelloResponseWebSocketMessage>() {
-            @Override
-            public void onSubscribe(Subscription s) {
-
-            }
-
-            @Override
-            public void onNext(HelloResponseWebSocketMessage helloResponseWebSocketMessage) {
-
-            }
-
-            @Override
-            public void onError(Throwable t) {
-
-            }
-
-            @Override
-            public void onComplete() {
-
-            }
-        });
-
-        externalSignaling.observeOnConnectionOpenedEvent().subscribe(new FlowableSubscriber<WebSocket.Event.OnConnectionOpened>() {
-            @Override
-            public void onSubscribe(Subscription s) {
-
-            }
-
-            @Override
-            public void onNext(WebSocket.Event.OnConnectionOpened onConnectionOpened) {
-                externalSignaling.sendHello(scarletHelper.getAssembledHelloModel(conversationUser,
-                        externalSignalingServer.getExternalSignalingTicket()));
-            }
-
-            @Override
-            public void onError(Throwable t) {
-
-            }
-
-            @Override
-            public void onComplete() {
-
-            }
-        });
+    private void setupAndInitiateWebSocketsConnection() {
+        webSocketConnectionHelper = new WebSocketConnectionHelper();
+        webSocketClient = webSocketConnectionHelper.getExternalSignalingInstanceForServer(
+                externalSignalingServer.getExternalSignalingServer(), false,
+                conversationUser, externalSignalingServer.getExternalSignalingTicket());
     }
 
     @OnClick({R.id.pip_video_view, R.id.remote_renderers_layout})

+ 3 - 0
app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.java

@@ -20,9 +20,12 @@
 
 package com.nextcloud.talk.models;
 
+import org.parceler.Parcel;
+
 import lombok.Data;
 
 @Data
+@Parcel
 public class ExternalSignalingServer {
     String externalSignalingServer;
     String externalSignalingTicket;

+ 1 - 2
app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthParametersWebSocketMessage.java

@@ -22,7 +22,6 @@ package com.nextcloud.talk.models.json.websocket;
 
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
-import com.squareup.moshi.Json;
 
 import org.parceler.Parcel;
 
@@ -35,6 +34,6 @@ public class AuthParametersWebSocketMessage {
     @JsonField(name = "userid")
     String userid;
 
-    @Json(name = "ticket")
+    @JsonField(name = "ticket")
     String ticket;
 }

+ 0 - 1
app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthWebSocketMessage.java

@@ -22,7 +22,6 @@ package com.nextcloud.talk.models.json.websocket;
 
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
-import com.squareup.moshi.Json;
 
 import org.parceler.Parcel;
 

+ 0 - 1
app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloOverallWebSocketMessage.java

@@ -22,7 +22,6 @@ package com.nextcloud.talk.models.json.websocket;
 
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
-import com.squareup.moshi.Json;
 
 import org.parceler.Parcel;
 

+ 0 - 1
app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloWebSocketMessage.java

@@ -22,7 +22,6 @@ package com.nextcloud.talk.models.json.websocket;
 
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
-import com.squareup.moshi.Json;
 
 import org.parceler.Parcel;
 

+ 0 - 1
app/src/main/java/com/nextcloud/talk/models/json/websocket/RequestOfferSignalingMessage.java

@@ -22,7 +22,6 @@ package com.nextcloud.talk.models.json.websocket;
 
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
-import com.squareup.moshi.Json;
 
 import org.parceler.Parcel;
 

+ 94 - 0
app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketListener.java

@@ -0,0 +1,94 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.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.webrtc;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.bluelinelabs.logansquare.LoganSquare;
+import com.nextcloud.talk.models.database.UserEntity;
+import com.nextcloud.talk.models.json.websocket.BaseWebSocketMessage;
+
+import java.io.IOException;
+
+import okhttp3.Response;
+import okhttp3.WebSocket;
+import okhttp3.WebSocketListener;
+import okio.ByteString;
+
+public class MagicWebSocketListener extends WebSocketListener {
+    private static final String TAG = "MagicWebSocketListener";
+    private static final int NORMAL_CLOSURE_STATUS = 1000;
+
+    private UserEntity conversationUser;
+    private String webSocketTicket;
+    private String resumeId;
+    private WebSocketConnectionHelper webSocketConnectionHelper;
+
+    MagicWebSocketListener(UserEntity conversationUser, String webSocketTicket) {
+        this.conversationUser = conversationUser;
+        this.webSocketTicket = webSocketTicket;
+        this.webSocketConnectionHelper = new WebSocketConnectionHelper();
+    }
+
+    @Override
+    public void onOpen(WebSocket webSocket, Response response) {
+        try {
+            if (TextUtils.isEmpty(resumeId)) {
+                Log.d("MARIO", LoganSquare.serialize(webSocketConnectionHelper.getAssembledHelloModel(conversationUser, webSocketTicket)));
+                webSocket.send(LoganSquare.serialize(webSocketConnectionHelper.getAssembledHelloModel(conversationUser, webSocketTicket)));
+            } else {
+                webSocket.send(LoganSquare.serialize(webSocketConnectionHelper.getAssembledHelloModelForResume(resumeId)));
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to serialize hello model");
+        }
+        //webSocket.close(NORMAL_CLOSURE_STATUS, "Goodbye !");
+    }
+
+    @Override
+    public void onMessage(WebSocket webSocket, String text) {
+        Log.d(TAG, "Receiving : " + text);
+
+        try {
+            BaseWebSocketMessage baseWebSocketMessage = LoganSquare.parse(text, BaseWebSocketMessage.class);
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to parse base WebSocket message");
+        }
+    }
+
+    @Override
+    public void onMessage(WebSocket webSocket, ByteString bytes) {
+        Log.d(TAG, "Receiving bytes : " + bytes.hex());
+    }
+
+    @Override
+    public void onClosing(WebSocket webSocket, int code, String reason) {
+        webSocket.close(NORMAL_CLOSURE_STATUS, null);
+        Log.d(TAG, "Closing : " + code + " / " + reason);
+    }
+
+    @Override
+    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
+        Log.d(TAG, "Error : " + t.getMessage());
+    }
+
+}

+ 17 - 24
app/src/main/java/com/nextcloud/talk/webrtc/ScarletHelper.java → app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java

@@ -20,13 +20,9 @@
 
 package com.nextcloud.talk.webrtc;
 
-import com.google.android.gms.common.api.Api;
-import com.nextcloud.talk.api.ExternalSignaling;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.models.database.UserEntity;
-import com.nextcloud.talk.models.json.rooms.Conversation;
 import com.nextcloud.talk.models.json.signaling.NCMessageWrapper;
-import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
 import com.nextcloud.talk.models.json.websocket.AuthParametersWebSocketMessage;
 import com.nextcloud.talk.models.json.websocket.AuthWebSocketMessage;
 import com.nextcloud.talk.models.json.websocket.CallOverallWebSocketMessage;
@@ -40,11 +36,6 @@ import com.nextcloud.talk.models.json.websocket.RoomOverallWebSocketMessage;
 import com.nextcloud.talk.models.json.websocket.RoomWebSocketMessage;
 import com.nextcloud.talk.models.json.websocket.SignalingDataWebSocketMessageForOffer;
 import com.nextcloud.talk.utils.ApiUtils;
-import com.tinder.scarlet.Scarlet;
-import com.tinder.scarlet.messageadapter.moshi.MoshiMessageAdapter;
-import com.tinder.scarlet.retry.LinearBackoffStrategy;
-import com.tinder.scarlet.streamadapter.rxjava2.RxJava2StreamAdapterFactory;
-import com.tinder.scarlet.websocket.okhttp.OkHttpClientUtils;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -52,17 +43,20 @@ import java.util.Map;
 import javax.inject.Inject;
 
 import autodagger.AutoInjector;
+import io.requery.Nullable;
 import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.WebSocket;
 
 @AutoInjector(NextcloudTalkApplication.class)
-public class ScarletHelper {
-    private Map<String, ExternalSignaling> externalSignalingMap = new HashMap<>();
+public class WebSocketConnectionHelper {
+    private Map<String, WebSocket> webSocketMap = new HashMap<>();
 
     @Inject
     OkHttpClient okHttpClient;
 
 
-    public ScarletHelper() {
+    public WebSocketConnectionHelper() {
         NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
     }
 
@@ -78,21 +72,19 @@ public class ScarletHelper {
         return generatedURL;
     }
 
-    public ExternalSignaling getExternalSignalingInstanceForServer(String url, boolean forceReconnect) {
+    public WebSocket getExternalSignalingInstanceForServer(String url, boolean forceReconnect, UserEntity userEntity, String webSocketTicket) {
+
         String connectionUrl = getExternalSignalingServerUrlFromSettingsUrl(url);
 
-        if (externalSignalingMap.containsKey(connectionUrl) && !forceReconnect) {
-            return externalSignalingMap.get(connectionUrl);
+        if (webSocketMap.containsKey(connectionUrl) && !forceReconnect) {
+            return webSocketMap.get(connectionUrl);
         } else {
-            Scarlet scarlet = new Scarlet.Builder()
-                    .backoffStrategy(new LinearBackoffStrategy(500))
-                    .webSocketFactory(OkHttpClientUtils.newWebSocketFactory(okHttpClient, connectionUrl))
-                    .addMessageAdapterFactory(new MoshiMessageAdapter.Factory())
-                    .addStreamAdapterFactory(new RxJava2StreamAdapterFactory())
-                    .build();
-            ExternalSignaling externalSignaling = scarlet.create(ExternalSignaling.class);
-            externalSignalingMap.put(connectionUrl, externalSignaling);
-            return externalSignaling;
+            Request request = new Request.Builder().url(connectionUrl).build();
+            MagicWebSocketListener listener = new MagicWebSocketListener(userEntity, webSocketTicket);
+            WebSocket webSocket = okHttpClient.newWebSocket(request, listener);
+
+            webSocketMap.put(connectionUrl, webSocket);
+            return webSocket;
         }
     }
 
@@ -108,6 +100,7 @@ public class ScarletHelper {
         authParametersWebSocketMessage.setUserid(userEntity.getUserId());
         authWebSocketMessage.setAuthParametersWebSocketMessage(authParametersWebSocketMessage);
         helloWebSocketMessage.setAuthWebSocketMessage(authWebSocketMessage);
+        helloOverallWebSocketMessage.setHelloWebSocketMessage(helloWebSocketMessage);
         return helloOverallWebSocketMessage;
     }