mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-26 23:25:20 +03:00
Lots of progress on WebSocket implementation
This commit is contained in:
parent
41bdcbd3c3
commit
5e546734cd
14 changed files with 263 additions and 250 deletions
|
@ -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'
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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})
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in a new issue