diff --git a/app/build.gradle b/app/build.gradle index caa90aa4e..db44df625 100644 --- a/app/build.gradle +++ b/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' diff --git a/app/src/main/java/com/nextcloud/talk/activities/BaseActivity.java b/app/src/main/java/com/nextcloud/talk/activities/BaseActivity.java new file mode 100644 index 000000000..7fe727da5 --- /dev/null +++ b/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 + * + * 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.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); + } + +} diff --git a/app/src/main/java/com/nextcloud/talk/activities/MagicCallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/MagicCallActivity.java index 3a1606e33..b77621ee2 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MagicCallActivity.java +++ b/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 diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.java b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.java index cef60461f..2cb9366e2 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.java +++ b/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); - } } diff --git a/app/src/main/java/com/nextcloud/talk/api/ExternalSignaling.java b/app/src/main/java/com/nextcloud/talk/api/ExternalSignaling.java deleted file mode 100644 index a6f5261fa..000000000 --- a/app/src/main/java/com/nextcloud/talk/api/ExternalSignaling.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Nextcloud Talk application - * - * @author Mario Danic - * Copyright (C) 2017-2018 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.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 observeOnMessageReceived(); - - @Receive - Flowable observeOnConnectionOpenedEvent(); - - @Receive - Flowable observeOnConnectionFailedEvent(); - - @Receive - Flowable observeOnConnectionClosedEvent(); - - @Send - void sendHello(HelloOverallWebSocketMessage helloOverallWebSocketMessage); - - @Send - void sendResumeHello(RoomOverallWebSocketMessage roomOverallWebSocketMessage); - - @Send - void sendOfferRequest(RequestOfferOverallWebSocketMessage requestOfferOverallWebSocketMessage); - - @Send - void sendCallMessage(CallOverallWebSocketMessage callOverallWebSocketMessage); - - @Receive - Flowable observeOnHelloBackEvent(); -} diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java index 879bd232a..37cff064f 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java +++ b/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() { - @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() { - @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}) diff --git a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.java b/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.java index 502270985..9cbb1b1ba 100644 --- a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.java +++ b/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; diff --git a/app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthParametersWebSocketMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthParametersWebSocketMessage.java index a8cbcbc7a..129b387f0 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthParametersWebSocketMessage.java +++ b/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; } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthWebSocketMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthWebSocketMessage.java index 9389f8f2c..7a17273ca 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/websocket/AuthWebSocketMessage.java +++ b/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; diff --git a/app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloOverallWebSocketMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloOverallWebSocketMessage.java index 9196c30c5..a39af616a 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloOverallWebSocketMessage.java +++ b/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; diff --git a/app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloWebSocketMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloWebSocketMessage.java index 76e418c79..af2ff3831 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/websocket/HelloWebSocketMessage.java +++ b/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; diff --git a/app/src/main/java/com/nextcloud/talk/models/json/websocket/RequestOfferSignalingMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/websocket/RequestOfferSignalingMessage.java index 677d4ea5b..58c96d0ec 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/websocket/RequestOfferSignalingMessage.java +++ b/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; diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketListener.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketListener.java new file mode 100644 index 000000000..66ac07027 --- /dev/null +++ b/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 + * + * 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 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()); + } + +} diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/ScarletHelper.java b/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java similarity index 81% rename from app/src/main/java/com/nextcloud/talk/webrtc/ScarletHelper.java rename to app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java index da58084cb..1728a0eee 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/ScarletHelper.java +++ b/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 externalSignalingMap = new HashMap<>(); +public class WebSocketConnectionHelper { + private Map 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; }