Lots of progress on WebSocket implementation

This commit is contained in:
Mario Danic 2018-10-12 11:41:04 +02:00
parent 41bdcbd3c3
commit 5e546734cd
14 changed files with 263 additions and 250 deletions

View file

@ -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'

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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();
}

View file

@ -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})

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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());
}
}

View file

@ -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;
}